我正在以类似形式从服务器接收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/
我在您的示例中做了一点努力-我不确定您期望得到的结果...通常,您将数据对象构建为地图列表,其中地图中的键是您的动态属性,我改变了它到对象列表:
/* 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>