Reputation: 310
I am using a regular HTML + js setup and I have JQuery + ChartJS 2.9.3 I am creating a line chart, exactly like the samples. I am querying a JSON from a server using JQuery's getJSON. I am treating it accordingly, and my final datasets and labels are in the correct form an count (checked via debugging). When clicking my update button which gets and parse the JSON, the chart disappears, only to reappear on a redraw (example: moving the window) just fine with all my data in the correct way.
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<canvas id="canvas"></canvas>
<br />
<br />
<input type="number" id="limit" min="3" max="100" value="10" step="1" />
<button type="button" id="update">Update</button>
<script>
const colors = ["#fcba03", "#56fc03", "#56fc03", "#054eeb", "#8f05eb", "#eb05e0", "#05ebeb"]
Object.map = function (o, f, ctx) {
ctx = ctx || this;
var result = {};
Object.keys(o).forEach(function (k) {
result[k] = f.call(ctx, o[k], k, o);
});
return result;
}
var config = {
type: 'line',
data: {
labels: [],
datasets: []
},
options: {
responsive: true,
title: {
display: true,
text: "Qualité de l'air"
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
x: {
display: true,
scaleLabel: {
display: true,
labelString: 'Time'
}
},
y: {
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}
}
}
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myChart = new Chart(ctx, config);
};
document.getElementById('update').addEventListener('click', updateGraph);
function updateGraph() {
var limit = document.getElementById('limit').value;
$.getJSON("http://localhost/api.php?limit=" + limit, function (obj) {
var labels_obj = Object.map(obj, (value) => { return value.numeric.time; });
var arr = $.map(obj, function (el) { return el });
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const element = obj[key];
delete element.numeric.time;
}
}
var dataset_names = Object.keys(obj[0].numeric);
var datasets_obj = Object.map(dataset_names, (element, index) => {
var data = Object.values(Object.map(obj, (value) => { return value.numeric[dataset_names[index]]; }));
return {
backgroundColor: colors[index],
borderColor: colors[index],
fill: false,
label: element,
data: data,
};
});
window.myChart.config.data.labels = Object.values(labels_obj);
window.myChart.config.data.datasets = Object.values(datasets_obj);
});
window.myChart.update();
}
</script>
</body>
My JSON looks like this:
{
"0": {
"numeric": {
"NH3": "0.995879",
"CO": "0.333835",
"NO2": "0.68154",
"C3H8": "0.406195",
"C4H10": "0.986352",
"CH4": "0.713178",
"H2": "0.606834",
"time": "2019-11-27 09:52:56"
},
"analog": {
"HCHO": "0.688368",
"MQ2": "0.230614",
"time": "2019-11-27 09:51:00"
}
},
"1": {
"numeric": {
"NH3": "0.406223",
"CO": "0.440095",
"NO2": "0.981807",
"C3H8": "0.588751",
"C4H10": "0.998331",
"CH4": "0.225404",
"H2": "0.132026",
"time": "2019-11-27 09:52:55"
},
"analog": {
"HCHO": "0.482279",
"MQ2": "0.768992",
"time": "2019-11-27 09:50:59"
}
} (etc...)
}
Having tried everything to make that chart not disappear. I also get this js error on update: TypeError: this.getDatasetMeta(...).controller is null [email protected]:7:107693
Thanks a lot !
Upvotes: 1
Views: 1461
Reputation: 310
Found the issue:
As getJSON
is executed asyncronously, and chart.update()
was called after it, the chart was updated, and then it's data was changed, causing the bug.
Make sure the chart.update()
call is inside the $.getJSON(){...}
.
Upvotes: 1