npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@silverpoint/angular

v0.6.0

Published

Angular adapter of silverpoint: standalone, signal-input, OnPush components in Angular Package Format.

Readme

@silverpoint/angular

Angular components for silverpoint: charts drawn in the manner of a Renaissance silverpoint drawing, with a fine silver line on a prepared ground, tone built from hatching, and white heightening on the live value. The hand-drawn irregularity is only in the ornament. The data geometry is exact, and every chart has a precision mode that turns the inking off.

  • 60 standalone components with signal inputs and OnPush. They work zoneless.
  • Angular Package Format, with one secondary entry point per chart, so you only ship the charts you use.
  • Accessible: an accessible name, a hidden data table, keyboard navigation, and a prefers-contrast / forced-colors fallback to precision.

Installation

npm install @silverpoint/angular @silverpoint/grounds @silverpoint/fonts

| Package | Why | |---|---| | @silverpoint/angular | The components. Brings @silverpoint/core with it. | | @silverpoint/grounds | The stylesheet (styles.css) that colours the strokes. Required. | | @silverpoint/fonts | Optional. Self-hosted EB Garamond, the typeface the charts are designed for. |

Peer dependencies: @angular/core and @angular/common >=21.0.0 <23.0.0 (Angular 21 and 22). Built with the Angular CLI (@angular/build, on Vite). No extra configuration is needed.

Load the two stylesheets once, as global styles.

Quickstart (Angular CLI)

npx @angular/cli@22 new my-charts --defaults --skip-git
cd my-charts
npm install @silverpoint/angular @silverpoint/grounds @silverpoint/fonts

Replace src/styles.css with:

@import '@silverpoint/fonts/fonts.css';
@import '@silverpoint/grounds/styles.css';

Replace src/app/app.ts with:

import { Component } from '@angular/core';
import { SpLineChart } from '@silverpoint/angular/line-chart';

@Component({
  selector: 'app-root',
  imports: [SpLineChart],
  template: `
    <div style="width: 480px">
      <sp-line-chart [data]="data" xKey="hour" valueKey="hits" title="Hits per hour" />
    </div>
  `,
})
export class App {
  protected readonly data = [
  { hour: '00', hits: 18 },
  { hour: '04', hits: 11 },
  { hour: '08', hits: 42 },
  { hour: '12', hits: 64 },
  { hour: '16', hits: 57 },
  { hour: '20', hits: 30 },
];
}

Then run npm start. The chart takes the width of its container. height is the height of the drawing area and defaults to 160 px.

Examples

One ground for the whole app

provideSilverpoint sets the ground, the substrate, the mode and the locale for every chart. An input on a chart overrides it.

// 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' }),
  ],
};
import { Component } from '@angular/core';
import { SpBarChart } from '@silverpoint/angular/bar-chart';
import { SpDonutChart } from '@silverpoint/angular/donut-chart';

@Component({
  selector: 'app-dashboard',
  imports: [SpBarChart, SpDonutChart],
  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="%" />
  `,
})
export class Dashboard {
  protected readonly sales = [
    { month: 'Jan', units: 120 },
    { month: 'Feb', units: 98 },
    { month: 'Mar', units: 143 },
  ];
  protected readonly channels = [
    { channel: 'Web', share: 54 },
    { channel: 'Stores', share: 31 },
    { channel: 'Partners', share: 15 },
  ];
}

Substrates: cream (the default), green, blue, ochre.

Precision mode

mode="precision" switches the inking off entirely and draws exact, even strokes. The chart switches to it by itself when the system asks for more contrast (prefers-contrast: more or forced-colors: active). No input can override that.

<sp-line-chart [data]="data" xKey="hour" valueKey="hits" title="Hits per hour" mode="precision" />

Interaction and a custom readout

import { Component, input, signal } from '@angular/core';
import { SpTooltip } from '@silverpoint/angular';
import { SpLineChart } from '@silverpoint/angular/line-chart';

type Row = { hour: string; hits: number };

@Component({
  selector: 'app-explorer',
  imports: [SpLineChart, SpTooltip],
  template: `
    <sp-line-chart
      [data]="data()"
      xKey="hour"
      valueKey="hits"
      title="Hits per hour"
      (activeChange)="active.set($event ? $event.datum['hour'] + ': ' + $event.value : '—')"
      (select)="selected($event.datum)"
    >
      <ng-template spTooltip let-item>
        <strong>{{ item.value }} hits</strong>
      </ng-template>
    </sp-line-chart>
    <p>Under the pointer: {{ active() }}</p>
  `,
})
export class Explorer {
  readonly data = input.required<Row[]>();
  protected readonly active = signal('—');
  protected selected(datum: unknown) {
    console.log('selected', datum);
  }
}

(activeChange) carries the item under the pointer or keyboard focus, and null when it leaves. (select) fires on click, Enter or Space.

Imperative handle

Each component exposes getGeometry() and toSVGString():

import { Component, viewChild } from '@angular/core';
import { SpLineChart } from '@silverpoint/angular/line-chart';

@Component({
  selector: 'app-exportable',
  imports: [SpLineChart],
  template: `
    <sp-line-chart #chart [data]="data" xKey="hour" valueKey="hits" title="Hits per hour" />
    <button (click)="download()">Export SVG</button>
  `,
})
export class Exportable {
  protected readonly data = [
    { hour: '00', hits: 18 },
    { hour: '12', hits: 64 },
  ];
  private readonly chart = viewChild.required<SpLineChart>('chart');

  protected download() {
    const svg = this.chart().toSVGString();
    window.open(URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' })));
  }
}

Inputs every chart shares

| Input | Default | | |---|---|---| | data | demo dataset | The rows to draw. | | ground / substrate / mode | 'silverpoint' / 'cream' / 'ink' | Style; mode: 'precision' turns off inking. | | seed, id | derived, stable | The hand drawing is deterministic: same inputs, same strokes. | | height, width | 160, container width | Size of the drawing area in px. | | chrome | 'card' | 'bare' draws only the plot. | | title, badge, value, unit, footerLeft, footerRight | — | The card's text. | | label, description, dataTable | from title, —, 'hidden' | Accessibility. | | locale, numberFormat | environment | Number formatting. | | hatchFill | 'tile' | 'per-shape' gives richer hatching at a much greater weight. |

The 60 charts

Every chart is a secondary entry point, @silverpoint/angular/<kebab-case-name>, exporting the Sp… component with the sp-… selector:

| Component | Selector | Component | Selector | |---|---|---|---| | SpLineChart | sp-line-chart | SpDonutChart | sp-donut-chart | | SpStepChart | sp-step-chart | SpRadarChart | sp-radar-chart | | SpSparklineRows | sp-sparkline-rows | SpPolarBarChart | sp-polar-bar-chart | | SpKpiCard | sp-kpi-card | SpRadialArcGroup | sp-radial-arc-group | | SpBarChart | sp-bar-chart | SpRadialRings | sp-radial-rings | | SpStackedBarChart | sp-stacked-bar-chart | SpGaugeArc | sp-gauge-arc | | SpComposedChart | sp-composed-chart | SpMeterChart | sp-meter-chart | | SpWaterfallChart | sp-waterfall-chart | SpScatterChart | sp-scatter-chart | | SpFunnelChart | sp-funnel-chart | SpBubbleChart | sp-bubble-chart | | SpBulletChart | sp-bullet-chart | SpHeatmapChart | sp-heatmap-chart | | SpPyramidChart | sp-pyramid-chart | SpTreemapChart | sp-treemap-chart | | SpCandlestickChart | sp-candlestick-chart | SpSankeyChart | sp-sankey-chart | | SpAreaChart | sp-area-chart | SpActivityGrid | sp-activity-grid | | SpRangeBandChart | sp-range-band-chart | SpCoxcombChart | sp-coxcomb-chart | | SpStreamChart | sp-stream-chart | SpWindRose | sp-wind-rose | | SpVolvelleChart | sp-volvelle-chart | SpChordRing | sp-chord-ring | | SpOrbitChart | sp-orbit-chart | | |

The second catalog, for distributions, comparisons, ranks and uncertainty (since 0.6.0):

| Component | Selector | Component | Selector | |---|---|---|---| | SpHistogramChart | sp-histogram-chart | SpEcdfChart | sp-ecdf-chart | | SpBoxPlotChart | sp-box-plot-chart | SpViolinChart | sp-violin-chart | | SpRidgelineChart | sp-ridgeline-chart | SpBeeswarmChart | sp-beeswarm-chart | | SpLollipopChart | sp-lollipop-chart | SpDumbbellChart | sp-dumbbell-chart | | SpSlopeChart | sp-slope-chart | SpBumpChart | sp-bump-chart | | SpErrorBarChart | sp-error-bar-chart | SpIntervalChart | sp-interval-chart | | SpDivergingBarChart | sp-diverging-bar-chart | SpConnectedScatterChart | sp-connected-scatter-chart |

Hierarchies, parts of a whole, many dimensions and polar charts (since 0.6.0):

| Component | Selector | Component | Selector | |---|---|---|---| | SpWaffleChart | sp-waffle-chart | SpMarimekkoChart | sp-marimekko-chart | | SpSquarifiedTreemap | sp-squarified-treemap | SpSunburstChart | sp-sunburst-chart | | SpTreeChart | sp-tree-chart | SpParallelCoordinatesChart | sp-parallel-coordinates-chart | | SpPolarLineChart | sp-polar-line-chart | SpPolarScatterChart | sp-polar-scatter-chart |

Fields and networks (since 0.6.0):

| Component | Selector | Component | Selector | |---|---|---|---| | SpDensityBinChart | sp-density-bin-chart | SpContourChart | sp-contour-chart | | SpDelaunayChart | sp-delaunay-chart | SpVectorFieldChart | sp-vector-field-chart | | SpNetworkChart | sp-network-chart | | |

<sp-ridgeline-chart> requires groupKey, <sp-diverging-bar-chart> requires levels and <sp-parallel-coordinates-chart> requires dimensions (input.required), even with the demo dataset, which ignores them.

<sp-squarified-treemap> and <sp-sunburst-chart> drill down under your control: bind [rootId] and update it from (rootChange), which a click, Enter or Space on a node emits with its id (its centre or frame emits the parent's, null for the top). The component keeps no root of its own.

The repository holds the API specification and the documentation site with the gallery and every chart's inputs.

Related packages

@silverpoint/react · @silverpoint/vue · @silverpoint/grounds · @silverpoint/fonts · @silverpoint/core

MIT.