OMD
A JavaScript library for rendering mathematical visualizations and expressions as SVG.
Installation
npm install @teachinglab/omd
Getting Started
import { omdDisplay } from '@teachinglab/omd';
const display = new omdDisplay(document.getElementById('container'));
// Render a math string
display.render('3*x + 2');
// Render any visualization from JSON — one line
display.loadFromJSON({ omdType: 'numberLine', min: 0, max: 10, dotValues: [3, 7] });
Quick Start
import { omdDisplay, omdNumberLine } from '@teachinglab/omd';
// Render an expression
const display = new omdDisplay(document.getElementById('container'));
display.render('3*x + 2'); // expression
display.render('2*x + 3 = 7'); // equation (auto-detected by =)
// Render a visualization from JSON
display.loadFromJSON({ omdType: 'numberLine', min: 0, max: 10, dotValues: [3, 7] });
// Or build a component and load it
const line = new omdNumberLine();
line.loadFromJSON({ min: 0, max: 10, dotValues: [3, 7] });
display.load(line);
Core Concepts
omdDisplay
Renders a single component into a DOM container. The SVG sizes to fit the content and is aligned within the container.
const display = new omdDisplay(container, {
alignment: 'center', // 'center' | 'left' | 'right' (default: 'center')
autoScale: true, // shrink to fit if too large (default: true)
maxScale: 1, // never upscale past natural size (default: 1)
padding: 8, // padding around content in px (default: 8)
});
display.render('sqrt(x + 4)'); // string → auto-detected
display.loadFromJSON({ omdType: 'numberLine', min: 0, max: 10 }); // from JSON
display.load(myVisual); // pre-built component
display.clear();
display.destroy();
omdCanvas
A multi-object stage. Add components at explicit positions.
const canvas = new omdCanvas(document.getElementById('stage'), {
width: 1100,
height: 500,
});
const plane = new omdCoordinatePlane();
plane.loadFromJSON({ xMin: -5, xMax: 5, yMin: -5, yMax: 5 });
// Position via add options
canvas.add(plane, { x: 30, y: 40 });
// Or position beforehand — equivalent
plane.setPosition(30, 40);
canvas.add(plane);
const eq = new omdEquation();
eq.loadFromJSON('2*x + 3 = 7');
canvas.add(eq, { x: 400, y: 200, scale: 1.5 });
canvas.move(plane, 60, 40);
canvas.remove(eq);
canvas.clear();
Components
Expressions & Equations

| Class | Description | Example input |
|---|---|---|
omdExpression |
Math expression | '3*x + 2' or { expression: '3*x+2', fontSize: 24 } |
omdEquation |
Equation with = |
'2*x + 3 = 7' or { equation: '...', fontSize: 24 } |
omdEquationStack |
Stacked equations aligned by = |
{ equations: ['2x+3=7', '2x=4', 'x=2'] } |
omdEquationWork |
Step-by-step worked solution | { rows: [{kind:'equation', left:'2x+3', right:'7'}, ...] } |
All expression/equation components support:
expr.setBackgroundColor('#fff'); // set background color
expr.hideBackgroundByDefault(); // transparent background
Number Visualizations

| Class | Description |
|---|---|
omdNumberLine |
Number line with optional dot markers |
omdDoubleNumberLine |
Two parallel number lines |
omdBalanceHanger |
Balance scale with variables and numbers |
omdRatioChart |
Pie, dot, or bar ratio chart |
omdSpinner |
Circular spinner with divisions |
Tape Diagrams

| Class | Description |
|---|---|
omdTapeDiagram |
Part-whole tape diagram |
omdDoubleTapeDiagram |
Two stacked tape diagrams |
Graphing & Data

| Class | Description |
|---|---|
omdCoordinatePlane |
2D graph — plot equations, points, segments |
omdTable |
Data table from an equation or manual data |
omdTileEquation |
Algebra tile equation |
Shapes

| Class | Description |
|---|---|
omdRectangle |
Rectangle with dimension labels |
omdRectangularPrism |
3D rectangular prism |
omdRightTriangle |
Right triangle |
omdIsoscelesTriangle |
Isosceles triangle |
omdCircle |
Circle with optional points and segments |
omdEllipse |
Ellipse |
omdAngle |
Angle diagram with rays and arc markers |
omdRegularPolygon |
Regular polygon (triangle, hexagon, etc.) |
Examples
Number Line
import { omdDisplay, omdNumberLine } from '@teachinglab/omd';
const line = new omdNumberLine();
line.loadFromJSON({
min: 0,
max: 20,
increment: 2,
dotValues: [6, 14],
title: 'Miles walked',
});
new omdDisplay(document.getElementById('line-container')).load(line);
Coordinate Plane
import { omdCoordinatePlane } from '@teachinglab/omd';
const plane = new omdCoordinatePlane();
plane.loadFromJSON({
xMin: -10, xMax: 10,
yMin: -10, yMax: 10,
graphEquations: [
{ equation: 'y = x^2 - 4', color: '#e11d48' },
{ equation: 'y = 2*x + 1', color: '#0f766e' },
],
dotValues: [[2, 0, '#e11d48']],
});
Balance Hanger
import { omdBalanceHanger } from '@teachinglab/omd';
const hanger = new omdBalanceHanger();
hanger.loadFromJSON({
leftValues: ['x', 'x', '3'],
rightValues: ['9'],
});
Rectangle with Labels
import { omdRectangle } from '@teachinglab/omd';
const rect = new omdRectangle();
rect.loadFromJSON({
width: 8,
height: 5,
unitScale: 40,
showLabels: true,
centerLabel: '40 sq ft',
});
Equation Work
import { omdEquationWork } from '@teachinglab/omd';
const work = new omdEquationWork();
work.loadFromJSON({
rows: [
{ kind: 'equation', left: '2x + 3', right: '11' },
{ kind: 'operation', left: '-3', right: '-3' },
{ kind: 'line' },
{ kind: 'equation', left: '2x', right: '8' },
{ kind: 'operation', left: '÷2', right: '÷2' },
{ kind: 'line' },
{ kind: 'equation', left: 'x', right: '4' },
],
});
Factory Function
All components can be created from a JSON object using createFromJSON. The JSON structure is flat — the same object you pass to the factory is what loadFromJSON expects on each class directly.
import { createFromJSON } from '@teachinglab/omd';
// All fields are at the top level alongside omdType
const visual = createFromJSON({
omdType: 'numberLine',
min: 0,
max: 10,
dotValues: [3, 7],
});
// This is equivalent to:
const line = new omdNumberLine();
line.loadFromJSON({ omdType: 'numberLine', min: 0, max: 10, dotValues: [3, 7] });
// Or render directly via omdDisplay.loadFromJSON — one line:
display.loadFromJSON({ omdType: 'numberLine', min: 0, max: 10, dotValues: [3, 7] });
Documentation
Dependencies
@teachinglab/jsvg— SVG renderingmathjs— Expression parsing