import { ConnectedScatterplot } from "semiotic"
A connected scatterplot draws lines between consecutive data points, revealing the trajectory through a two-dimensional space. Points are colored using a viridis gradient from start (purple) to end (yellow), and connecting lines match the color and width of their source point. When fewer than 100 points are plotted, a semi-transparent white halo is drawn under each line for legibility.
Quick Start
import { ConnectedScatterplot } from "semiotic" const frameProps = { /* --- Data --- */ data: [ { x: 30, y: 60, year: 2000 }, { x: 33, y: 62, year: 2001 }, // ...20 points tracing a trajectory ], /* --- Process --- */ xAccessor: "x", yAccessor: "y", orderAccessor: "year", /* --- Customize --- */ showGrid: true, xLabel: "GDP per capita", yLabel: "Life Expectancy", pointRadius: 5, orderLabel: "Year" } export default () => { return <ConnectedScatterplot {...frameProps} /> }
Examples
Spiral Trajectory
With 30 points, the white halo under each line improves readability where the path crosses itself.
import { ConnectedScatterplot } from "semiotic" const frameProps = { /* --- Data --- */ data: Array.from({ length: 30 }, (_, i) => { const t = i * 0.3 return { x: Math.cos(t) * (50 + i * 3) + 100, y: Math.sin(t) * (50 + i * 3) + 100, } }), /* --- Process --- */ xAccessor: "x", yAccessor: "y", /* --- Customize --- */ showGrid: true, pointRadius: 4 } export default () => { return <ConnectedScatterplot {...frameProps} /> }
Larger Points
Increase pointRadius for bolder connections. The line width always matches the point radius so the circle (diameter = 2×radius) remains visually distinct from the line.
import { ConnectedScatterplot } from "semiotic" const frameProps = { /* --- Data --- */ data: trajectoryData.slice(0, 12), /* --- Process --- */ xAccessor: "x", yAccessor: "y", /* --- Customize --- */ xLabel: "X", yLabel: "Y", pointRadius: 8 } export default () => { return <ConnectedScatterplot {...frameProps} /> }
Streaming
ConnectedScatterplot supports forwardRef with push/pushMany/clear/getData. Push new points and the viridis gradient and connecting lines update automatically.
Design Choices
- Viridis color scale — encodes sequence position. Purple = start, yellow = end. No legend needed; the color gradient itself communicates directionality.
- Line width = point radius — a circle with radius 4 is 8px in diameter, connected by a 4px line. The circle is always wider than the line, maintaining visual hierarchy.
- White halo (<100 points) — when paths cross, the semi-transparent white underline separates overlapping segments. Disabled for large datasets to maintain rendering performance.
- No size encoding — point radius is fixed. This is intentional: in a connected scatterplot, varying point size would also vary line width, creating visual noise.
Props
| Prop | Type | Required | Default | Description |
|---|
data | array | — | — | Array of data points in order. Consecutive points are connected by lines. Optional when using the push API via ref.push()/pushMany(). |
xAccessor | string | function | — | "x" | Field name or function to access x values. |
yAccessor | string | function | — | "y" | Field name or function to access y values. |
orderAccessor | string | function | — | — | Field or function for point ordering (number or Date). Data is sorted ascending. Shown in tooltip. |
orderLabel | string | — | field name | Label for the ordering metric in tooltips. |
pointRadius | number | — | 4 | Circle radius. Connecting lines match this width. |
enableHover | boolean | — | true | Enable hover tooltips. |
showGrid | boolean | — | false | Show grid lines. |
tooltip | object | function | — | — | Tooltip configuration. |
responsiveWidth | boolean | — | false | Auto-match width to container. |
width | number | — | 600 | Chart width. |
height | number | — | 400 | Chart height. |