如何动态呈现和更新chart.js折线图

问题描述 投票:0回答:1

我正在以类似形式从服务器接收json格式的数据:

{"id":"1","temp1":"22","temp2":"33","hum":"55", "date":"02-08-2020"}, 
{"id":"2","temp1":"33","temp2":"44","hum":"44", "date":"02-08-2020"}, 
{"id":"3","temp1":"12","temp2":"25","hum":"66", "date":"02-08-2020"}

但是问题是,它是少数可能的数据集之一。接收到的数据可以在“ id”和“ date”之间具有任意多个字段,因此我想动态创建和呈现chart.js折线图。

我尝试模拟服务器响应并测试我的逻辑以查看其是否有效。这些是我的全局变量:

var data = [];
var jsonString = '[{"id":"1","temp1":"22","temp2":"33","hum":"55"},{"id":"2","temp1":"33","temp2":"44","hum":"44"},{"id":"3","temp1":"12","temp2":"25","hum":"66"}]';
var myData = JSON.parse(jsonString);

//chart.js config arrays
var graphColors = [
  '#0275d8',
  '#d9534f',
  '#5cb85c',
  '#f0ad4e',
  '#5bc0de'
];

var graphDatasets = [];

我有一个称为init的函数,该函数会在窗口加载后立即被调用:

window.onload=init();

在此函数中,我使用key:value提取数据并将其排序到“ data”数组中,因此“ myData”对象及其键的每个接收到的对象的属性都映射到数组中的该键下,因此我具有类似的内容(尽管我不确定这是否是最好的方法):

[{"id:[1,2,3]"},{"temp1:[22,33,12]"}, {"temp2:[33,44,25]"}.....]

在此init函数中,我还准备了graphDatasets数组,以便能够将其传递给chart.js的'datasets'属性。

这是我的初始化函数:

function init() {
      var temp = [];
      myData.slice(-2).forEach(o => Object.entries(o).forEach(([k, v]) => {
          if (!temp[k]) data.push({ [k]: temp[k] = [] });
          temp[k].push(v);
      }));
      //Populate graphDatasets array
      var i = 0;
      for(var key in data) {
        if ((key !== "id") || (key !== "date") ) {
          graphDatasets.push({
            label: key,
            lineTension: 0.3,
            backgroundColor: "rgba(78, 115, 223, 0.05)",
            borderColor: graphColors[i],
            pointRadius: 3,
            pointBackgroundColor: graphColors[i],
            pointBorderColor: "rgba(78, 115, 223, 1)",
            pointHoverRadius: 3,
            pointHoverBackgroundColor: "rgba(78, 115, 223, 1)",
            pointHoverBorderColor: "rgba(78, 115, 223, 1)",
            pointHitRadius: 10,
            pointBorderWidth: 2,
            data: data[key]
          });
          i++;
        }
      }
    }

我尝试检查接收到的密钥是否不是'id'或'date',因为我不想绘制它们的图形,但是检查似乎无法正常进行。我做错了什么,如何解决此问题并正确检查“ id”和“ date”字段?

此后,我尝试呈现图表,但没有成功:

// Chart Example
var ctx = document.getElementById("chartIndex");
var chartIndex = new Chart(ctx, {
  type: 'line',
  data: {
    labels: data[0].id,
    datasets: graphDatasets
  }

我相信我试图将数据全部传递给图表都是错误的。但是,由于我一般不熟悉javascript,因此我不知道如何正确处理这种情况,因为我有JSON格式的数据,可以更改其结构,并且无论有多少数据及其键是什么,他们都需要显示在图表上。

如何正确执行此操作,以及在代码和方法中需要做哪些修复才能实现基于json响应的动态数据图表?

我在这里准备了一个小提琴:https://jsfiddle.net/ph7ydonL/

javascript arrays json ecmascript-6 chart.js
1个回答
0
投票

我在您的示例中做了一点努力-我不确定您期望得到的结果...通常,您将数据对象构建为地图列表,其中地图中的键是您的动态属性,我改变了它到对象列表:

/* var base_url = $('head base').attr('href'); */

//chart.js config arrays
var graphColors = [
  '#0275d8',
  '#d9534f',
  '#5cb85c',
  '#f0ad4e',
  '#5bc0de'
];

var graphDatasets = [];

const number_format = (a) => a;

// Set new default font family and font color to mimic Bootstrap's default styling
Chart.defaults.global.defaultFontFamily = 'Nunito', '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
Chart.defaults.global.defaultFontColor = '#858796';

var data = [];

window.onload = init();

function init() {
  var jsonString = '[{"id":"1","temp1":"22","temp2":"33","hum":"55"},{"id":"2","temp1":"33","temp2":"44","hum":"44"},{"id":"3","temp1":"12","temp2":"25","hum":"66"}]';
  var myData = JSON.parse(jsonString);
  var temp = [];
  myData.slice(-2).forEach(o => Object.entries(o).forEach(([k, v]) => {
    if (!temp[k]) data.push({
      data: temp[k] = [],
      key: k
    });
    temp[k].push(v);
  }));
  //Populate graphDatasets array
  var i = 0;
  data.forEach((elem) => {
    if ((elem.key !== "id") && (elem.key !== "date")) {
      graphDatasets.push({
        label: elem.key,
        lineTension: 0.3,
        backgroundColor: "rgba(78, 115, 223, 0.05)",
        borderColor: graphColors[i],
        pointRadius: 3,
        pointBackgroundColor: graphColors[i],
        pointBorderColor: "rgba(78, 115, 223, 1)",
        pointHoverRadius: 3,
        pointHoverBackgroundColor: "rgba(78, 115, 223, 1)",
        pointHoverBorderColor: "rgba(78, 115, 223, 1)",
        pointHitRadius: 10,
        pointBorderWidth: 2,
        data: elem.data
      });
      i++;
    }
  })
}

//console.log(data[0]);
//console.log(graphDatasets);

// Area Chart Example
var ctx = document.getElementById("chartIndex");
var chartIndex = new Chart(ctx, {
  type: 'line',
  data: {
    labels: data[0].id,
    datasets: graphDatasets
  },
  options: {
    maintainAspectRatio: false,
    layout: {
      padding: {
        left: 10,
        right: 25,
        top: 25,
        bottom: 0
      }
    },
    scales: {
      xAxes: [{
        time: {
          unit: 'date'
        },
        gridLines: {
          display: false,
          drawBorder: false
        },
        ticks: {
          maxTicksLimit: 7
        }
      }],
      yAxes: [{
        ticks: {
          maxTicksLimit: 5,
          padding: 10,
          // Include a dollar sign in the ticks
          callback: function(value, index, values) {
            return '$' + number_format(value);
          }
        },
        gridLines: {
          color: "rgb(234, 236, 244)",
          zeroLineColor: "rgb(234, 236, 244)",
          drawBorder: false,
          borderDash: [2],
          zeroLineBorderDash: [2]
        }
      }],
    },
    legend: {
      display: false
    },
    tooltips: {
      backgroundColor: "rgb(255,255,255)",
      bodyFontColor: "#858796",
      titleMarginBottom: 10,
      titleFontColor: '#6e707e',
      titleFontSize: 14,
      borderColor: '#dddfeb',
      borderWidth: 1,
      xPadding: 15,
      yPadding: 15,
      displayColors: false,
      intersect: false,
      mode: 'index',
      caretPadding: 10,
      callbacks: {
        label: function(tooltipItem, chart) {
          var datasetLabel = chart.datasets[tooltipItem.datasetIndex].label || '';
          return datasetLabel + ': $' + number_format(tooltipItem.yLabel);
        }
      }
    }
  }
});

var updateChart = function() {
  $.ajax({
    type: 'GET',
    url: base_url + '//',
    dataType: 'json',
    success: function(response) {

      var obj = response.parse();
      var i = 0;

      Object.keys(obj).forEach(function(key, index) {
        if (data.hasOwnProperty(key)) {
          data.key.push(obj[key]);
          chartIndex.data.labels.push(obj.date);
          chartIndex.data.datasets[i].data.push(data.key);
          i++;
        }
      });
      // re-render the chart
      myChart.update();
    }
  });
};

// get new data every 3 seconds
//setInterval(updateChart, 3000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="chartIndex" width="400" height="400"></canvas>
© www.soinside.com 2019 - 2024. All rights reserved.