bugfix> python > 投稿

私はdjangoとchart.jsを使用してダッシュボードを作成しようとしています。

私のモジュールは次のようになります:

class Sets(models.Model):
   time = models.DateTimeField(default=timezone.now)
   set1 = models.IntegerField()
   set2 = models.IntegerField()
   set3 = models.IntegerField()

私の見解:

from .function_sum import get_sets
from .models import Sets
def home(request, *args, **kwargs):
   sets = Sets.objects.all()
   time = []
   set1 = []
   set2 = []
   set3 = []
   time, set1, set2, set3= get_sets()
   data = {
       "sets" : sets,
       "time": time,
       "set1": set1,
       "set2": set2,
       "set3": set3
   }
   return render(request, "pages/home.html", data)
class ChartData(APIView):
   authentication_classes = []
   permission_classes = []
   sets = Sets.objects.all()
   time = []
   set1 = []
   set2 = []
   set3 = []
   time, set1 , set2 , set3 = get_sets()
   def get(self, request, format=None):
      data = {
        "time": self.time,
        "set1": self.set1,
        "set2": self.set2,
        "set3": self.set3
       }
       return Response(data)

get_setsは、Setデータテーブルから現在のデータを取得しています。

レイアウトページに含まれている私のhtmlファイル:

<div class="col-xl-6" url-endpoint='{% url "chart-data" %}'>
    <div class="card mb-5">
        <div class="card-header"><i class="fas fa-chart-line mr-1"></i>Chart</div>
        <div class="card-body"><canvas id="SetChart" width="100%" height="40"></canvas></div>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/js/all.min.js" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script>
var endpoint ='chart/data'
var labels = []
var set1 = []
var set2 = []
var set3 = []

$.ajax({
    method: "GET",
    url: endpoint,
    
    success: function(data){
        labels = data.time
        set1 = data.set1
        set2 = data.set2
        set3 = data.set3
        var ctx = document.getElementById('SetChart').getContext('2d');
        var startingData = {
                labels: labels,
                datasets: [{
                    label: '1',
                    data: set1,
                    borderColor: 'rgba(255, 0, 0, 1)',
                    backgroundColor: 'rgba(0, 0, 0, 0)',
                    pointStyle : "point",
                    borderWidth: 1
                },{
                    label: '2',
                    data: set2,
                    borderColor: 'rgba(20, 0, 0, 1)',
                    backgroundColor: 'rgba(0, 0, 0, 0)',
                    
                    borderWidth: 1
                },{
                    label: '3',
                    data: set3,
                    borderColor: 'rgba(0, 99, 132, 1)',
                    fill: false,
                    borderWidth: 1
                }]
            }
        var SetChart = new Chart(ctx, { type: 'line', data: startingData, options:{}});
        
    },
    error: function(error_data){
        console.log("error")
        console.log(error_data)
    },
}),
setInterval(function(){
   SetChart.data.labels= data.time
   SetChart.data.datasets[0].data = data.set1
   SetChart.data.datasets[1].data = data.set2
   SetChart.data.datasets[2].data = data.set3
   SetChart.update();
}, 1000);
</script>

私はdjango、js、html、chart.js、さらにはpythonを初めて使用するので、チュートリアルからコピーして変更したほとんどすべてのことを実行しました。

私のチャートには、dj manageサーバーをpy manage.py runserverで実行した瞬間の現在のデータベースデータとラベルが表示されます。 しかし、ジェネレータをバックグラウンドで実行しているときに、ランダムな値をセットテーブルに書き込んでいるときに、F5キーを押してもグラフが更新されません。サーバーを停止して再度実行した場合のみ。

チャートでdbの新しいデータをチェックし、数分ごとに更新する方法(dbが更新された直後のほうがよい) また、私はポップとプッシュ機能を処理できませんでした。実際、私のグラフには私のデータベースの最後の10個のデータとラベルのみが表示されます。

更新

コマンドに基づいて、私はそれを動作させました。

私は自分のHTMLを更新し、var SetChartの後の$.ajax呼び出しに以下を含めました:

       function addLabel(chart,label){
            chart.data.labels.push(label)
            chart.update();
        }
        function addData(chart, data, index) {
            chart.data.datasets[index].data.push(data)
            chart.update();
        }
        function removeData(chart) {
            try{
                chart.data.labels.shift();
                chart.data.datasets.forEach((dataset) => {
                    dataset.data.shift();
                });
                chart.update();
            }
            catch(e){
                console.log(e)
            }
        }
        function updateChart(chart, label, set1, set2, set3){
            addLabel(chart,label)
            addData(chart, set1.slice(-1)[0], 0)
            addData(chart, set2.slice(-1)[0], 1)
            addData(chart, set3.slice(-1)[0], 2)
            removeData(chart);
        }
        setInterval(function(){
            $.ajax({
                method: "GET",
                url: endpoint,
                success: function(data){
                    labels = data.time
                    set1 = data.set1
                    set2= data.set2
                    set3= data.set3
                    updateChart(SetChart, labels.slice(-1)[0], set1, set2, set3) 
                    SetChart.update();
                },
                error: function(error_data){
                    console.log("error")
                    console.log(error_data)
                }
            })
        }, 60000);

そして、他のsetIntervall関数を削除しました。

回答 1 件
  • あなたの入力に基づいて、私は最初のリクエストが呼び出していると思います home 初期設定データの表示と読み込み-HTMLページに表示されます。一方、使用しているのは ChartData APIビュー。このシナリオが正しい場合-次に:

    の問題 ChartData つまり、この部分 time, set1 , set2 , set3 = get_sets() (説明されているように)djangoが初期化されるときに1回実行されます。必要なのは、リクエストが送信されるたびにセットを取得することです。そして、コードフラグメントはリクエストに応じて実行されています get 方法。

    適切なソリューションは次のようになります。

    class ChartData(APIView):
       authentication_classes = []
       permission_classes = []
       sets = Sets.objects.all()
       def get(self, request, format=None):
          time, set1 , set2 , set3 = get_sets()
          data = {
            "time": time,
            "set1": set1,
            "set2": set2,
            "set3": set3
           }
           return Response(data)
    
    

    追加のクラス変数は必要ありません( self.set1 ...)。そしてその get_sets 関数がリクエストに到達するたびに呼び出されます get 方法。

    更新(コメントに基づく)

    API Viewでリクエストが処理されるたびにデータ全体が読み込まれないようにするために-フロントエンドで受信した最後のレコードを追跡し、最後のレコードID(別のフィールドがある場合があります)に基づいて追跡しているIDの後に作成されたレコードをフェッチしますフロントエンド。

あなたの答え