Reputation: 791
Using Chart.js with zoom/pan enabled, I am trying to write a function to export only what is visible on the canvas to CSV.
But I cannot figure out how to get only the visible datapoints after the user zooms/pans.
I know I can just look at myChart.data.datasets
but that would fetch all the points in the chart, not just the currently visible ones.
var config = {
type: 'line',
data: {
// data is from API call
}
pan: {
enabled: true,
mode: 'xy'
},
zoom: {
enabled: true,
mode: 'xy'
},
bezierCurve : false
}
};
var ctx = document.getElementById('myChart').getContext('2d');
window.myChart = new Chart(ctx, config);
$('#exportTheseRunsToCSV').on('click', function() {
// something like myChart.getVisibleDataPoints() ???
console.log(chart)
console.log(chart.data.datasets)
});
There has to be some internal API call to get the visible points, as I also have a function to export the current visible points to PNG and that only grabs what is currently drawn on the canvas:
<a id="exportTheseRuns" class="text-white" href="#" download="image.png" download><i class="fas fa-download"></i> Export to PNG</a>
$('#exportTheseRuns').on('click', function() {
$('#exportTheseRuns').attr('href', myChart.toBase64Image());
})
The function .toBase64Image()
seems like it internally does what I am looking for, as it will only capture visible points, but then it returns a Base64 URI which I can't use for my arrayToCSV
function.
Upvotes: 6
Views: 2469
Reputation: 1
In the last versions of ChartJS, minIndex
and maxIndex
are not linked to the visible points, they are linked to the visible X axis position, I found the same problem. But I found 2 properties that I used to solve it:
chart._metasets[0].controller._drawStart
chart._metasets[0].controller._drawCount
that show the first point visible Index and the number of visible points, both needs some corrections, but if you are here, you will fix it.
PS: I use Zoom in my code and it still works.
Upvotes: 0
Reputation: 13004
The chart object contains minIndex
and maxIndex
properties that can be used to slice
the dataset for the visible values.
Here's a snippet showing how to use the plugin-provided functions onPanComplete
and onZoomComplete
to output the visible values after panning or zooming the chart:
function getVisibleValues({
chart
}) {
let x = chart.scales["x-axis-0"];
document.getElementById("vv").innerText = JSON.stringify(chart.data.datasets[0].data.slice(x.minIndex, x.maxIndex + 1));
}
new Chart(document.getElementById("chart"), {
type: "line",
data: {
labels: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'],
datasets: [{
data: [0, 1, 2, 4, 8, 16, 32, 64, 128, 256]
}]
},
options: {
maintainAspectRatio: false,
scales: {
xAxes: [{
ticks: {
min: 'c',
max: 'h'
}
}]
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x',
onPanComplete: getVisibleValues
},
zoom: {
enabled: true,
mode: 'x',
onZoomComplete: getVisibleValues
}
}
}
}
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<canvas id="chart" style="max-height:125px"></canvas>
<p>
Visible values: <span id="vv"></span>
</p>
Upvotes: 4
Reputation: 916
The toBase64Image
function does not what you want, it just gets the data URL from the canvas.
toBase64Image on github.com/chartjs
toBase64Image: function() {
return this.canvas.toDataURL.apply(this.canvas, arguments);
},
You can get the updated chart data with onZoomComplete
and onPanComplete
, they both get an object that contains chart
from this you might get more information about the current zoom, but as far as I can see you will need to do some calculations/work to get the visible points...
Upvotes: 0