v0.8.0 · MIT · React · Vue · Angular · Reflex
Charts drawn in silverpoint
A charting library whose visual language is historical drawing technique. The first ground reproduces Renaissance silverpoint: a prepared middle-tone substrate, a fine silver line, tone built from hatching, and white heightening reserved for the live value. The second, cyanotype, prints a white line on Prussian blue. Since 0.3 the same hand draws buttons, inputs, tabs and alerts too, 0.6 adds a second catalog — distributions, hierarchies, fields and networks — and 0.7 palettes, overlays and a timeline.
| point | value |
|---|---|
| 1 | 118 |
| 2 | 124 |
| 3 | 121 |
| 4 | 132 |
| 5 | 140 |
| 6 | 136 |
| 7 | 129 |
| 8 | 142 |
| 9 | 151 |
| 10 | 147 |
| 11 | 155 |
| 12 | 162 |
| 13 | 158 |
| 14 | 171 |
| measure | value |
|---|---|
| Capacity used | 72% |
| hour | hits | baseline |
|---|---|---|
| 00 | 18 | 22 |
| 02 | 14 | 18 |
| 04 | 11 | 15 |
| 06 | 16 | 17 |
| 08 | 34 | 30 |
| 10 | 58 | 48 |
| 12 | 71 | 60 |
| 14 | 66 | 62 |
| 16 | 74 | 64 |
| 18 | 88 | 70 |
| 20 | 62 | 55 |
| 22 | 41 | 40 |
One chart, four frameworks
Seven packages share one version. The engine, @silverpoint/core, computes every scale and arc; the adapters only translate its geometry into JSX, Vue nodes or Angular templates, so the three render the same SVG, compared as trees in CI.
React
<LineChart /> · react and react-dom 18.2+ or 19; @knight-lab/timelinejs ^3.9.13 (optional, for SpTimeline)
npm install @silverpoint/react @silverpoint/grounds @silverpoint/fontsVite and Next.js (App Router, React Server Components) are validated.
React guide →Vue
<SpLineChart /> · vue ^3.5.0; @knight-lab/timelinejs ^3.9.13 (optional, for SpTimeline)
npm install @silverpoint/vue @silverpoint/grounds @silverpoint/fontsVite is validated; SSR is verified with @vue/server-renderer. Nuxt works but is not a validated integration.
Vue guide →Angular
<sp-line-chart /> · @angular/core, @angular/common and @angular/forms >=21 <23; @knight-lab/timelinejs ^3.9.13 (optional)
npm install @silverpoint/angular @silverpoint/grounds @silverpoint/fontsThe Angular CLI (@angular/build, on Vite) is validated, including @angular/ssr.
Angular guide →Reflex (Python)
line_chart() · reflex >= 0.10.0 (React 19), Python 3.11+
pip install reflex-silverpoint-reactA Reflex custom component wrapping @silverpoint/react 0.8; Reflex installs the npm side for you. Every chart, UI component, composed component, overlay and the timeline is the npm component, with a snake_case Python API.
Reflex (Python) guide →import '@silverpoint/fonts/fonts.css';
import '@silverpoint/grounds/styles.css';
import { LineChart } from '@silverpoint/react/line-chart';
<LineChart data={data} xKey="hour" valueKey="hits" title="Hits per hour" /><script setup lang="ts">
import '@silverpoint/fonts/fonts.css';
import '@silverpoint/grounds/styles.css';
import { SpLineChart } from '@silverpoint/vue/line-chart';
</script>
<SpLineChart :data="data" x-key="hour" value-key="hits" title="Hits per hour" />import { SpLineChart } from '@silverpoint/angular/line-chart';
@Component({
imports: [SpLineChart],
template: `<sp-line-chart [data]="data" xKey="hour" valueKey="hits" title="Hits per hour" />`,
})from reflex_silverpoint_react import line_chart
line_chart(data=DATA, x_key="hour", value_key="hits", title="Hits per hour")From the gallery
| name | value | share |
|---|---|---|
| Rent | 38 | 38% |
| Food | 22 | 22% |
| Savings | 15 | 15% |
| Transport | 14 | 14% |
| Leisure | 11 | 11% |
| subject | value |
|---|---|
| Speed | 8 |
| Range | 6 |
| Comfort | 7 |
| Safety | 9 |
| Cost | 4 |
| Style | 6 |
| direction | share | < 5 | 5–10 | 10–15 | 15–20 | ≥ 20 |
|---|---|---|---|---|---|---|
| N | 11% | 1% | 5% | 4% | 0% | 0% |
| NNE | 7% | 1% | 3% | 2% | 0% | 0% |
| NE | 4% | 0% | 2% | 1% | 0% | 0% |
| ENE | 4% | 1% | 3% | 1% | 0% | 0% |
| E | 13% | 0% | 7% | 5% | 0% | 0% |
| ESE | 5% | 0% | 2% | 3% | 0% | 0% |
| SE | 4% | 0% | 1% | 2% | 1% | 0% |
| SSE | 6% | 0% | 3% | 1% | 1% | 0% |
| S | 7% | 0% | 2% | 2% | 1% | 1% |
| SSW | 5% | 0% | 1% | 3% | 0% | 1% |
| SW | 3% | 0% | 1% | 1% | 1% | 0% |
| WSW | 2% | 0% | 1% | 1% | 0% | 0% |
| W | 3% | 1% | 1% | 1% | 0% | 0% |
| WNW | 6% | 0% | 1% | 2% | 1% | 1% |
| NW | 11% | 0% | 3% | 4% | 3% | 1% |
| NNW | 6% | 0% | 3% | 3% | 1% | 0% |
| x | value |
|---|---|
| Mon | 32 |
| Tue | 45 |
| Wed | 41 |
| Thu | 58 |
| Fri | 66 |
| Sat | 38 |
| Sun | 29 |
| flow | value |
|---|---|
| Search → Visit | 48 |
| Social → Visit | 27 |
| Email → Visit | 15 |
| Visit → Signup | 42 |
| Visit → Bounce | 48 |
| Signup → Paid | 18 |
| ring | segment | under the index |
|---|---|---|
| Day | Mon | no |
| Day | Tue | no |
| Day | Wed | no |
| Day | Thu | no |
| Day | Fri | no |
| Day | Sat | yes |
| Day | Sun | no |
| Shift | Early | no |
| Shift | Late | no |
| Shift | Night | yes |
| Team | Atlas | no |
| Team | Borealis | no |
| Team | Cygnus | no |
| Team | Draco | no |
| Team | Eridanus | yes |
Palettes, overlays and a timeline
Twenty-one more components in the same hand — tables, pagination, statistics, collapse panels, and overlays on the platform's own <dialog> and Popover API: modal, drawer, popover, tooltip, select, menu and toast — for 38 UI components in all. Six palettes named after drawing media re-colour everything without re-rendering it, and Knight Lab's TimelineJS is drawn in silverpoint. In React, Vue and Angular, and in Python with reflex-silverpoint-react.
The second catalog: 27 new charts
Histograms, box plots, violins, ridgelines and beeswarms whose statistics the core derives; dumbbells, slopes, bumps and diverging bars; squarified treemaps and sunbursts that drill down under your control; parallel coordinates, contours, Voronoi cells, vector fields and a seeded force-laid network. The same exact geometry, the same hand.
| service | n | min | q1 | median | q3 | max | outliers |
|---|---|---|---|---|---|---|---|
| Search | 60 | 134 | 161.75 | 178.5 | 189.5 | 229 | — |
| Checkout | 60 | 116 | 141 | 200.5 | 258.5 | 311 | — |
| Profile | 48 | 100 | 113.75 | 120 | 128.5 | 148 | 246, 250, 287, 290 |
| Reports | 36 | 303 | 316.25 | 344.5 | 367 | 443 | 464, 464, 518 |
| Login | 24 | 76 | 83.75 | 88 | 95.75 | 109 | — |
| service | n | median | peak |
|---|---|---|---|
| Search | 60 | 178.5 | 182.41 |
| Checkout | 60 | 200.5 | 138.06 |
| Profile | 48 | 120 | 115.88 |
| Reports | 36 | 344.5 | 308.09 |
| Login | 24 | 88 | 86.31 |
| node | amount |
|---|---|
| City budget | 69,364 |
| City budget › Public works | 19,197, 27.7% of City budget |
| City budget › Public works › Street lighting | 8,015, 41.8% of Public works |
| City budget › Public works › Bridges | 6,154, 32.1% of Public works |
| City budget › Public works › Water mains | 2,878, 15% of Public works |
| City budget › Public works › Water mains › Water mains: staff | 2,069, 71.9% of Water mains |
| City budget › Public works › Water mains › Water mains: materials | 809, 28.1% of Water mains |
| City budget › Public works › Roads | 2,150, 11.2% of Public works |
| City budget › Public works › Roads › Roads: staff | 1,760, 81.9% of Roads |
| City budget › Public works › Roads › Roads: materials | 390, 18.1% of Roads |
| City budget › Administration | 18,611, 26.8% of City budget |
| City budget › Administration › IT services | 8,252, 44.3% of Administration |
| City budget › Administration › Payroll | 6,768, 36.4% of Administration |
| City budget › Administration › Records | 3,591, 19.3% of Administration |
| City budget › Administration › Records › Records: staff | 3,281, 91.4% of Records |
| City budget › Administration › Records › Records: materials | 310, 8.6% of Records |
| City budget › Safety | 13,294, 19.2% of City budget |
| City budget › Safety › Emergency planning | 6,265, 47.1% of Safety |
| City budget › Safety › Lifeguards | 5,224, 39.3% of Safety |
| City budget › Safety › Lifeguards › Lifeguards: materials | 2,953, 56.5% of Lifeguards |
| City budget › Safety › Lifeguards › Lifeguards: staff | 2,271, 43.5% of Lifeguards |
| City budget › Safety › Fire service | 1,805, 13.6% of Safety |
| City budget › Parks | 10,626, 15.3% of City budget |
| City budget › Parks › Playgrounds | 5,030, 47.3% of Parks |
| City budget › Parks › Playgrounds › Playgrounds: materials | 2,865, 57% of Playgrounds |
| City budget › Parks › Playgrounds › Playgrounds: staff | 2,165, 43% of Playgrounds |
| City budget › Parks › Tree care | 2,835, 26.7% of Parks |
| City budget › Parks › Sports fields | 2,761, 26% of Parks |
| City budget › Parks › Sports fields › Sports fields: staff | 2,455, 88.9% of Sports fields |
| City budget › Parks › Sports fields › Sports fields: materials | 306, 11.1% of Sports fields |
| City budget › Culture | 7,636, 11% of City budget |
| City budget › Culture › Libraries | 3,177, 41.6% of Culture |
| City budget › Culture › Libraries › Libraries: materials | 2,265, 71.3% of Libraries |
| City budget › Culture › Libraries › Libraries: staff | 912, 28.7% of Libraries |
| City budget › Culture › Museum | 2,999, 39.3% of Culture |
| City budget › Culture › Festivals | 1,460, 19.1% of Culture |
| City budget › Culture › Festivals › Festivals: staff | 1,275, 87.3% of Festivals |
| City budget › Culture › Festivals › Festivals: materials | 185, 12.7% of Festivals |
| density | band |
|---|
| model | mass | gears | price | range | rating |
|---|---|---|---|---|---|
| Model 01 | 13.9 | 15 | 3,434 | 125 | 1.5 |
| Model 02 | 8.6 | 22 | 3,897 | 29 | 3.8 |
| Model 03 | 19.5 | 13 | 3,202 | 62 | 2.9 |
| Model 04 | 12.7 | 15 | 2,760 | 28 | 2.2 |
| Model 05 | 22.8 | 21 | 485 | 39 | 2.9 |
| Model 06 | 20.1 | 22 | 1,178 | 60 | 3.1 |
| Model 07 | 22.5 | 8 | 3,952 | 40 | 4.8 |
| Model 08 | 22.6 | 16 | 1,407 | 133 | 1.7 |
| Model 09 | 18.3 | 18 | 2,982 | 126 | 3.4 |
| Model 10 | 19.1 | 11 | 2,060 | 24 | 2.1 |
| Model 11 | 13.9 | 9 | 2,430 | 78 | 2.5 |
| Model 12 | 18.4 | 11 | 1,046 | 42 | 1.3 |
| Model 13 | 9 | 5 | 343 | 55 | 4 |
| Model 14 | 16.7 | 13 | 3,837 | 36 | 4 |
| Model 15 | 20.8 | 18 | 3,644 | 107 | 4.8 |
| Model 16 | 16.2 | 14 | 4,053 | 28 | 1.5 |
| Model 17 | 15.9 | 13 | 1,664 | 114 | 1.3 |
| Model 18 | 10.4 | 4 | 3,600 | 75 | 1.9 |
| Model 19 | 20.6 | 14 | 1,052 | 124 | 3.5 |
| Model 20 | 17 | 4 | 2,367 | 50 | 3.5 |
| Model 21 | 21 | 6 | 2,545 | 96 | 3.1 |
| Model 22 | 20.1 | 22 | 3,674 | 115 | 3.2 |
| Model 23 | 18.7 | 13 | 2,686 | 108 | 1.8 |
| Model 24 | 21.4 | 7 | 863 | 60 | 2.6 |
| Model 25 | 12.8 | 12 | 4,163 | 95 | 2.4 |
| Model 26 | 22.9 | 3 | 3,148 | 135 | 3.5 |
| Model 27 | 12.6 | 12 | 3,104 | 124 | 4.2 |
| Model 28 | 18.2 | 10 | 2,765 | 131 | 2.3 |
| Model 29 | 18.3 | 8 | 922 | 106 | 3.9 |
| Model 30 | 9 | 9 | 886 | 32 | 2 |
| node | group | degree | weight |
|---|---|---|---|
| Archive 1 | Archive | 3 | |
| Archive 2 | Archive | 9 | |
| Archive 3 | Archive | 5 | |
| Archive 4 | Archive | 8 | |
| Archive 5 | Archive | 5 | |
| Archive 6 | Archive | 6 | |
| Archive 7 | Archive | 6 | |
| Archive 8 | Archive | 3 | |
| Archive 9 | Archive | 5 | |
| Archive 10 | Archive | 6 | |
| Studio 1 | Studio | 3 | |
| Studio 2 | Studio | 4 | |
| Studio 3 | Studio | 3 | |
| Studio 4 | Studio | 3 | |
| Studio 5 | Studio | 7 | |
| Studio 6 | Studio | 4 | |
| Studio 7 | Studio | 4 | |
| Studio 8 | Studio | 4 | |
| Studio 9 | Studio | 6 | |
| Studio 10 | Studio | 3 | |
| Lab 1 | Lab | 5 | |
| Lab 2 | Lab | 5 | |
| Lab 3 | Lab | 1 | |
| Lab 4 | Lab | 2 | |
| Lab 5 | Lab | 2 | |
| Lab 6 | Lab | 4 | |
| Lab 7 | Lab | 2 | |
| Lab 8 | Lab | 4 | |
| Lab 9 | Lab | 4 | |
| Lab 10 | Lab | 2 | |
| Press 1 | Press | 6 | |
| Press 2 | Press | 4 | |
| Press 3 | Press | 10 | |
| Press 4 | Press | 6 | |
| Press 5 | Press | 1 | |
| Press 6 | Press | 5 | |
| Press 7 | Press | 6 | |
| Press 8 | Press | 7 | |
| Press 9 | Press | 3 | |
| Press 10 | Press | 4 | |
| Studio 5 – Studio 2 | 5 | ||
| Press 10 – Archive 6 | 1 | ||
| Press 1 – Press 7 | 5 | ||
| Studio 6 – Studio 4 | 1 | ||
| Press 3 – Lab 6 | 1 | ||
| Studio 8 – Studio 5 | 5 | ||
| Archive 5 – Archive 7 | 2 | ||
| Press 2 – Press 1 | 3 | ||
| Archive 4 – Archive 2 | 5 | ||
| Lab 8 – Studio 8 | 2 | ||
| Archive 4 – Archive 1 | 1 | ||
| Press 3 – Studio 9 | 5 | ||
| Lab 1 – Studio 5 | 5 | ||
| Studio 7 – Studio 9 | 4 | ||
| Press 1 – Press 4 | 5 | ||
| Archive 2 – Archive 9 | 1 | ||
| Archive 3 – Archive 5 | 2 | ||
| Press 10 – Press 8 | 3 | ||
| Press 4 – Archive 10 | 1 | ||
| Press 4 – Press 10 | 2 | ||
| Lab 10 – Studio 9 | 4 | ||
| Lab 6 – Lab 2 | 4 | ||
| Archive 1 – Studio 3 | 4 | ||
| Lab 9 – Lab 2 | 2 | ||
| Press 3 – Press 6 | 2 | ||
| Press 6 – Press 1 | 4 | ||
| Studio 8 – Studio 2 | 4 | ||
| Archive 9 – Archive 8 | 3 | ||
| Lab 2 – Lab 1 | 3 | ||
| Archive 3 – Studio 10 | 3 | ||
| Press 9 – Press 2 | 3 | ||
| Press 4 – Press 7 | 1 | ||
| Studio 6 – Studio 5 | 4 | ||
| Studio 3 – Studio 5 | 5 | ||
| Archive 10 – Archive 4 | 3 | ||
| Studio 1 – Studio 9 | 1 | ||
| Archive 2 – Archive 7 | 3 | ||
| Studio 8 – Studio 9 | 4 | ||
| Archive 6 – Archive 4 | 1 | ||
| Press 3 – Press 1 | 2 | ||
| Studio 7 – Studio 5 | 4 | ||
| Archive 2 – Archive 5 | 1 | ||
| Press 8 – Press 1 | 4 | ||
| Archive 2 – Archive 1 | 2 | ||
| Studio 6 – Studio 7 | 5 | ||
| Archive 4 – Press 8 | 3 | ||
| Studio 4 – Studio 1 | 1 | ||
| Press 3 – Archive 10 | 2 | ||
| Archive 3 – Archive 6 | 1 | ||
| Studio 1 – Studio 2 | 4 | ||
| Archive 5 – Archive 10 | 4 | ||
| Lab 7 – Lab 4 | 1 | ||
| Archive 4 – Archive 5 | 2 | ||
| Archive 7 – Studio 4 | 3 | ||
| Press 7 – Lab 8 | 3 | ||
| Press 2 – Press 3 | 3 | ||
| Lab 9 – Lab 4 | 5 | ||
| Press 8 – Archive 6 | 1 | ||
| Lab 6 – Lab 9 | 2 | ||
| Press 9 – Press 8 | 3 | ||
| Studio 10 – Lab 5 | 3 | ||
| Press 8 – Press 3 | 3 | ||
| Studio 9 – Studio 10 | 4 | ||
| Lab 1 – Lab 3 | 5 | ||
| Archive 3 – Archive 2 | 4 | ||
| Lab 6 – Lab 5 | 3 | ||
| Lab 2 – Studio 7 | 2 | ||
| Archive 8 – Archive 4 | 1 | ||
| Press 4 – Archive 3 | 2 | ||
| Lab 8 – Archive 7 | 4 | ||
| Press 5 – Press 3 | 5 | ||
| Press 6 – Press 9 | 2 | ||
| Press 7 – Press 10 | 3 | ||
| Archive 6 – Archive 2 | 4 | ||
| Archive 9 – Archive 4 | 1 | ||
| Lab 1 – Archive 10 | 1 | ||
| Press 8 – Press 6 | 4 | ||
| Archive 2 – Archive 10 | 5 | ||
| Lab 2 – Lab 10 | 5 | ||
| Archive 8 – Archive 7 | 2 | ||
| Press 3 – Studio 6 | 2 | ||
| Press 4 – Press 6 | 3 | ||
| Lab 8 – Studio 5 | 4 | ||
| Studio 2 – Studio 3 | 3 | ||
| Lab 9 – Lab 1 | 4 | ||
| Archive 9 – Archive 6 | 5 | ||
| Press 7 – Press 3 | 2 | ||
| Press 7 – Press 2 | 1 | ||
| Archive 7 – Archive 9 | 5 | ||
| Lab 7 – Archive 2 | 4 |
17 form and display components, drawn by the same hand
Buttons, inputs, checkboxes, switches, sliders, tabs, steps, cards, tags, badges, progress, alerts and skeletons, with frames hand-drawn by each ground's own inker. A native control underneath every one: forms submit, the keyboard follows the WAI-ARIA patterns, and precision mode switches the inking off. Every control on this site is one of them.
Why silverpoint
Exact data, drawn ornament
The hand irregularity lives only in strokes that carry no data. Every encoded vertex is exact.
A precision mode
mode="precision" switches the inking off. Charts switch by themselves under prefers-contrast and forced-colors.
Deterministic
No Math.random on the render path: the seed derives from the id, so the same props draw the same strokes, on server and client.
Accessible
An accessible name and description, a hidden data table, keyboard exploration and announced readouts.
Server-rendered
React Server Components, @vue/server-renderer and @angular/ssr, hydrating without a mismatch.
Pay for what you use
One subpath per chart, a framework-free core, tree-shakeable. The core's full bundle stays under 45 kB.
Two grounds
Tone is hatch density on the silverpoint ground, and line weight on cyanotype. No chart code changes between them: ground="cyanotype" on a chart, the provider or a dashboard.
Grounds & substrates →| x | value |
|---|---|
| Mon | 32 |
| Tue | 45 |
| Wed | 41 |
| Thu | 58 |
| Fri | 66 |
| Sat | 38 |
| Sun | 29 |
| x | value |
|---|---|
| Mon | 32 |
| Tue | 45 |
| Wed | 41 |
| Thu | 58 |
| Fri | 66 |
| Sat | 38 |
| Sun | 29 |
Also in Python, with Reflex
reflex-silverpoint-react wraps @silverpoint/react as a Reflex custom component: the 60 charts, the Dashboard, the 17 UI components, the provider, events, custom readouts and SVG export, as Python, and the palettes, 21 composed components and overlays and the Knight Lab timeline of silverpoint 0.7. Version 0.8.0 wraps @silverpoint/react 0.8.0. This site is built with it.
import reflex as rx
from reflex_silverpoint_react import donut_chart, radar_chart
rx.hstack(
donut_chart(data=budget, name_key="name", value_key="value", title="Budget"),
radar_chart(data=profile, subject_key="subject", value_key="value", title="Profile"),
)| name | value | share |
|---|---|---|
| Rent | 38 | 38% |
| Food | 22 | 22% |
| Savings | 15 | 15% |
| Transport | 14 | 14% |
| Leisure | 11 | 11% |
| subject | value |
|---|---|
| Speed | 8 |
| Range | 6 |
| Comfort | 7 |
| Safety | 9 |
| Cost | 4 |
| Style | 6 |
| direction | share | < 5 | 5–10 | 10–15 | 15–20 | ≥ 20 |
|---|---|---|---|---|---|---|
| N | 11% | 1% | 5% | 4% | 0% | 0% |
| NNE | 7% | 1% | 3% | 2% | 0% | 0% |
| NE | 4% | 0% | 2% | 1% | 0% | 0% |
| ENE | 4% | 1% | 3% | 1% | 0% | 0% |
| E | 13% | 0% | 7% | 5% | 0% | 0% |
| ESE | 5% | 0% | 2% | 3% | 0% | 0% |
| SE | 4% | 0% | 1% | 2% | 1% | 0% |
| SSE | 6% | 0% | 3% | 1% | 1% | 0% |
| S | 7% | 0% | 2% | 2% | 1% | 1% |
| SSW | 5% | 0% | 1% | 3% | 0% | 1% |
| SW | 3% | 0% | 1% | 1% | 1% | 0% |
| WSW | 2% | 0% | 1% | 1% | 0% | 0% |
| W | 3% | 1% | 1% | 1% | 0% | 0% |
| WNW | 6% | 0% | 1% | 2% | 1% | 1% |
| NW | 11% | 0% | 3% | 4% | 3% | 1% |
| NNW | 6% | 0% | 3% | 3% | 1% | 0% |