Edward Tufte's data-ink ratio (The Visual Display of Quantitative Information, 1983) measures how much of a graphic's rendered ink actually encodes data, versus decoration:
Data-Ink Ratio = Data-Ink / Total-Ink
This build measures it for real, at the pixel level, instead of estimating shape areas. Every time the data changes or a toggle flips, the engine renders the chart twice into two hidden offscreen canvases at a fixed 800ร500 resolution:
- Data-only render โ just the bars, flat fill, no decoration of any kind.
- Full render โ the bars plus whichever chartjunk toggles are currently on.
Each offscreen canvas is read back with getImageData() and every pixel is compared against the known background colour (with a small tolerance for anti-aliasing). The count of pixels that differ from the background is that render's ink. Data-ink is the pixel count from the data-only render; Total-ink is the pixel count from the full render; the ratio is Data-ink รท Total-ink. The underlying bar geometry is byte-for-byte identical between the two renders, so any change in the ratio comes purely from decoration pixels being added or removed โ verifiable by toggling one item at a time and watching only the chartjunk-pixel count move.
A ratio near 1.0 means nearly every rendered pixel serves the data โ Tufte's ideal. Switching on every decoration typically drags a small chart's ratio down to 0.3โ0.6. This is the same trade-off behind "remove chartjunk" advice in real infographic design: gridlines and labels can aid readability in moderation, but each one has a real, measurable pixel cost.