@molecule/app-charts
v1.0.1
Published
Chart interface and utilities for molecule.dev
Maintainers
Readme
@molecule/app-charts
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Chart interface for molecule.dev.
A framework-agnostic, imperative charting API: createChart(container,
config) plus shorthands (createLineChart, createBarChart,
createPieChart, createDoughnutChart, createAreaChart,
createScatterChart, createRadarChart), color utilities
(colorPalettes, getColor, generateColors), and a swappable
ChartProvider contract so any chart library (Chart.js, Recharts, D3,
uPlot, …) can back the same calls.
Quick Start
import { useEffect, useRef } from 'react'
import { createLineChart } from '@molecule/app-charts'
export function RevenueChart() {
const canvasRef = useRef<HTMLCanvasElement>(null)
useEffect(() => {
if (!canvasRef.current) return
const chart = createLineChart(canvasRef.current, {
labels: ['Jan', 'Feb', 'Mar', 'Apr'],
datasets: [{ label: 'Revenue', data: [4200, 5800, 5100, 7300] }],
})
return () => chart.destroy()
}, [])
return <canvas ref={canvasRef} width={600} height={300} />
}Type
feature
Installation
npm install @molecule/app-charts @molecule/app-bond @molecule/app-i18nAPI
Interfaces
AnimationConfig
Chart animation settings (duration, easing, delay, loop, disable).
interface AnimationConfig {
/**
* Animation duration (ms).
*/
duration?: number
/**
* Easing function.
*/
easing?:
| 'linear'
| 'easeInQuad'
| 'easeOutQuad'
| 'easeInOutQuad'
| 'easeInCubic'
| 'easeOutCubic'
| 'easeInOutCubic'
| 'easeInBounce'
| 'easeOutBounce'
| 'easeInOutBounce'
/**
* Delay before animation.
*/
delay?: number
/**
* Loop animation.
*/
loop?: boolean
/**
* Disable animations.
*/
disabled?: boolean
}AxisConfig
Chart axis settings (type, title, min/max, grid, ticks, stacking, time unit).
interface AxisConfig {
/**
* Axis type.
*/
type?: 'linear' | 'logarithmic' | 'category' | 'time' | 'timeseries'
/**
* Axis title.
*/
title?: {
display?: boolean
text?: string
color?: string
font?: FontConfig
}
/**
* Min value.
*/
min?: number
/**
* Max value.
*/
max?: number
/**
* Begin at zero.
*/
beginAtZero?: boolean
/**
* Display axis.
*/
display?: boolean
/**
* Grid configuration.
*/
grid?: {
display?: boolean
color?: string
lineWidth?: number
drawBorder?: boolean
}
/**
* Ticks configuration.
*/
ticks?: {
display?: boolean
color?: string
font?: FontConfig
stepSize?: number
maxTicksLimit?: number
callback?: (value: number | string) => string
}
/**
* Stacked axis.
*/
stacked?: boolean
/**
* Position.
*/
position?: 'top' | 'bottom' | 'left' | 'right'
/**
* Time unit (for time axes).
*/
time?: {
unit?:
'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
displayFormats?: Record<string, string>
tooltipFormat?: string
}
}ChartConfig
Full chart configuration (type, datasets, labels, axes, legend, tooltip, animation, responsive).
interface ChartConfig {
/**
* Chart type.
*/
type: ChartType
/**
* Datasets.
*/
datasets: Dataset[]
/**
* Labels (for category charts).
*/
labels?: (string | number)[]
/**
* Chart title.
*/
title?: {
display?: boolean
text?: string
color?: string
font?: FontConfig
padding?: number
position?: 'top' | 'bottom'
}
/**
* X-axis configuration.
*/
xAxis?: AxisConfig
/**
* Y-axis configuration.
*/
yAxis?: AxisConfig
/**
* Additional axes (for multi-axis charts).
*/
axes?: Record<string, AxisConfig>
/**
* Legend configuration.
*/
legend?: LegendConfig
/**
* Tooltip configuration.
*/
tooltip?: TooltipConfig
/**
* Animation configuration.
*/
animation?: AnimationConfig
/**
* Responsive.
*/
responsive?: boolean
/**
* Maintain aspect ratio.
*/
maintainAspectRatio?: boolean
/**
* Aspect ratio.
*/
aspectRatio?: number
/**
* Padding.
*/
padding?: number | { top?: number; right?: number; bottom?: number; left?: number }
/**
* Click handler.
*/
onClick?: (event: unknown, elements: unknown[], chart: unknown) => void
/**
* Hover handler.
*/
onHover?: (event: unknown, elements: unknown[], chart: unknown) => void
}ChartInstance
Live chart instance with update, resize, destroy, dataset manipulation, and image export.
interface ChartInstance {
/**
* Updates the chart with new data/config.
*/
update(config?: Partial<ChartConfig>): void
/**
* Resizes the chart.
*/
resize(): void
/**
* Destroys the chart.
*/
destroy(): void
/**
* Gets the chart as a base64 image.
*/
toBase64Image(type?: string, quality?: number): string
/**
* Gets the underlying chart instance.
*/
getInstance(): unknown
/**
* Shows a dataset.
*/
showDataset(index: number): void
/**
* Hides a dataset.
*/
hideDataset(index: number): void
/**
* Toggles a dataset.
*/
toggleDataset(index: number): void
/**
* Gets visible datasets.
*/
getVisibleDatasets(): number[]
/**
* Sets data for a dataset.
*/
setData(datasetIndex: number, data: (number | DataPoint)[]): void
/**
* Adds a dataset.
*/
addDataset(dataset: Dataset): void
/**
* Removes a dataset.
*/
removeDataset(index: number): void
/**
* Adds data point(s) to all datasets.
*/
addData(label: string | number, values: number[]): void
/**
* Removes data point(s) from all datasets.
*/
removeData(index?: number): void
}ChartProvider
Chart provider interface.
interface ChartProvider {
/**
* Creates a chart instance.
*/
createChart(container: HTMLCanvasElement | HTMLElement, config: ChartConfig): ChartInstance
/**
* Gets the provider name.
*/
getName(): string
/**
* Gets supported chart types.
*/
getSupportedTypes(): ChartType[]
/**
* Registers a plugin.
*/
registerPlugin?(plugin: unknown): void
/**
* Sets global defaults.
*/
setDefaults?(defaults: Partial<ChartConfig>): void
}DataPoint
Data point for a chart.
interface DataPoint {
/**
* X-axis value or label.
*/
x: string | number | Date
/**
* Y-axis value.
*/
y: number
/**
* Optional secondary value (for bubble charts, etc.).
*/
r?: number
/**
* Optional label override.
*/
label?: string
/**
* Optional color override.
*/
color?: string
/**
* Additional metadata.
*/
meta?: Record<string, unknown>
}Dataset
Dataset for a chart.
interface Dataset {
/**
* Dataset label.
*/
label: string
/**
* Data points.
*/
data: (number | DataPoint)[]
/**
* Background color(s).
*/
backgroundColor?: string | string[]
/**
* Border color(s).
*/
borderColor?: string | string[]
/**
* Border width.
*/
borderWidth?: number
/**
* Fill area under line.
*/
fill?: boolean | string
/**
* Line tension (0 = straight, 1 = curved).
*/
tension?: number
/**
* Point radius.
*/
pointRadius?: number
/**
* Point style.
*/
pointStyle?: 'circle' | 'cross' | 'rect' | 'triangle' | 'star'
/**
* Show/hide dataset.
*/
hidden?: boolean
/**
* Stack group (for stacked charts).
*/
stack?: string
/**
* Y-axis ID (for multi-axis charts).
*/
yAxisID?: string
/**
* X-axis ID (for multi-axis charts).
*/
xAxisID?: string
/**
* Order (z-index).
*/
order?: number
}FontConfig
Chart font settings (family, size, weight, style).
interface FontConfig {
family?: string
size?: number
weight?: 'normal' | 'bold' | number
style?: 'normal' | 'italic'
}LegendConfig
Chart legend settings (display, position, alignment, label styling, click handler).
interface LegendConfig {
/**
* Display legend.
*/
display?: boolean
/**
* Position.
*/
position?: 'top' | 'bottom' | 'left' | 'right' | 'chartArea'
/**
* Align.
*/
align?: 'start' | 'center' | 'end'
/**
* Labels configuration.
*/
labels?: {
color?: string
font?: FontConfig
padding?: number
usePointStyle?: boolean
boxWidth?: number
boxHeight?: number
}
/**
* Click handler.
*/
onClick?: (event: unknown, legendItem: unknown, legend: unknown) => void
}TooltipConfig
Chart tooltip settings (mode, position, colors, border, padding, custom callbacks).
interface TooltipConfig {
/**
* Enable tooltips.
*/
enabled?: boolean
/**
* Tooltip mode.
*/
mode?: 'point' | 'nearest' | 'index' | 'dataset' | 'x' | 'y'
/**
* Intersect.
*/
intersect?: boolean
/**
* Position.
*/
position?: 'average' | 'nearest'
/**
* Background color.
*/
backgroundColor?: string
/**
* Title color.
*/
titleColor?: string
/**
* Body color.
*/
bodyColor?: string
/**
* Border color.
*/
borderColor?: string
/**
* Border width.
*/
borderWidth?: number
/**
* Padding.
*/
padding?: number
/**
* Custom callbacks.
*/
callbacks?: {
title?: (context: unknown) => string | string[]
label?: (context: unknown) => string | string[]
footer?: (context: unknown) => string | string[]
}
}Types
ChartType
Available chart visualization types (line, bar, pie, doughnut, area, scatter, radar, polar).
type ChartType =
| 'line'
| 'bar'
| 'pie'
| 'doughnut'
| 'area'
| 'scatter'
| 'bubble'
| 'radar'
| 'polar'
| 'heatmap'
| 'treemap'
| 'funnel'
| 'gauge'
| 'candlestick'Functions
createAreaChart(container, config)
Creates an area chart (shorthand that sets type to 'area').
function createAreaChart(
container: HTMLCanvasElement | HTMLElement,
config: Omit<ChartConfig, 'type'>,
): ChartInstancecontainer— The DOM element to render the chart into.config— The chart configuration (type is set automatically).
Returns: The created area chart instance.
createBarChart(container, config)
Creates a bar chart (shorthand that sets type to 'bar').
function createBarChart(
container: HTMLCanvasElement | HTMLElement,
config: Omit<ChartConfig, 'type'>,
): ChartInstancecontainer— The DOM element to render the chart into.config— The chart configuration (type is set automatically).
Returns: The created bar chart instance.
createChart(container, config)
Creates a chart using the active provider.
function createChart(container: HTMLCanvasElement | HTMLElement, config: ChartConfig): ChartInstancecontainer— The DOM element to render the chart into.config— The chart configuration including type, data, and options.
Returns: The created chart instance with update and destroy methods.
createDoughnutChart(container, config)
Creates a doughnut chart (shorthand that sets type to 'doughnut').
function createDoughnutChart(
container: HTMLCanvasElement | HTMLElement,
config: Omit<ChartConfig, 'type'>,
): ChartInstancecontainer— The DOM element to render the chart into.config— The chart configuration (type is set automatically).
Returns: The created doughnut chart instance.
createLineChart(container, config)
Creates a line chart (shorthand that sets type to 'line').
function createLineChart(
container: HTMLCanvasElement | HTMLElement,
config: Omit<ChartConfig, 'type'>,
): ChartInstancecontainer— The DOM element to render the chart into.config— The chart configuration (type is set automatically).
Returns: The created line chart instance.
createPieChart(container, config)
Creates a pie chart (shorthand that sets type to 'pie').
function createPieChart(
container: HTMLCanvasElement | HTMLElement,
config: Omit<ChartConfig, 'type'>,
): ChartInstancecontainer— The DOM element to render the chart into.config— The chart configuration (type is set automatically).
Returns: The created pie chart instance.
createRadarChart(container, config)
Creates a radar chart (shorthand that sets type to 'radar').
function createRadarChart(
container: HTMLCanvasElement | HTMLElement,
config: Omit<ChartConfig, 'type'>,
): ChartInstancecontainer— The DOM element to render the chart into.config— The chart configuration (type is set automatically).
Returns: The created radar chart instance.
createScatterChart(container, config)
Creates a scatter chart (shorthand that sets type to 'scatter').
function createScatterChart(
container: HTMLCanvasElement | HTMLElement,
config: Omit<ChartConfig, 'type'>,
): ChartInstancecontainer— The DOM element to render the chart into.config— The chart configuration (type is set automatically).
Returns: The created scatter chart instance.
createSimpleChartProvider(options)
Creates the built-in placeholder chart provider. It does NOT draw real
charts: every createChart paints a "placeholder — no chart provider bonded"
notice onto the canvas and logs a one-time, actionable console.warn, rather
than silently pretending to render. No real chart provider ships with the
fleet — to draw actual charts, implement the {@link ChartProvider} interface
around a real library (Chart.js / Recharts / D3) and wire it with
bond('charts', provider) (or setProvider(provider)) at startup, before any
create*Chart call.
function createSimpleChartProvider(options?: SimpleChartProviderOptions): ChartProvideroptions— Optional overrides for the placeholder label/description text.
Returns: A placeholder chart provider — renders a non-functional notice, not a chart.
generateColors(count, palette)
Generates colors for a dataset.
function generateColors(
count: number,
palette?: 'default' | 'pastel' | 'vivid' | 'cool' | 'warm' | 'monochrome',
): string[]count— The number of colors to generate.palette— The named color palette to draw from.
Returns: An array of hex color strings cycling through the palette.
getColor(index, palette)
Gets a color from a palette.
function getColor(
index: number,
palette?: 'default' | 'pastel' | 'vivid' | 'cool' | 'warm' | 'monochrome',
): stringindex— The color index (wraps around if it exceeds palette length).palette— The named color palette to pick from.
Returns: The hex color string at the given index.
getProvider()
Gets the current chart provider. Falls back to the built-in placeholder
provider if none has been bonded — that fallback does not draw real charts and
warns once when it first renders (see {@link createSimpleChartProvider}). Bond
a real ChartProvider before any create*Chart call to draw actual charts.
function getProvider(): ChartProviderReturns: The active chart provider instance.
hasProvider()
Checks if a chart provider has been bonded.
function hasProvider(): booleanReturns: Whether a chart provider is currently registered.
setProvider(provider)
Sets the chart provider.
function setProvider(provider: ChartProvider): voidprovider— The chart provider implementation to bond.
Constants
colorPalettes
Color palette presets.
const colorPalettes: {
default: string[]
pastel: string[]
vivid: string[]
cool: string[]
warm: string[]
monochrome: string[]
}provider
Default chart provider — the built-in placeholder provider. It does NOT
draw real charts: it paints a "no chart provider bonded" notice and warns
once (see {@link createSimpleChartProvider}). Exported only so apps can name
it explicitly; it is NOT a shippable renderer. To draw real charts, implement
the ChartProvider interface around a real library (Chart.js / Recharts / D3)
and bond that instead with bond('charts', provider) (equivalent to
setProvider), matching the convention of other bondable feature packages
(e.g. @molecule/app-data-table-*).
const provider: ChartProviderInjection Notes
Requirements
Peer dependencies:
@molecule/app-bond^1.0.1@molecule/app-i18n1.0.1
Runtime Dependencies
@molecule/app-bond@molecule/app-i18n
The built-in default provider does NOT draw real charts. If no provider
is bonded, every create*Chart call paints a non-functional placeholder
notice onto the canvas (e.g. "bar chart — placeholder" / "No chart provider
bonded") and logs a one-time, actionable console.warn — it never silently
pretends to render. For real charts, bond @molecule/app-charts-chartjs
(Chart.js — line/bar/pie/doughnut/area/scatter/bubble/radar/polar) at startup:
import { provider } from '@molecule/app-charts-chartjs' then
setProvider(provider) (same as bond('charts', provider)) in bonds.ts,
BEFORE any component calls createChart. All create*Chart calls then route
through it unchanged. (To use a different library, implement the
ChartProvider interface around it — but the Chart.js bond covers the common
cases.) Do not import a chart library directly in screens/components — keep it
behind the provider so it stays swappable.
E2E Tests
Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:
- [ ] Every chart on the app's screens renders with real data — no blank canvas, no NaN/undefined axis labels.
- [ ] Plotted values match the data: spot-check at least one point/bar/slice against a number you can verify elsewhere in the UI.
- [ ] Charts update when their inputs change (date range, filter, or a newly created record that should appear).
- [ ] An empty dataset renders an empty state or zeroed axes — not a crash or a stale chart from previous data.
- [ ] Tooltips and legends (where enabled) show the correct labels and values on hover.
- [ ] Resizing the window/panel keeps charts legible (no overflow, no zero-height canvas).
Translations
Translation strings are provided by @molecule/app-locales-charts.
