Why we built our own chart engine — Scrolld® Blog

Off-the-shelf chart libraries optimize for dashboards. Scrolld stories needed scroll-synchronized animation, annotation, and full pixel control — so we drew every pixel ourselves on Canvas 2D.

The pragmatic choice would have been an off-the-shelf chart library. There are excellent ones. We use one ourselves for parts of the BI dashboard surface, where its trade-offs fit. But for Scrolld stories — the scroll-driven, animated, annotated heart of the product — we wrote our own engine, drawing every pixel with Canvas 2D. Here is why.

Chart libraries optimize for dashboards

A general-purpose chart library is built around one assumption: the chart renders once, then sits there. Tooltips and zoom are interactions on a static picture.

A Scrolld story breaks that assumption hundreds of times per second. As the reader scrolls, a chart might draw its axes, reveal series point by point, shift its viewport to a new date range, and hand off to an annotation — all keyed to scroll position, all reversible when the reader scrolls back up. Retrofitting that onto a library's render cycle means fighting the library. Owning the render loop means scroll progress is just another input to the frame.

Animation as a first-class citizen

In most libraries, animation is a transition effect you configure. In our engine, every chart is a function of time and scroll progress. That makes the storytelling behaviors natural to express: a line that draws itself as the paragraph beside it makes its point, a bar race that pauses while you read, a candlestick window that glides to the date the text is discussing.

Owning the pixels pays for itself

Drawing everything ourselves had compounding benefits we only partly anticipated:

  • One consistent visual language. Every chart type shares the same scales, grid logic, typography, and color system, because they share the same code.
  • Annotations everywhere. Arrows, highlights, and callouts work identically across chart types, because they draw onto the same canvas with the same coordinate mappers.
  • No dependency weight on the story path. Readers load our rendering code and nothing else; there is no general-purpose library shipped along for features stories never use.
  • Nothing is impossible. When a story needs a chart form that doesn't exist yet, the answer is some math and some drawing code — not a feature request on someone else's roadmap.
  • The honest trade-off

    Building a chart engine is a lot of work, permanently. Every axis-labeling edge case, every high-DPI rendering quirk, every accessibility consideration is ours to handle. For most products that price is not worth paying — use a library. For a product whose entire purpose is making charts tell stories, the render loop is the product. That is the thing you don't outsource.

    Read on Scrolld →


    Scrolld® — Drop your data. Get a story.