I'm working with Apache ECharts and trying to use two different data sources: one for the main chart and another for the dataZoom preview.
Due to the large amount of data, I've reduced the resolution over longer time periods to minimize the data sent to the client. However, I want the main chart to display a much higher resolution when the user zooms in on a smaller time range.
This screenshot shows my issue
Unfortunately, I can't figure out how to use two different data sources for the main chart and the dataZoom overview. Does anyone have any suggestions on how to achieve this?
Basically the dataZoom chart should always show the complete chart, and the main plot should load and display the selected area.
I have created this example in the online editor of ECharts, to demonstrate my issue
The best way I can think of is using a helper xAxis with type: 'category'
, show: false
and your time data (formatted in some way) as data
property. Now you only need a dataZoom on this axis and use the dataZoom event to fetch new data.
function generateDateRandomPairs() {
const dateRandomPairs = [];
const date = new Date();
var j = 1;
for (let i = 0; i < 10000; i++) {
const number = j;
if (i % 10 == 0) {
j++;
}
dateRandomPairs.push([date.toISOString(), number]);
date.setSeconds(date.getSeconds() + 60);
}
return dateRandomPairs;
}
// All data but with lower resolution
// Should be used in dataZoom
var allData = generateDateRandomPairs();
// Data with high resolution
// Would be loaded through Ajax in real world
var mainPlotData = allData.slice(50, 200);
option = {
tooltip: {
trigger: 'axis'
},
xAxis: [
{
type: 'time',
name: 'Date'
},
{
type: 'category',
data: allData.map((point) => point[0]),
show: false
}
],
yAxis: [
{
gridIndex: 0,
type: 'value',
name: 'Value',
}
],
series: [
{
name: 'High-Res Data',
type: 'line',
xAxisIndex: 0,
yAxisIndex: 0,
data: mainPlotData
}
],
dataZoom: [
{
type: 'slider',
xAxisIndex: 1,
endValue: 200,
realtime: false
}
]
};
myChart.on('dataZoom', function(params) {
const startIndex = Math.round((params.start / 100) * allData.length);
const endIndex = Math.round((params.end / 100) * allData.length);
let resolution = Math.ceil((endIndex - startIndex) / 200);
resolution = resolution === 0 ? 1 : resolution;
const data = allData.slice(startIndex, endIndex).filter((x, i) => i % resolution === 0);
myChart.setOption({series: [{data: data}]})
});