Actual behaviour
Now a series of all days of the week is being built on the X-axis.
like now:
2022-5-30
2022-5-31
2022-6-1
2022-6-2
2022-6-3
2022-6-4
2022-6-5
2022-6-6
Live demo with steps to reproduce
https://jsfiddle.net/5z1b9xnp/
let globalData = []; let finRez = [];
let chart;
let duration = 500; // Determines how long the animation between new points should be take
let startIterator = 1; // Determines how many points will be rendered on chart's init
let currentIterator = startIterator;
let maxIterator = 1;
let guiButton = document.getElementById('start');
let guiButtonState = 'Start';
let intervalId;
// Fetch data:
fetch('https://raw.githubusercontent.com/veleg/trade/main/trade.json')
.then(response => response.json())
.then(data => {
parseData(data);
createChart();
initEvents();
});
function initEvents() {
guiButton.addEventListener('click', function() {
if (guiButtonState === 'Stop') {
// User clicked "Stop" -> stop animation and allow to resume
intervalId = clearInterval(intervalId);
guiButton.innerText = guiButtonState = 'Resume';
} else {
// If animation has finished, recreate chart
if (guiButtonState === 'Restart') {
createChart();
}
guiButton.innerText = guiButtonState = 'Stop';
// Start animation:
redrawChart(currentIterator += 1);
intervalId = setInterval(function() {
// If we reached last available point, stop animation:
if (currentIterator === maxIterator) {
intervalId = clearInterval(intervalId);
currentIterator = startIterator;
guiButton.innerText = guiButtonState = 'Restart';
} else {
redrawChart(currentIterator += 1);
}
}, duration);
}
});
}
function redrawChart(index) {
// Set new subtitle on every redraw
chart.setTitle(null, {
text: ' Заработано: ' + globalData[0].data[index][1]
}, false);
const newValues = globalData.map(series => series.data[index][1]);
const maxIndex = newValues.indexOf(Math.max.apply(null, newValues));
// To each series, add a point:
chart.series.forEach(
(series, seriesIndex) => {
const enabled = maxIndex === seriesIndex && ((index < 5) || (index % 5 === 0));
series.addPoint(
{
x: globalData[seriesIndex].data[index][0],
y: globalData[seriesIndex].data[index][1]
<!-- dataLabels: { -->
<!-- enabled -->
<!-- }, -->
<!-- marker: { -->
<!-- enabled -->
<!-- } -->
},
false,
false,
false
);
}
);
// Now, once everything is updated, redraw chart:
chart.redraw({
duration
});
}
function parseData(data) {
Highcharts.objectEach(
data,
// Prepare Highcharts data-format:
// series: [{
// data: [ [x, y], [x, y], ..., [x, y]]
// }]
(countryData, country) => {
if (country !== 'Diamond Princess' && country !== 'Holy See') {
globalData.push({
name: country,
data: countryData.map(p => [Date.parse(p.date), p.recovered / getCountryPopulation(country)])
<!-- data: countryData.map(p => [p.date, p.recovered / getCountryPopulation(country)]), -->
<!-- datas: countryData.date, -->
<!-- datass: countryData.map(p => [p.date, p.date]) -->
});
}
}
);
// Sort and limit dataset:
globalData = globalData
.sort((countryA, countryB) => {
let countryALen,
countryBLen;
if (!countryA || !countryA.data || countryA.data.length === 0) {
return 1;
}
if (!countryB || !countryB.data || countryB.data.length === 0) {
return -1;
}
return countryB.data[countryB.data.length - 1][1] - countryA.data[countryA.data.length - 1][1];
})
.splice(0, 8);
maxIterator = Math.max.apply(null, globalData.map(series => series.data.length - 1));
}
function createChart() {
function format(y) {
return y.toFixed(2);
}
chart = Highcharts.chart('container', {
chart: {
type: 'spline',
marginLeft: 100
},
legend: {
layout: 'proximate',
align: 'right'
},
title: {
floating: true,
align: 'left',
x: 93,
y: 20,
text: 'Confirmed cases per country per 1000 inhabitants'
},
subtitle: {
floating: true,
align: 'left',
y: 60,
x: 90,
text: ' Заработано: ' + globalData[0].data[0][1],
style: {
fontSize: '20px'
}
},
tooltip: {
split: true,
pointFormatter: function() {
<!-- var value = format(this.y); -->
<!-- return `<span style="color:${this.color}">●</span> ${this.series.name}: <b>${value}</b><br/>`; -->
}
},
yAxis: {
title: {
text: ''
},
maxPadding: 0.2,
softMax: 1
},
xAxis: {
gridLineWidth: 2,
min: globalData[0].data[0][0],
minRange: 7 * 24 * 3600 * 1000,
type: 'datetime'
<!-- categories: [1] -->
},
plotOptions: {
series: {
animation: {
duration
},
<!-- marker: { -->
<!-- symbol: 'circle' -->
<!-- }, -->
dataLabels: {
formatter: function() {
return format(this.y);
}
}
}
},
series: globalData.map(series => {
return {
name: series.name,
data: series.data.slice(0, startIterator).map(point => {
return { x: point[0], y: point[1] }
})
}
})
});
}
function getCountryPopulation(country) {
return {
"Заработано": 1,
"Финансовый результат": 1
}[country];
}
Product version
Highcharts JS v10.3.2 (2022-11-28)
It is necessary to skip days on the X axis that are not in the JSON file.
need:
2022-5-30
2022-5-31
2022-6-1
2022-6-2
2022-6-3
2022-6-6