JavaScript Lasso Selection Chart

This example showcases the creation of a custom user interaction.

By default, dragging left mouse inside the series area, a zoom/fit interaction is activated.
This default interaction can be disabled:

chart
  // Disable default chart interactions with left mouse button.
  .setMouseInteractionRectangleFit(false)
  .setMouseInteractionRectangleZoom(false);

And any custom interaction can be implemented with different event subscription methods.
In this example, ChartXY.onSeriesBackgroundMouseDrag is used to hook on to the event when user drags their left mouse button inside the series area.
PolygonSeries are used to draw a freeform lasso selection as the user moves their mouse on the chart.

The data points that are inside the lasso are solved in real-time, and highlighted with a separate PointSeries.

Highlighted lasso selection

This idea of custom interactions can be extended to any application specific dynamic interaction, like deleting selected points, displaying them in a separate chart or moving them - imagination is the limit!

When implementing custom interactions that involve solving a list of data points from some selection - like lasso - optimizing the application side code is very important. Performing heavy computations inside event handlers can block the thread which can make it seem like the chart is not performing well when in reality it is the application code that is bottle-necking the performance.

Some rules of thumb for implementing custom interactions:

  • Don't do heavy calculations directly inside event handlers. Instead, schedule an update using setTimeout and prevent recalculations happening more often than necessary. This example limits the lasso update to max. 1 update per 25 milliseconds.

  • Work smart, not hard. In the case of lasso selection, iterating over a large data set one-by-one and checking which points are inside a polygon can be really heavy.
    Instead, on each update, we only check the new expanded polygon area.
    In practice, the lasso polygon often has even 1000 coordinates in which case we're skipping 999 iterations of the entire data set every time the lasso is updated.

The code in this example is optimized very well, feel free to reference it in your own custom interaction implementations!