Concepts
Grounds & substrates
A ground is a whole drawing technique: the prepared substrate, the inks, and how tone is made. A substrate is the colour the ground is prepared on. Neither changes the data geometry.
The two grounds
| Ground | Tone is built by | Substrates |
|---|---|---|
silverpoint | Hatching, drawn by hand (RoughInker). Default. | cream, green, blue, ochre |
cyanotype | The weight of an exact white line on Prussian blue (WeightInker); nothing is hatched. | prussian |
| 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 |
| 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 |
| x | value |
|---|---|
| Mon | 32 |
| Tue | 45 |
| Wed | 41 |
| Thu | 58 |
| Fri | 66 |
| Sat | 38 |
| Sun | 29 |
Setting the ground
On a chart (ground="cyanotype"), on the app-wide provider, or on a Dashboard, which passes it to every chart inside. A prop on a chart always wins.
import { SilverpointProvider } from '@silverpoint/react';
import { BarChart } from '@silverpoint/react/bar-chart';
import { DonutChart } from '@silverpoint/react/donut-chart';
export function Dashboard() {
return (
<SilverpointProvider ground="silverpoint" substrate="green" locale="en-GB">
<BarChart data={sales} xKey="month" valueKey="units" title="Units sold" unit="units" />
<DonutChart data={channels} nameKey="channel" valueKey="share" title="Sales by channel" centerLabel="%" />
</SilverpointProvider>
);
}// src/main.ts
import { createApp } from 'vue';
import { provideSilverpoint } from '@silverpoint/vue';
import App from './App.vue';
createApp(App)
.use(provideSilverpoint({ ground: 'silverpoint', substrate: 'green', locale: 'en-GB' }))
.mount('#app');
<!-- any component -->
<SpBarChart :data="sales" x-key="month" value-key="units" title="Units sold" unit="units" />
<SpDonutChart :data="channels" name-key="channel" value-key="share" title="Sales by channel" center-label="%" />// src/app/app.config.ts
import { type ApplicationConfig, provideZonelessChangeDetection } from '@angular/core';
import { provideSilverpoint } from '@silverpoint/angular';
export const appConfig: ApplicationConfig = {
providers: [
provideZonelessChangeDetection(),
provideSilverpoint({ ground: 'silverpoint', substrate: 'green', locale: 'en-GB' }),
],
};
<!-- any template -->
<sp-bar-chart [data]="sales" xKey="month" valueKey="units" title="Units sold" unit="units" />
<sp-donut-chart [data]="channels" nameKey="channel" valueKey="share" title="Sales by channel" centerLabel="%" />from reflex_silverpoint_react import bar_chart, donut_chart, silverpoint_provider
silverpoint_provider(
bar_chart(data=sales, x_key="month", value_key="units", title="Units sold", unit="units"),
donut_chart(data=channels, name_key="channel", value_key="share",
title="Sales by channel", center_label="%"),
ground="silverpoint",
substrate="green",
locale="en-GB",
)Re-theming with CSS
Every stroke carries a part attribute bound to a public custom property. Overriding a property re-themes the charts without re-rendering them:
.sp-ground-silverpoint[data-substrate='cream'] {
--sp-ink: #4d525a;
--sp-ink-secondary: #6b5a45;
--sp-font-display: 'EB Garamond', Georgia, serif;
}Public properties: --sp-substrate --sp-ink --sp-ink-secondary --sp-heighten --sp-rule --sp-grid --sp-text --sp-text-muted --sp-font-display --sp-stroke-width --sp-hatch-gap --sp-radius --sp-weight-1…4
Mind this
The palette is computed for WCAG contrast, not chosen by eye. If you change an ink, check the contrast again. Every white heightening carries an ink outline so it passes contrast on every substrate.