Fork me on GitHub

Using Dygraphs to load down-sampled data while zooming - Example 1

In the example below, new data is loaded every time the user zooms in on the graph. This provides an overall view of the entire possible data set via the range selector below the graph, but allows interactive drill down in to more detailed views of the data without having to load the entire data set at the start. For very large data sets, loading all the data from the start is not practical.

The shaded areas above and below the solid line indicate min/max values whenever the data is being down-sampled, and in this case, the solid line indicates the average value. As the user zooms in, eventually there are no min/max indicators because the raw data values are being displayed.


This page. Contains the graph container's HTML and this documentation. No javascript.
This is the most relevant file. Contains all of the Dygraphs specific handling.
Responsible for getting range and detail data from the server/simulator and then aggregating,splicing, and converting it for dygraphs.
Simulates a remote time series data service. Includes simulated delays.

How it works

On page load, two data requests are sent to the server. One for the "range" data, and one for the "detail" data. When zooming, a new request is made for more detailed data according to the new zoom extents (or "dateWindow" in Dygraphs terminology.)

When the new detail data set is received, the code in GraphDataProvider.js splices it with the previously loaded range data set to generate a single new "spliced data set". This spliced data set is what is given to Dygraphs for drawing.

This allows Dygraphs to draw and support the range selector control, but also draw the more detailed data in the zoom window currently being viewed. The non-zoomed, more down-sampled, data can be seen while dragging the range selector because the code does not initiate a new detail data load until mouse-up.

The key to this approach is in understanding the different ways the zoom window (dateWindow) can be changed in Dygraphs and the different results from each interaction. Interactions causing dateWindow to be changed include:

  • A - Dragging on the range selector handles - Causes multiple zoomCallbacks while the position of the handle is changing
  • B - Dragging the range selector to move the dateWindow - No zoomCallback
  • C - Click-dragging on the graph to zoom - Causes a single zoomCallback
  • D - Click-dragging while holding Shift to pan - No zoomCallback, and not handled in examples 1 & 2. See example 3.

To handle these interactions, the code installs a mouse-down and subsequent mouse-up listener on the range selector. (It also installs corresponding touch event listeners so this works on tablets.) When a mouse down occurs on the range selector, the code tracks it and ignores all subsequent zoomCallbacks. This handles (A). We initiate the data load on mouse-up. This handles (A) and (B). If there was no mouse-down on the range selector and we get a zoomCallback, then we assume (C), and so initiate an immediate data load. Handling (D) requires hooking in to the drawCallback and is not shown in this example.

That's basically it. The code, and comments in the code, shows the details.

Other examples:

  • example 2 - shows functionality for changing the overall range
  • example 3 - shows how to handle pan interaction

Third party libraries

I used jQuery because it simplifies the code and, honestly, I've probably started forgetting how to work with DOM events correctly without it. I also used two other third party libraries that are not required, but made this example a little better. Both can be easily removed.


Dygraphs is a well designed and robust library. Thanks to the Dygraphs developers for releasing it with an MIT license and for continuing to supporting it.

Credit also to KCF Technologies for giving me permission to publish code showing the basic technique above. I flushed out the technique while doing work for them on their next generation Smart Diagnostics product, which uses a much more complicated variant of the example graph above.