motionchart
v0.1.0-beta.0
Published
Cinematic React chart library with beautiful animations and storytelling-first charts
Maintainers
Readme
motionchart
Cinematic React chart library with beautiful animations and storytelling-first data visualization. Built with SVG and Motion — zero canvas, zero D3.
Install
npm install motionchart motion react react-domComponents
MotionBar
Bar chart with single or grouped multi-series support.
import { MotionBar } from "motionchart";
// Single series
<MotionBar
data={[
{ label: "Jan", value: 40 },
{ label: "Feb", value: 70 },
{ label: "Mar", value: 55 },
]}
theme="midnight"
width={600}
height={400}
animation={{ type: "spring", stiffness: 120, damping: 14, staggerDelay: 0.05 }}
showValues
/>
// Grouped series
<MotionBar
series={[
{ label: "Revenue", color: "#4285f4", data: [74, 83, 99] },
{ label: "Profit", color: "#34a853", data: [42, 53, 55] },
]}
labels={["Q1", "Q2", "Q3"]}
theme="midnight"
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | BarDataPoint[] | — | Single series data |
| series | BarSeries[] | — | Multi-series grouped data |
| labels | string[] | — | X-axis labels for grouped mode |
| borderRadius | number | 4 | Bar corner radius |
| barPadding | number | 0.3 | Spacing between bars (0-1) |
| groupPadding | number | 0.1 | Spacing within groups (0-1) |
| showValues | boolean | false | Show value labels above bars |
| showLabels | boolean | true | Show x-axis labels |
| legend | boolean \| LegendConfig | — | Legend configuration |
MotionLine
Line chart with smooth/linear/step curves, area fills, and multi-series support.
import { MotionLine } from "motionchart";
<MotionLine
data={{
label: "Growth",
data: [
{ x: "Jan", y: 20 },
{ x: "Feb", y: 45 },
{ x: "Mar", y: 35 },
],
}}
theme="ocean"
curve="smooth"
showArea
showDots
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | LineSeries \| LineSeries[] | — | Line series data |
| curve | "smooth" \| "linear" \| "step" | "smooth" | Curve interpolation |
| drawSpeed | number | 1.8 | Line draw animation duration (s) |
| showDots | boolean | true | Show data point dots |
| dotRadius | number | 5 | Dot size |
| showArea | boolean | false | Fill area under the line |
MotionPie
Pie and donut charts with gradient support.
import { MotionPie } from "motionchart";
<MotionPie
data={[
{ label: "React", value: 45 },
{ label: "Vue", value: 25 },
{ label: "Svelte", value: 18 },
]}
theme="sunset"
innerRadius={0.55}
legend={{ position: "bottom" }}
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | PieDataPoint[] | — | Slice data |
| innerRadius | number | 0 | Donut hole ratio (0-1) |
| cornerRadius | number | 0 | Rounded slice edges |
| padAngle | number | 0 | Gap between slices (degrees) |
| showLabels | boolean | false | Show percentage labels |
| showValues | boolean | false | Show raw value labels |
| legend | boolean \| LegendConfig | — | Legend configuration |
MotionRadar
Radar/spider chart for multi-dimensional comparison.
import { MotionRadar } from "motionchart";
<MotionRadar
axes={[
{ label: "Speed" },
{ label: "Shooting" },
{ label: "Passing" },
{ label: "Defense" },
]}
series={[
{ label: "Player A", data: [88, 92, 78, 60] },
{ label: "Player B", data: [70, 65, 90, 88] },
]}
theme="midnight"
shape="polygon"
legend={{ position: "bottom" }}
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| axes | RadarDataPoint[] | — | Axis definitions |
| series | RadarSeries[] | — | Data series |
| levels | number | 5 | Concentric grid rings |
| shape | "polygon" \| "circle" | "polygon" | Grid shape |
| fillOpacity | number | 0.25 | Area fill opacity |
| showDots | boolean | true | Show data point dots |
MotionScatter
Scatter plot with optional bubble mode (size dimension).
import { MotionScatter } from "motionchart";
<MotionScatter
data={{
label: "Cities",
data: [
{ x: 40, y: 85, size: 12, label: "Tokyo" },
{ x: 80, y: 60, size: 15, label: "New York" },
],
}}
theme="ocean"
xAxisLabel="GDP Index"
yAxisLabel="Quality of Life"
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | ScatterSeries \| ScatterSeries[] | — | Scatter data |
| dotRadius | number | 5 | Default dot size |
| dotOpacity | number | 0.7 | Dot fill opacity |
| minDotRadius | number | 3 | Min size for bubble mode |
| maxDotRadius | number | 20 | Max size for bubble mode |
MotionCandlestick
Financial OHLC candlestick chart with optional volume overlay.
import { MotionCandlestick } from "motionchart";
<MotionCandlestick
data={[
{ label: "Mon", open: 150, high: 158, low: 147, close: 155, volume: 42000 },
{ label: "Tue", open: 155, high: 162, low: 153, close: 160, volume: 38000 },
]}
theme="midnight"
showVolume
yAxisLabel="Price ($)"
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | CandlestickDataPoint[] | — | OHLC data |
| bullishColor | string | theme color | Close > Open color |
| bearishColor | string | theme color | Close < Open color |
| candleWidth | number | 0.6 | Body width fraction (0-1) |
| showVolume | boolean | false | Show volume bars |
MotionGantt
Gantt chart for project timelines with dependencies.
import { MotionGantt } from "motionchart";
<MotionGantt
tasks={[
{ id: "design", label: "UI Design", start: 0, end: 4, progress: 1, group: "Design" },
{ id: "dev", label: "Development", start: 4, end: 10, progress: 0.4, group: "Eng", dependencies: ["design"] },
]}
theme="midnight"
showProgress
showDependencies
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| tasks | GanttTask[] | — | Task data |
| barHeight | number | 24 | Task bar height |
| rowGap | number | 8 | Gap between rows |
| showProgress | boolean | true | Show progress fill |
| showDependencies | boolean | true | Draw dependency arrows |
| showPercentage | boolean | false | Show % text on bars |
MotionTree
Classic node-and-branch tree diagram for hierarchical data.
import { MotionTree } from "motionchart";
<MotionTree
data={{
label: "CEO",
children: [
{
label: "CTO",
children: [{ label: "Frontend" }, { label: "Backend" }],
},
{ label: "CFO" },
],
}}
theme="midnight"
direction="top-down"
nodeRadius={6}
branchWidth={2}
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | TreeNode | — | Hierarchical tree data |
| direction | "top-down" \| "bottom-up" \| "left-right" \| "right-left" | "top-down" | Layout direction |
| nodeRadius | number | 6 | Node circle radius |
| levelSpacing | number | 80 | Distance between levels |
| siblingSpacing | number | 40 | Minimum sibling gap |
| branchWidth | number | 2 | Branch stroke width |
| branchColor | string | theme grid color | Branch color override |
| showLabels | boolean | true | Show node labels |
| showValues | boolean | false | Show node values |
MotionTreemap
Squarified treemap — nested rectangles where area represents value.
import { MotionTreemap } from "motionchart";
<MotionTreemap
data={{
label: "Portfolio",
children: [
{
label: "Tech",
children: [
{ label: "Apple", value: 180 },
{ label: "Google", value: 140 },
],
},
{
label: "Finance",
children: [
{ label: "JPMorgan", value: 120 },
{ label: "Visa", value: 70 },
],
},
],
}}
theme="sunset"
showLabels
showValues
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | TreeNode | — | Hierarchical data (leaf value = area) |
| tilePadding | number | 4 | Padding between nested tiles |
| borderRadius | number | 4 | Tile corner radius |
| minLabelSize | number | 30 | Min tile dimension to show label |
| showLabels | boolean | true | Show labels on tiles |
| showValues | boolean | false | Show values on tiles |
MotionRadialTree
Circular tree layout with nodes fanning outward from center.
import { MotionRadialTree } from "motionchart";
<MotionRadialTree
data={{
label: "Root",
children: [
{ label: "A", children: [{ label: "A1" }, { label: "A2" }] },
{ label: "B", children: [{ label: "B1" }, { label: "B2" }, { label: "B3" }] },
],
}}
theme="ocean"
angularSpread={360}
nodeRadius={5}
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | TreeNode | — | Hierarchical tree data |
| nodeRadius | number | 5 | Node circle radius |
| angularSpread | number | 360 | Angular range in degrees |
| startAngle | number | 0 | Starting angle in degrees |
| levelSpacing | number | auto | Radial distance between levels |
| branchWidth | number | 1.5 | Branch stroke width |
| showLabels | boolean | true | Show node labels |
MotionDendrogram
Clustering dendrogram with elbow connectors and distance scale.
import { MotionDendrogram } from "motionchart";
<MotionDendrogram
data={{
label: "Animals",
value: 0,
children: [
{
label: "Mammals",
value: 1,
children: [
{ label: "Dog", value: 3 },
{ label: "Cat", value: 3 },
],
},
{
label: "Birds",
value: 1,
children: [
{ label: "Eagle", value: 2 },
{ label: "Parrot", value: 2 },
],
},
],
}}
theme="midnight"
direction="left-right"
elbowConnectors
showScale
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | TreeNode | — | Hierarchical data (value = branch distance) |
| direction | "top-down" \| "left-right" | "left-right" | Layout direction |
| nodeRadius | number | 5 | Node circle radius |
| branchWidth | number | 1.5 | Branch stroke width |
| elbowConnectors | boolean | true | Use right-angle connectors |
| showLabels | boolean | true | Show leaf node labels |
| showScale | boolean | true | Show distance axis |
MotionHeatmap
Colored grid chart for correlations, activity patterns, and matrix data.
import { MotionHeatmap } from "motionchart";
<MotionHeatmap
data={[
{ row: "Mon", col: "9am", value: 5 },
{ row: "Mon", col: "12pm", value: 12 },
{ row: "Tue", col: "9am", value: 8 },
{ row: "Tue", col: "12pm", value: 15 },
]}
theme="midnight"
colorRange={["#1e3a5f", "#06b6d4"]}
showValues
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | HeatmapDataPoint[] | — | Grid data (row, col, value) |
| cellRadius | number | 2 | Cell corner radius |
| cellGap | number | 2 | Gap between cells |
| showValues | boolean | false | Show values inside cells |
| colorRange | [string, string] | theme colors | Low-to-high color interpolation |
| showXLabels | boolean | true | Show column labels |
| showYLabels | boolean | true | Show row labels |
MotionFunnel
Funnel/pipeline chart for conversion flows and stage analysis.
import { MotionFunnel } from "motionchart";
<MotionFunnel
data={[
{ label: "Visitors", value: 12000 },
{ label: "Sign Ups", value: 7500 },
{ label: "Trial", value: 4200 },
{ label: "Paid", value: 1800 },
]}
theme="sunset"
showPercentage
showValues
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | FunnelStage[] | — | Stage data |
| showLabels | boolean | true | Show stage labels |
| showValues | boolean | true | Show stage values |
| showPercentage | boolean | true | Show conversion % from first stage |
| gapBetweenStages | number | 4 | Gap between stages |
| borderRadius | number | 4 | Bar corner radius |
| legend | boolean \| LegendConfig | — | Legend configuration |
MotionSunburst
Hierarchical radial chart — concentric rings where arc angle represents value.
import { MotionSunburst } from "motionchart";
<MotionSunburst
data={{
label: "World",
children: [
{
label: "Americas",
children: [
{ label: "USA", value: 330 },
{ label: "Brazil", value: 210 },
],
},
{
label: "Europe",
children: [
{ label: "Germany", value: 83 },
{ label: "France", value: 67 },
],
},
],
}}
theme="ocean"
showLabels
legend={{ position: "bottom" }}
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | TreeNode | — | Hierarchical data (leaf value = arc angle) |
| innerRadius | number | 0 | Inner hole ratio (0-1) |
| padAngle | number | 0.5 | Gap between arcs (degrees) |
| showLabels | boolean | false | Show labels on arcs |
| legend | boolean \| LegendConfig | — | Legend configuration |
Shared Props
All components accept these base props:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| width | number | 600 | Chart width in pixels |
| height | number | 400 | Chart height in pixels |
| theme | "midnight" \| "sunset" \| "ocean" \| Theme | "midnight" | Built-in or custom theme |
| colors | string[] | theme colors | Override element colors by index |
| gradient | GradientConfig | — | Global gradient for all elements |
| animation | AnimationConfig | spring default | Animation settings |
| hover | HoverConfig | enabled | Hover effect settings |
| tooltip | TooltipConfig | enabled | Tooltip settings |
| showGrid | boolean | true | Show grid lines |
| ariaLabel | string | — | Accessible label |
| className | string | — | CSS class name |
| backgroundColor | string | — | Override theme background |
| textColor | string | — | Override theme text color |
| gridColor | string | — | Override theme grid color |
Animation
// Spring (default)
animation={{ type: "spring", stiffness: 120, damping: 14, staggerDelay: 0.05 }}
// Tween
animation={{ type: "tween", duration: 0.6, ease: "easeInOut", staggerDelay: 0.03 }}
// Disabled
animation={{ disabled: true }}Themes
Three built-in dark themes: "midnight", "sunset", "ocean".
// Built-in
<MotionBar data={data} theme="sunset" />
// Custom
<MotionBar
data={data}
theme={{
name: "custom",
background: "#1a1a2e",
gridColor: "rgba(255,255,255,0.1)",
textColor: "rgba(255,255,255,0.8)",
colors: ["#e94560", "#0f3460", "#533483", "#16213e"],
gradients: [],
tooltipBackground: "rgba(0,0,0,0.85)",
tooltipText: "#fff",
tooltipBorder: "rgba(255,255,255,0.15)",
glowColor: "rgba(233,69,96,0.3)",
}}
/>
// Quick overrides
<MotionBar data={data} backgroundColor="#000" textColor="#fff" />Custom Tooltips
<MotionBar
data={data}
tooltip={{
enabled: true,
render: ({ label, value, color }) => (
<div style={{ color: "#fff" }}>
<strong style={{ color }}>{label}</strong>: {value}
</div>
),
}}
/>Data Types
TreeNode (shared by all tree components)
interface TreeNode {
label: string;
value?: number; // area in treemap, distance in dendrogram
color?: string; // per-node color override
gradient?: GradientConfig;
children?: TreeNode[];
}GradientConfig
interface GradientConfig {
from: string; // start color
to: string; // end color
angle?: number; // rotation in degrees
}Peer Dependencies
react>= 18.0.0react-dom>= 18.0.0motion>= 11.0.0
License
MIT
