как динамически отображать и обновлять диаграмму. js линейный график - PullRequest
0 голосов
/ 08 февраля 2020

Я получаю отформатированные 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», поэтому я хочу динамически создавать и отображать мою диаграмму. js line Chart.

Я пытался смоделировать ответ сервера и проверить мой лог c чтобы посмотреть работает ли он. Это мои глобальные переменные:

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();

В этой функции я извлекаю и упорядочиваю свои данные в " массив данных с ключом: значение, поэтому каждое полученное свойство объекта из объекта «myData» с его ключом сопоставляется с этим ключом в массиве, так что у меня есть что-то вроде этого (хотя я не уверен, что это лучший подход):

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

В этой функции инициализации я также подготавливаю массив graphDatasets, чтобы иметь возможность передавать его в свойство 'наборов данных' для диаграммы. js.

это моя функция инициализации:

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 отформатированные данные, которые могут изменить их структуру и, независимо от того, сколько данных и какой их ключ есть, они должны отображаться на графике.

Как правильно это сделать, и какие исправления мне нужно сделать в моем коде и подходе для достижения динамического c построения диаграмм данных на основе ответа json?

Я подготовил скрипку здесь: https://jsfiddle.net/ph7ydonL/

1 Ответ

1 голос
/ 08 февраля 2020

Я немного поиграл с вашим примером - я не уверен, что результат, который вы ожидаете получить ... В общем, вы построили объект данных в виде списка карт, где ключом на карте является ваша динамика c атрибут, я изменяю его на список объектов:

/* 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>
...