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

@bsol-oss/mathdiagram

v0.1.0

Published

React SVG renderer for declarative exam-style math and geometry diagrams.

Readme

MathDiagram

MathDiagram is a React SVG diagram renderer for student-friendly math and geometry diagrams. It is built for plain Vite/React projects and uses local SVG rendering only: no hosted embeds, no Three.js, no Babylon.js, and no commercial diagram platform.

The core idea is simple: pass a JSON-friendly spec object to <MathDiagram />, and the renderer draws the matching 2D or 3D exam-style diagram.

Quick Start

Install and run this repo:

npm install
npm run dev

Open the demo app and go to #/mathdiagram/3d-solids to see the live editable MathDiagram examples.

Use In React

Install the package:

npm install @bsol-oss/mathdiagram

Import the component and stylesheet in any React/Vite app:

import { MathDiagram } from '@bsol-oss/mathdiagram';
import '@bsol-oss/mathdiagram/style.css';

export function Example() {
  return <MathDiagram spec={{
    kind: 'volume',
    shape: 'rectangular_prism',
    color: 'green',
    arrowColor: 'auto',
    canvas: {
      width: 420,
      height: 270,
      fit: 'contain',
      padding: 32
    },
    dimensions: {
      length: 4,
      width: 3,
      height: 2,
      unit: 'cm'
    },
    view: {
      azimuth: 45,
      elevation: 30
    },
    header: {
      text: 'V = l x w x h',
      position: 'left-upper'
    }
  }} />;
}

The current repo also keeps the library source in src/diagrams for local development. If you do not want to use npm yet, copy that folder into another React project and import ./diagrams/MathDiagram.jsx directly.

You can also render from JSON:

const spec = JSON.parse(jsonText);

<MathDiagram spec={spec} />

Component API

MathDiagram currently accepts one prop:

| Prop | Type | Description | | --- | --- | --- | | spec | object | Declarative diagram configuration. Must include shape. |

If the spec is invalid, the component renders a visible validation error instead of throwing.

Spec Model

Common top-level keys:

| Key | Type | Description | | --- | --- | --- | | shape | string | Diagram renderer to use, such as rectangle, cube, or triangular_prism. | | kind | string | Optional teaching context, usually volume. Net diagrams are not supported. | | dimensions | object | Numeric dimensions and unit. These drive labels and proportional geometry. | | layoutDimensions | object | Numeric fallback dimensions for unknown values like height: '?'. | | unknowns | string[] | Dimension keys to display as unknowns. | | measurements | array | Optional list of dimension arrows/labels to show. | | canvas | object | SVG output size and scaling behavior. | | view | object/string | 3D viewing angle for supported 3D shapes. | | color | string | Per-shape color name. | | arrowColor | string | auto or a supported color name for dimension arrows. | | header | object | Annotation badge with text and named position. | | remarks | object | Secondary annotation badge with text and named position. | | labels | array | Extra annotation badges. | | alt | string | Accessible label for the SVG. |

Canvas Sizing

Use canvas.width and canvas.height to specify the rendered SVG size. The default fit: 'contain' scales the internal diagram coordinate system into that canvas.

canvas: {
  width: 420,
  height: 270,
  fit: 'contain',
  padding: 32
}

Use viewBoxWidth and viewBoxHeight only when you need a custom SVG coordinate space:

canvas: {
  width: 520,
  height: 300,
  viewBoxWidth: 520,
  viewBoxHeight: 300,
  padding: 36
}

Supported Shapes

2D shapes:

  • rectangle
  • square
  • triangle
  • right_triangle
  • circle
  • trapezoid
  • parallelogram
  • regular_polygon
  • composite_2d

3D solids:

  • rectangular_prism
  • cube
  • cylinder
  • cone
  • square_pyramid
  • rectangular_pyramid
  • triangular_prism
  • sphere
  • hemisphere
  • capsule
  • triangular_pyramid
  • frustum_cone
  • frustum_pyramid
  • composite_3d

Legacy shape: 'composite' is still routed to the 3D composite renderer, but new specs should use composite_3d.

Dimension Names

Preferred public dimension keys:

| Shape | Dimensions | | --- | --- | | rectangle | length, width, unit | | square | side, unit | | triangle | base, height, topOffset, unit | | right_triangle | base, height, hypotenuse, unit | | circle | radius, unit | | trapezoid | bottomBase, topBase, height, unit | | parallelogram | base, height, side, unit | | regular_polygon | sides, side, unit | | rectangular_prism | length, width, height, unit | | cube | side, unit | | cylinder | radius, height, unit | | cone | radius, height, slantHeight, unit | | square_pyramid | baseSide, height, unit | | rectangular_pyramid | length, width, height, unit | | triangular_prism | base, triangleHeight, length, unit | | triangular_pyramid | base, baseHeight, height, unit | | frustum_cone | topRadius, bottomRadius, height, unit | | frustum_pyramid | topLength, topWidth, bottomLength, bottomWidth, height, unit |

topOffset means the horizontal distance from the left base endpoint to the vertical foot of the triangle's top vertex. If omitted, the triangle defaults to an isosceles layout with topOffset = base / 2.

Older aliases such as apexX, legA, legB, baseA, baseB, and sideLength are kept internally for compatibility, but new JSON should use the clearer names above.

Measurements And Unknowns

By default, renderers show their standard measurements. You can restrict or relabel them with measurements:

measurements: [
  { target: 'base' },
  { target: 'height', label: 'h = ?' }
]

For exam questions with unknown values, put the visible value in dimensions, provide a numeric fallback in layoutDimensions, and list the unknown key in unknowns:

{
  shape: 'triangle',
  dimensions: { base: 8, height: '?', topOffset: 3, unit: 'cm' },
  layoutDimensions: { height: 5 },
  unknowns: ['height'],
  measurements: [
    { target: 'base' },
    { target: 'height', label: 'h = ?' }
  ]
}

Annotations

Use header, remarks, and labels for diagram text. They use named positions instead of exact coordinates.

header: { text: 'A = 1/2 bh', position: 'left-upper' },
remarks: { text: 'Find h', position: 'right-lower' },
labels: [{ text: 'radius shown', position: 'right-lower' }]

Supported positions:

  • left-upper
  • center-upper
  • right-upper
  • left-middle
  • center-middle
  • right-middle
  • left-lower
  • center-lower
  • right-lower

Colors

Use one color per shape. Composite diagrams can set color per part.

Supported color names:

  • blue
  • sky
  • cyan
  • green
  • lime
  • yellow
  • orange
  • red
  • pink
  • purple
  • slate
  • neutral

Use arrowColor: 'auto' for contrast-friendly dimension arrows, or override it with one of the supported color names.

3D Viewing Angle

Supported 3D renderers accept either a preset string or an angle object:

view: { azimuth: 45, elevation: 30 }

Presets:

  • isometric
  • textbook
  • front
  • right
  • top
  • left
  • right_down
  • left_down

Composite Examples

2D additive composite:

{
  shape: 'composite_2d',
  operation: 'add',
  parts: [
    { shape: 'rectangle', color: 'blue', dimensions: { length: 8, width: 4, unit: 'cm' }, position: { x: 0, y: 0 } },
    { shape: 'rectangle', color: 'orange', dimensions: { length: 3, width: 5, unit: 'cm' }, position: { x: 0, y: 4 } }
  ]
}

3D additive composite:

{
  shape: 'composite_3d',
  operation: 'add',
  view: { azimuth: 45, elevation: 30 },
  canvas: { width: 520, height: 300 },
  parts: [
    { id: 'A', shape: 'rectangular_prism', color: 'blue', dimensions: { length: 8, width: 4, height: 2, unit: 'cm' }, position: { x: 0, y: 0, z: 0 } },
    { id: 'B', shape: 'rectangular_prism', color: 'orange', dimensions: { length: 3, width: 4, height: 5, unit: 'cm' }, position: { x: 5, y: 0, z: 2 } }
  ]
}

Validation

Run a production build:

npm run build

The current app also includes live JSON editors on the MathDiagram page so you can test each supported shape interactively.