I try to implement a Google Chart displaying sensor value in a time line. I want to have the min, max and average value in the graph (min and max is a filled interval). But I want also the chart to be more interactive by implementing a zoom inside the data : when the user zoom in the chart, data are fetched again from the server with updated values based on the selected time range during the zoom.
For example, when the user is zoomed out in a time window for a full month, the data are aggregated by day. But if the user zoom to a day, a server call should retreive data aggregated by hours. If he zoom to an hour, data are aggregated by seconds.
Unfortunately, I’m not able to make it works, because I do not find any trigger when the user zoom. I did addListener on rangechange but this event is never called.
Here is the Fiddle :
https://jsfiddle.net/93na1tcq/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Line Chart Example</title>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load("current", {
packages: ["corechart"],
callback: initGraph,
})
function initGraph() {
data = new google.visualization.DataTable()
data.addColumn("datetime", "DateTime")
data.addColumn("number", "values") // average
data.addColumn({ id: "i0", type: "number", role: "interval" }) // min
data.addColumn({ id: "i1", type: "number", role: "interval" }) // max
jsonData = fetchData()
data.addRows(jsonData)
options = {
title: "Min, Max, and Average Values Over Time",
intervals: { style: "area" },
hAxis: {
title: "Date",
format: "MMM dd, yyyy",
},
vAxis: {
title: "Values",
},
legend: { position: "bottom" },
explorer: {
actions: ["dragToZoom", "rightClickToReset"],
axis: "horizontal",
keepInBounds: true,
maxZoomIn: 0.1,
},
}
chart = new google.visualization.LineChart(
document.getElementById("chart_div"),
)
google.visualization.events.addListener(chart, "ready", addZoomListener)
chart.draw(data, options)
}
function fetchData(
startDate = "2025-03-01T00:00:00Z",
endDate = "2025-03-05T00:00:00Z",
) {
/**
const url = `data.php?fmt=json&agregate=86400&startdate=${startDate}&enddate=${endDate}`;
fetch(url)
.then(response => response.json())
.then(data => {
const formattedData = [['Date', 'Min', 'Average', 'Max']];
data.forEach(item => {
formattedData.push([new Date(item[0]), item[1], item[2], item[3]]);
});
drawChart(formattedData);
})
.catch(error => console.error('Error fetching data:', error));
**/
formattedData = [] // Date, avg, min, max
formattedData.push([new Date("2025-03-23T23:00:00.000Z"), 10.0, 5, 20.0])
formattedData.push([new Date("2025-03-24T23:00:00.000Z"), 15.0, 10.0, 30.0])
formattedData.push([new Date("2025-03-25T23:00:00.000Z"), 35.0, 20.0, 45.0])
formattedData.push([new Date("2025-03-26T23:00:00.000Z"), 35.0, 30.0, 50.0])
formattedData.push([new Date("2025-03-27T23:00:00.000Z"), 55.0, 50.0, 60.0])
return formattedData
}
function addZoomListener() {
google.visualization.events.addListener(chart, "rangechange", function () {
alert("rangechange")
const viewWindow = chart.getOption("hAxis.viewWindow")
const startDate = new Date(viewWindow.min).toISOString()
const endDate = new Date(viewWindow.max).toISOString()
fetchData(startDate, endDate)
})
google.visualization.events.addListener(chart, "select", function () {
alert("select")
})
}
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
You can zoom on the graph by drag&drop in the chart, right click to zoom out. I was not able to implement slide or panning to.
The JS function fetchData() simulate the call to the server.
How to trigger an event when the user zoom on the chart ?