简体   繁体   English

使用 chart.js 从 django 创建动态图表

[英]Creating a dynamic chart from django using chart.js

I'm new to Django.我是 Django 的新手。 I'm currently doing sentiment analysis on real-time user tweets via Twitter API.我目前正在通过 Twitter API 对实时用户推文进行情绪分析。 I have managed to do the analysis and display the sentiments.我已经设法进行分析并显示情绪。 Now, I want to visualize the sentiments using charts in my Django app (perhaps bar chart or pie chart) but I'm not sure how.现在,我想使用我的 Django 应用程序(可能是条形图或饼图)中的图表来可视化情绪,但我不确定如何。

I was thinking of using Chart.js to make it responsive but most of the examples are using static data so I wasn't successful in integrating my data where I extracted from Twitter API with chart.js. I was thinking of using Chart.js to make it responsive but most of the examples are using static data so I wasn't successful in integrating my data where I extracted from Twitter API with chart.js.

This is a screenshot of my web page.这是我的 web 页面的截图。 The table was the extracted tweets with their corresponding sentiments.该表是提取的推文及其相应的情绪。 The bar chart however is just static data.然而,条形图只是 static 数据。 I don't know how to convert it into json.我不知道如何将其转换为 json。

screenshot of my webpage我的网页截图

this is my views.py这是我的views.py

from django.http.response import JsonResponse
from django.shortcuts import render, redirect, HttpResponse
from .forms import Sentiment_Typed_Tweet_analyse_form
from .sentiment_analysis_code import sentiment_analysis_code
from .forms import Sentiment_Imported_Tweet_analyse_form
from .tweepy_sentiment import Import_tweet_sentiment
from django.contrib.auth.decorators import login_required
from django.contrib import messages
      
def sentiment_analysis_import(request):
    if request.method == 'POST':
        form = Sentiment_Imported_Tweet_analyse_form(request.POST)
        tweet_text = Import_tweet_sentiment()
        analyse = sentiment_analysis_code()

        if form.is_valid():
            handle = form.cleaned_data['sentiment_imported_tweet']
            # messages.info(request, 'It might take a while to load the data.')

            if handle[0]!='#':
                list_of_tweets = tweet_text.get_hashtag(handle)
                list_of_tweets_and_sentiments = []
                for i in list_of_tweets:
            

    list_of_tweets_and_sentiments.append((i,analyse.get_tweet_sentiment(i)))
                args = {'list_of_tweets_and_sentiments':list_of_tweets_and_sentiments, 'handle':handle}
                return render(request, 'home/sentiment_import_result_hashtag.html', args)
            
            if handle[0]=='#':
                list_of_tweets = tweet_text.get_hashtag(handle)
                list_of_tweets_and_sentiments = []
                for i in list_of_tweets:
                    list_of_tweets_and_sentiments.append((i,analyse.get_tweet_sentiment(i)))
                args = {'list_of_tweets_and_sentiments':list_of_tweets_and_sentiments, 'handle':handle}
                return render(request, 'home/sentiment_import_result_hashtag.html', args)
            
    else:
        form = Sentiment_Imported_Tweet_analyse_form()
        return render(request, 'home/sentiment_import.html')

def get_data(request, *args, **kwargs):
def get_data(request, *args, **kwargs):
    sentiment_analysis_import(args)
    data = {
        args
    }
    return JsonResponse('home/sentiment_import_result_hashtag.html', data)

This is my HTML这是我的 HTML

    <!DOCTYPE html>
<html lang="en">
{% load static %}
  <head>
    <title>Sentymeter: Import Tweets</title>
   <!-- Required meta tags -->
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
   <!-- Bootstrap CSS -->
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <!--Chart js-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js" integrity="sha256-Uv9BNBucvCPipKQ2NS9wYpJmi8DTOEfTA/nH2aoJALw=" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.css" integrity="sha256-aa0xaJgmK/X74WM224KMQeNQC2xYKwlAt08oZqjeF0E=" crossorigin="anonymous" />
    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
   <title>Import Tweets</title>

   <style>
     .tbl-header {
      border: 5px solid;
        background-color: #fff;
    }
     table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td, th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

th{
  color: white;
  background: black;
}

tr:nth-child(even) {
  background-color: #e4e9e4;
}
tr:nth-child(odd) {
  background-color: #c2c2c2;
}

body,
        html {
            margin: 0;
            padding: 0;
            height: 100%;
            background: #f8f2ce !important;
        }
    h7.white-text {
         color: rgb(255, 255, 255);
        }
    
</style>
   </style>
   </head>
   <body>

  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item">
              <a class="nav-link" href="/">Home</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="/sentiment/type">Input Text</a>
        </li>
              <li class="nav-item active">
                  <a class="nav-link" href="/sentiment/import">Import Tweets<span class="sr-only">(current)</span></a>
              </li>
              <li class="nav-item">
                  <a class="nav-link" href="/feedback">Feedback</a>
              </li>
          </ul>
      </div>
      <span class="hello-msg"><strong>Hello, {{request.user}}</strong></span>&nbsp;&nbsp;&nbsp;
      <button class="btn btn-danger navbar-btn" ><a href="{% url 'user:logout' %}"><h7 class="white-text" color=white;>Logout</h7></a></button>
  </nav>


      <div class="container">
        <div class="row align-items-center ftco-vh-100">
          <div class="col-md-9">
            <h1 class="ftco-heading mb-3" >Import Tweets Result</h1>
            <h2 class="h5 ftco-subheading mb-5" ><strong>Keyword</strong> - {{ handle }}</h2>
      </div><div></div>   
      
      <div class = "container">
      
      <h1>test</h1>
    </div>
    <div class="col-sm-4">
    <canvas id="myChart" width="90" height="90"></canvas>

  {{ list_of_tweets_and_sentiments|json_script:"list_of_tweets_and_sentiments" }}
<!-- <script>
  const ctx = JSON.parse(document.getElementById('list_of_tweets_and_sentiments').textContent);
</script> -->


<script>
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['Positive', 'Neutral', 'Negative'] ,
        datasets: [{
            label: 'Sentiment Counts',
            data: [12, 19, 3],

            backgroundColor: [
                'green',
                'orange',
                'red',
            ],
        }]
    },
    options: {
        scales: {
            y: {
                beginAtZero: true
            }
        }
    }
});
</script></div>
 

<div class="tbl-header" >
    <table>
        <tr>
          <th >Tweet</th>
          <th>Sentiment</th>
          <th>Emotag</th>
        </tr>
      <tbody>
        {% for i,j in list_of_tweets_and_sentiments %}
        <tr>
          <td>{{i}}</td>
          <td>{{j}}</td>
          {% ifequal j 'Negative' %}
          <td><img src="{% static 'icons/negative.png' %}"></td>
          {% endifequal %}
          {% ifequal j 'Positive' %}
          <td><img src="{% static 'icons/positive.png' %}"></td>
          {% endifequal %}
          {% ifequal j 'Neutral' %}
          <td><img src="{% static 'icons/neutral.png' %}"></td>
          {% endifequal %}
        </tr>
        {% endfor %}
      </tbody>
    </table>
  </div>


<h1>test</h1>


<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>


  </body>
</html>

Can anyone help me on how to link my sentiment tweets with the chart?谁能帮助我如何将我的情绪推文与图表联系起来? I am so confused right now…我现在很困惑……

Please let me know if you need other files/code.如果您需要其他文件/代码,请告诉我。

In most case Chart.js except either an array or an api call in JSON format.在大多数情况下 Chart.js 除了数组或 JSON 格式的 api 调用。

If you are using Django you can create variable to be used in template and your data array for example:如果您使用 Django 您可以创建要在模板和数据数组中使用的变量,例如:

Sentiment.filter(neutral=True).count() # return the number based on a specific filter

Pass it to a variable and in your template in the data array:将其传递给变量并在数据数组中的模板中:

data: [{{neutral_sentiment}}, {{positive_sentiement}}, {{negative_sentiment}}], 

-> variables containing the number to be use to generate the chart -> 包含用于生成图表的数字的变量

I do that in most case, it works well if your data are not complicated and you are not fetching thousands of queries.在大多数情况下,我会这样做,如果您的数据并不复杂并且您没有获取数千个查询,它会很好地工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM