Scatter Plot
Real measurements from the Palmer penguins dataset: flipper length against bill length, colored by species and sized by body mass. Each click picks a different random half of the 342 penguins.
Pick a preset to reconfigure every chart
What to look for
- Size encoding. The Unovis example scales body mass to pixels from the full dataset in its
sizeaccessor, so hiding a species keeps the remaining points the same size. Chart.js expects sizes in pixels, so you scale the values yourself. ECharts takes pixels insymbolSize, or maps values to sizes with avisualMap. - Pick other penguins. Every penguin has a stable
id, so Unovis moves the points that stay, fades in the new ones and fades out the rest, and the axes follow. TanStack Charts keys the points byidtoo and animates them the same way (svgAnimation). - Colors from CSS. The Unovis example colors each species with the palette's CSS variables
(
var(--vis-color0)…), so the same code gives dark mode colors in dark mode. - Axis titles. Unovis takes a
labelon each axis. Recharts needs label positioning and extra margins for the same result. - Shapes. Each species has its own shape (
shape), in the chart and in the legend. Recharts, Chart.js, ECharts and AG Charts have the same shapes built in, and so do Observable Plot (symbol) and Vega-Lite (shape); Nivo's scatter plot and TanStack Charts'dotdraw circles only. - Hover. The Unovis crosshair (
snapMode: 'xy') snaps to the point nearest the pointer and draws guide lines to both axes. Nivo, AG Charts, Observable Plot (tip) and TanStack Charts also pick the nearest point, while Recharts shows a tooltip only when the pointer is over one. So do the Chart.js and Vega-Lite demos, which keep their defaults; Chart.js'interaction: { mode: 'nearest', intersect: false }and a Vega-Litenearestselection change that. - Presets. Labels gives every penguin a body mass label (
label) and hides the ones that would cover a point or another label (labelHideOverlapping, on by default). AG Charts hides those too; ECharts (labelLayout.hideOverlap) and Chart.js (chartjs-plugin-datalabels,display: 'auto') hide only the labels that overlap another label and keep the ones that cover a point; Recharts, Observable Plot, Vega-Lite and TanStack Charts would draw every one; and Nivo has no point labels. Rings draws hollow points in the species colors (strokeColor,strokeWidth): ECharts' documentedborderColorvalues don't take its palette (the undocumented'auto'does), so that demo sets the ring colors by hand; Nivo's points have no stroke; and TanStack Charts'dottakes one stroke color for every species. Average lines adds twoVisPlotlines, which every library can draw, Chart.js with chartjs-plugin-annotation.
Feature comparison
| Feature | Unovis1.8.0 | Recharts3.10.1 | Chart.js4.5.1 | ECharts6.1.0 | Nivo0.99.0 | AG Charts14.2.0 | Observable Plot0.6.17 | Vega-Lite6.5.0 | TanStack Charts1.1.0 |
|---|---|---|---|---|---|---|---|---|---|
| Bubble | |||||||||
| Point shapes | |||||||||
| Hover snaps to the nearest point | |||||||||
| Label overlap avoidance | |||||||||
| Brush / range selection | |||||||||
| Zoom and pan XY charts | |||||||||
| Animated data updates | |||||||||
| Dark mode |
Every cell links to its source. See how we compare for the rules we followed.