Point
Scatterplots, dot plots, dumbbells and lollipops on compact Cartesian axes.
import { point } from 'visdelta/point';point() places observations on compact Cartesian axes. It covers scatterplots,
dot plots, dumbbells and lollipops without changing datum identity.
import { point } from 'visdelta/point';
import { transition } from 'visdelta/transition';
import 'visdelta/style.css';
const cars = [
{ name: 'Civic', weight: 2.6, mpg: 33, horsepower: 158 },
{ name: 'Corolla', weight: 2.9, mpg: 34, horsepower: 169 },
{ name: 'Mustang', weight: 3.8, mpg: 21, horsepower: 315 },
{ name: 'Camry', weight: 3.3, mpg: 32, horsepower: 203 },
{ name: 'F-150', weight: 4.7, mpg: 20, horsepower: 290 },
{ name: 'Miata', weight: 2.3, mpg: 30, horsepower: 181 },
{ name: 'Tahoe', weight: 5.6, mpg: 17, horsepower: 355 },
{ name: 'Leaf', weight: 3.5, mpg: 111, horsepower: 147 },
];
const from = point(cars)
.x('weight', { label: 'Weight (1000 lb)' })
.y('mpg', { label: 'Miles per gallon' })
.key('name');
// Every car keeps its identity while the y mapping changes.
const to = from.y('horsepower', { label: 'Horsepower' });
const change = await transition(from, to, { target: '#chart' });
change.play({ duration: 800 }); // or change.progress(0.5)
Methods
| Method | Meaning |
|---|---|
.pointSize(number), .radius(number) | Set a constant point radius |
.connector({ from, channel? }) | Draw a lollipop stem from a quantitative baseline |
.connector({ by, orderBy? }) | Connect adjacent dots within each ordered group |
.flip(options?) | Swap x and y in an explicit order |
.rollup(groupby, options?) | Combine details into summary points |
.breakdown(detail?, options?) | Reveal detailed points |
Connectors
Connectors are derived geometry drawn behind the dots. They never change the data grain or datum identity.
// Lollipops: stems from a constant baseline.
point(rows).x('region').y('sales').connector({ from: 0 });
// Dumbbells: connect each country's dots in year order.
point(rows)
.x('value')
.y('country')
.color('year')
.connector({ by: 'country', orderBy: 'year' });A baseline connector infers its channel when exactly one positional channel is
quantitative; set channel when both are.
Summaries
.rollup() combines detailed points into summaries with explicit reducers for
each position, and optionally a count mapped to size:
const summary = detailed.rollup('cyl', {
key: 'cyl',
x: { op: 'mean' },
y: { op: 'mean' },
size: { op: 'count', range: [10, 24] },
});Transition behaviour
An ordinary entering point grows at its target position. Summary and detail motion may use a declared parent position, because that movement carries meaning.
Summary/detail transitions use gooey blending by default. Points in the same group share a silhouette while they merge or separate; completed endpoints return to crisp circles. Forward, reverse and scrubbed playback share the same geometry.
Try it
Edit the motor-cars scatter in the playground: summarize or focus.