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

@demo-charts/renderer-3d

v0.1.34

Published

Standalone 3D renderer and chart primitives

Readme

3D chart (@demo-charts/renderer-3d)

This package implements the phase-resolved 3D bar (“PRPD-style”) chart: vertical spikes over a phase × cycle floor, with an optional reference curve on the back wall, orbit camera, and tooltips.


High-level architecture

App / React
    │
    ▼
RmChart3D              ← thin facade: setSeries, updateOptions, resize, destroy
    │
    ▼
ChartController3D      ← DOM, input, camera state, tooltip, series transitions
    │
    ▼
Canvas3DRenderer       ← single HTML canvas, 2D context: full scene draw + hit-test
    │
    ▼
PhaseGraph3DSeries     ← normalized spike + wall-curve data, styles, bounds, interpolation

Exported public API: RmChart3D, ChartController3D, PhaseGraph3DSeries, and types from ./types.

Scene graph, coordinates, and WebGL background passes are described in PRPD_WEBGL_SCENE_ARCHITECTURE.md.

The React wrapper (@demo-charts/reactRmChart3DComponent) mounts a div, constructs RmChart3D({ ...options, container }), and calls setSeries when the series instance changes.


Data model: PhaseGraph3DSeries

A series is defined by parallel arrays of equal length:

| Field | Role (typical PRPD mapping) | |--------|-----------------------------| | phase | X on the floor (e.g. phase angle 0…360°) | | cycle | Z on the floor (e.g. cycle index) | | amplitude | Height of the bar (Y) |

Optional wallCurve: phase[] + amplitude[] — a polyline on the back vertical wall (phase vs amplitude), e.g. a sine reference.

Style (PhaseGraph3DSeriesStyle): bar color, stroke, wall curve color, spike width / depth, spike radius (0 = rectangular pillar, higher = rounder cap toward “cylinder”), wall line width.

The constructor normalizes inputs to number[] and truncates to the common length. getBounds() computes min/max over spikes (and wall curve for phase/amplitude) for axis scaling.

PhaseGraph3DSeries.interpolate(from, to, t) blends two series for smooth transitions when ChartController3D animates a data update.


Controller: ChartController3D

Responsibilities:

  1. Container — Resolves container from a CSS selector or HTMLElement, positions it relative, injects:

    • One canvas (full size of container).
    • One tooltip div (absolute, non-interactive, high z-index).
  2. Camera — Orbital parameters (degrees / distance):

    • yaw, pitch — updated by drag (pointer delta → clamped angles).
    • distance — dollies in/out with the mouse wheel (clamped to minDistance / maxDistance from options).
  3. Interaction (see Chart3DInteractionOptions):

    • Rotate: pointer drag on canvas (unless interaction.rotate === false).
    • Zoom: wheel (unless interaction.zoom === false).
    • Double-click: resets camera toward options defaults (camera.yaw, pitch, distance).
    • Tooltip: pointer move runs hit-test; if a spike is hit, shows phase / amplitude / cycle (unless interaction.tooltip === false).
  4. Pointer wiring — Uses pointerdown / pointermove / pointerup / pointerleave on the canvas; pointermove / pointerup are registered on window so dragging continues outside the element.

  5. ResizeResizeObserver on the container calls resize() → matches canvas backing store (with devicePixelRatio cap) and re-renders.

  6. Series updatessetSeries(series):

    • First series: immediate assign + render.
    • Later updates: starts a short transition (~220 ms) interpolating from the previous series to the new one via PhaseGraph3DSeries.interpolate, driven by requestAnimationFrame.

Rendering: Canvas3DRenderer

Uses getContext('2d') only for the shipped path: no WebGL in this pipeline.

render(series, options, state, hoverHit?) pipeline (order matters for painter’s algorithm):

  1. Clear and fill background (from theme / darkMode).
  2. buildProjection — Builds a simple perspective state from canvas size + yaw / pitch / distance (focal length, camera Z, center on screen). This is custom projection math (not a full scene graph).
  3. drawFloor — Floor plane with grid, striped cells (light/dark), clipped to the chart volume.
  4. drawHoverFloorGuide — On spike hover: L-shaped floor guides (phaseₘᵢₙ,cycle)→(phase,cycle)→(phase,cycleₘᵢₙ). Colour theme.hoverFloorGuideColor (default #ff6a14 in resolveChart3DTheme). Stroke thickness follows pillars (~half the narrower pillar semi-axis → pillarGraphHalfExtents). WebGL: renderHoverFloorCrosshair uses ribbon quads; same hoverHit as the tooltip.
  5. drawWall — Back wall quads + grid (behind the data volume).
  6. drawWallCurve — The reference polyline on the wall from series.getWallCurve().
  7. drawSpikes — For each spike, project base + top to screen; sort by depth (back to front); draw each spike as a filled trapezoid (body) + strokes + optional rounded cap at the top (pillar vs rounded style from spikeRadius).
  8. drawAxesAndLabels — Axis titles, ticks, numeric labels (from xAxis / yAxis / zAxis in options), using resolved theme and typography.

HiDPI: The canvas bitmap is scaled by dpr (capped at 2); drawing uses logical coordinates after ctx.scale(dpr, dpr).

Hit-test (hitTest) — Rebuilds the same projected spike segments as buildSpikeItems, iterates front to back (reverse of draw order), finds the closest spike whose screen-space distance from the pointer to the base–top segment is within a tolerance. Returns Chart3DHitResult: phase, cycle, amplitude, index, and screen point at the top.


Options (Chart3DOptions)

  • container — Selector string or element (required).
  • width / height — Optional explicit size; else container client size on resize.
  • darkMode + theme — Background, floor checkerboard tiles (floorStripeA / floorStripeB), wall amplitude bands (wallStripeA / wallStripeB; wallFill still overrides stripe A in the WebGL adapter only), grid (floorGrid / wallGrid), axis and default spike colors.
  • xAxis, yAxis, zAxis — Labels, min/max, tick count or tick values, formatLabel, per-axis typography colors/sizes/fonts.
  • camera — Initial / reset yaw, pitch, distance, min/max distance for zoom.
  • interaction — Toggle rotate, zoom, tooltip.
  • tooltip — Colors, font.

Axis mapping in the 3D scene is handled inside the renderer (phase/cycle/amplitude bounds vs. the fixed “graph box” in projection space); see resolveBounds / projection helpers in Canvas3DRenderer.ts.


Optional / internal GPU path

The default rendererBackend is auto, which prefers WebGL2 instanced pillars + a transparent Canvas2D overlay for axis labels. Set rendererBackend: 'canvas2d' to force the legacy full Canvas2D path.

Internals: WebGLPhaseSpikeRenderer, WebGLChart3DAdapter, GPU picking, chunking, renderPassGraph.ts (explicit background → pillar passes), gpuGraphProjection.ts, interleave worker (gpuInterleaveWorkerSource.ts), optional prpdAggregationLod (phase×cycle bins), data-prep worker string (prpdDataPrepWorkerSource.ts), and WebGPUComputeBackend (stub for future compute).


Package entry

src/index.ts exports:

  • ./types
  • ./PhaseGraph3DSeries
  • ./ChartController3D
  • ./Canvas3DRenderer
  • ./RmChart3D

Typical usage (vanilla)

import { RmChart3D, PhaseGraph3DSeries } from '@demo-charts/renderer-3d';

const chart = new RmChart3D({
  container: '#chart-3d',
  xAxis: { label: 'Phase Angle (deg)', min: 0, max: 360, /* ... */ },
  yAxis: { label: 'Amplitude (mVp)', min: 0, max: 2000, /* ... */ },
  zAxis: { label: 'Cycle', min: 0, max: 50, /* ... */ },
  camera: { yaw: -50, pitch: 32, distance: 3.65, maxDistance: 28 },
  interaction: { rotate: true, zoom: true, tooltip: true },
});

chart.setSeries(
  new PhaseGraph3DSeries({
    name: '3D Phase Distribution',
    spikes: { phase, cycle, amplitude },
    wallCurve: { phase: wallPhase, amplitude: wallAmp },
    style: { spikeColor: '#42a5f5', spikeStroke: '#1565c0', /* ... */ },
  })
);

Optional camera tuning: orbitRadiusBase overrides the additive orbit radius base, orbitTarget sets a graph-space look-at pivot (ignored when autoFit: 'spikes'), and autoFit: 'spikes' recenters on sampled spike centroids with a gentle zoom scale for tight clouds.


Files (reference)

| File | Role | |------|------| | RmChart3D.ts | Public API entry | | ChartController3D.ts | Layout, events, camera, tooltip, transitions | | Canvas3DRenderer.ts | 2D canvas drawing + projection + hit-test | | PhaseGraph3DSeries.ts | Data + styles + bounds + interpolation | | math.ts | Angles, color shading helpers | | types.ts | Options and data typings | | WebGLPhaseSpikeRenderer.ts | Optional WebGL instanced pillars (not in default bundle export) |