Skip to content
Domphy

Series Reference

Line

{
  type: "line",
  name?: string,
  data: number[] | [number, number][],
  smooth?: boolean,                  // bezier smoothing
  step?: "start" | "end" | "middle", // step line
  connectNulls?: boolean,
  stack?: string,                    // stack group name
  symbol?: "circle" | "rect" | "diamond" | "triangle" | "none",
  symbolSize?: number | [number, number],
  lineStyle?: { color?: ThemeFamily, width?: number, type?: "solid" | "dashed" | "dotted" },
  areaStyle?: {
    color?: ThemeFamily | GradientObject,
    opacity?: number,                // default 0.2
    origin?: "auto" | "start" | "end" | number,
  },
  label?: LabelOption,
  color?: ThemeFamily,
}

Gradient area fill:

{
  type: "line",
  data: [820, 932, 901, 934, 1290],
  areaStyle: {
    color: {
      type: "linear", x: 0, y: 0, x2: 0, y2: 1,
      colorStops: [
        { offset: 0, color: "rgba(58,77,233,0.8)" },
        { offset: 1, color: "rgba(58,77,233,0.05)" },
      ],
    },
  },
}

Bar

{
  type: "bar",
  name?: string,
  data: number[],
  stack?: string,
  barWidth?: number | string,        // px or "%"
  barMaxWidth?: number | string,
  barGap?: string,                   // gap between bars in same category (default "30%")
  barCategoryGap?: string,           // gap between category groups (default "20%")
  label?: LabelOption,
  itemStyle?: ItemStyleOption,
  color?: ThemeFamily,
}

Grouped bars — two series on same axis:

series: [
  { type: "bar", name: "2023", data: [120, 200, 150] },
  { type: "bar", name: "2024", data: [150, 230, 180] },
]

Stacked bars:

series: [
  { type: "bar", name: "A", stack: "total", data: [120, 200] },
  { type: "bar", name: "B", stack: "total", data: [80, 100] },
]

Horizontal bar

Swap axis types to orient bars horizontally:

xAxis: { type: "value" },
yAxis: { type: "category", data: ["Mon", "Tue", "Wed"] },
series: [{ type: "bar", data: [120, 200, 150] }]

All bar options (stack, grouped, itemStyle, label) work the same way.


Scatter

{
  type: "scatter",
  name?: string,
  data: [number, number][] | [number, number, number][],  // [x, y] or [x, y, size]
  symbolSize?: number | ((val: number[]) => number),
  label?: LabelOption,
  color?: ThemeFamily,
}

Variable bubble size:

{
  type: "scatter",
  symbolSize: (val) => Math.sqrt(val[2]) * 4,
  data: [[10, 8.04, 40], [8, 6.95, 20], [13, 7.58, 15]],
}

Pie

{
  type: "pie",
  name?: string,
  data: PieDataItem[],              // { value: number, name: string }[]
  radius?: number | string | [string | number, string | number],  // "60%" or ["35%", "60%"] for donut
  center?: [string | number, string | number],                    // ["50%", "50%"]
  roseType?: "radius" | "area",
  label?: LabelOption,
  labelLine?: LabelLineOption,
}

Donut:

{ type: "pie", radius: ["35%", "60%"], data: [...] }

Radar

{
  type: "radar",
  name?: string,
  data: Array<{ value: number[], name: string }>,
  areaStyle?: { opacity?: number },
  lineStyle?: LineStyleOption,
}

Requires a radar component in the option:

radar: {
  indicator: [
    { name: "Sales", max: 6500 },
    { name: "Admin", max: 16000 },
    { name: "IT", max: 30000 },
  ],
  shape?: "polygon" | "circle",
  splitNumber?: number,
  startAngle?: number,
}

Heatmap

{
  type: "heatmap",
  name?: string,
  data: [number, number, number][],  // [xIndex, yIndex, value]
}

Requires xAxis/yAxis category axes and a visualMap component.


Candlestick

{
  type: "candlestick",
  name?: string,
  data: [number, number, number, number][],  // [open, close, low, high]
  itemStyle?: {
    color?: string,                  // bullish candle color (close > open)
    color0?: string,                 // bearish candle color
    borderColor?: string,
    borderColor0?: string,
  },
}

Gauge

{
  type: "gauge",
  name?: string,
  data: Array<{ value: number, name: string }>,
  min?: number,
  max?: number,
  startAngle?: number,
  endAngle?: number,
  splitNumber?: number,
  detail?: { formatter?: string },   // "{value}%" etc.
  progress?: { show?: boolean },
}

Boxplot

{
  type: "boxplot",
  name?: string,
  data: [number, number, number, number, number][],  // [min, Q1, median, Q3, max]
}

Renders whisker box diagrams via SVG.


Funnel

{
  type: "funnel",
  name?: string,
  data: FunnelDataItem[],            // { value: number, name: string }[]
  left?: number | string,
  top?: number | string,
  width?: number | string,
  height?: number | string,
  label?: LabelOption,
}

Data is sorted descending by value automatically.


Treemap

{
  type: "treemap",
  name?: string,
  data: TreemapDataItem[],           // { name, value, children? }[]
  top?: number | string,
  left?: number | string,
  width?: number | string,
  height?: number | string,
}

Squarified layout. Nested children arrays are supported.


Sankey

{
  type: "sankey",
  nodes: SankeyNode[],               // { name: string }[]
  links: SankeyLink[],               // { source: string, target: string, value: number }[]
  left?: number | string,
  top?: number | string,
  width?: number | string,
  height?: number | string,
  nodeWidth?: number,
  nodeGap?: number,
  layoutIterations?: number,         // relaxation iterations (default 32)
}

Layout uses BFS depth assignment + iterative relaxation. Links are bezier curves.


Graph

{
  type: "graph",
  nodes: GraphNode[],
  links: GraphLink[],
  categories?: GraphCategory[],
  layout?: "force" | "circular" | "none",
  symbolSize?: number,
  edgeSymbol?: [string, string],     // e.g. ["none", "arrow"]
  edgeSymbolSize?: [number, number],
  label?: { show?: boolean },
  force?: {
    repulsion?: number,
    gravity?: number,
    edgeLength?: number,
    layoutAnimation?: boolean,
  },
}

interface GraphNode {
  id?: string,
  name?: string,
  x?: number,
  y?: number,
  symbolSize?: number,
  category?: number,                 // index into categories[]
}

interface GraphLink {
  source: string,                    // node id or name
  target: string,
}

interface GraphCategory {
  name?: string,
}

Force layout uses Fruchterman-Reingold (150 iterations, repulsion + spring + gravity).


Labels

interface LabelOption {
  show?: boolean,
  position?: "top" | "bottom" | "inside" | "left" | "right",
  formatter?: string | ((params: LabelParams) => string),
  fontSize?: number,
  color?: string,
  fontWeight?: string | number,
}

Labels are supported on: bar, line, scatter, pie (with leader lines and percentage).


Calendar (coordinate system)

Requires calendar in the option. Use with heatmap (set coordinateSystem: "calendar").

{
  calendar: {
    range: "2024",                        // full year, or ["2024-01-01", "2024-06-30"]
    cellSize?: number | [w, h],           // default 20; "auto" per dimension fills the rect
    dayLabel?: { firstDay?: 0|1, show?: boolean },
    monthLabel?: { show?: boolean },
    yearLabel?: { show?: boolean },
  },
  series: [{
    type: "heatmap",
    coordinateSystem: "calendar",
    data: [
      ["2024-01-15", 42],
      ["2024-03-22", 87],
      // ...
    ],
  }],
  visualMap: { type: "continuous", min: 0, max: 100 },
}

Parallel Coordinates

{
  parallel: { left: "10%", right: "5%", top: "10%", bottom: "10%" },
  parallelAxis: [
    { dim: 0, name: "Income",    type: "value" },
    { dim: 1, name: "Age",       type: "value" },
    { dim: 2, name: "Education", type: "category", data: ["High School","BSc","MSc","PhD"] },
  ],
  series: [{
    type: "parallel",
    data: [
      [45000, 32, "BSc"],
      [72000, 45, "MSc"],
      [28000, 24, "High School"],
    ],
    lineStyle: { opacity: 0.5 },
  }],
}

Each row becomes a polyline crossing each axis at its value position.


ThemeRiver

Stream/river chart showing changes in topic proportions over time.

{
  series: [{
    type: "themeRiver",
    data: [
      // [time, value, topic-name]
      ["2024-01", 20, "Topic A"],
      ["2024-02", 35, "Topic A"],
      ["2024-01", 15, "Topic B"],
      ["2024-02", 25, "Topic B"],
    ],
  }],
}

Multiple series names in the same dataset are stacked as separate streams. The baseline is silhouette-centered (zero-centered sum), giving the characteristic river shape.


Map (choropleth)

Requires calling registerMap before use.

import { registerMap } from "@domphy/chart"

// Register a GeoJSON (e.g. world countries from naturalearth)
registerMap("world", worldGeoJSON)

// Option:
{
  geo: {
    map: "world",
    roam: true,   // enable pan/zoom (not yet interactive — reserved for future)
    zoom: 1.2,
    center: [0, 20],
  },
  series: [{
    type: "map",
    map: "world",
    data: [
      { name: "China",         value: 89 },
      { name: "United States", value: 73 },
      { name: "Germany",       value: 61 },
    ],
  }],
  visualMap: { type: "continuous", min: 0, max: 100 },
}

scatter series with coordinateSystem: "geo" render as circles at [lng, lat] coordinates.


scatter3D / bar3D / line3D / surface3D

All 3D series require grid3D. Projection is perspective SVG (no WebGL needed).

{
  grid3D: {
    viewControl: { alpha: 35, beta: 45, distance: 180 },
  },
  xAxis3D: { name: "X", type: "value" },
  yAxis3D: { name: "Y", type: "value" },
  zAxis3D: { name: "Z", type: "value" },
  series: [
    {
      type: "scatter3D",
      symbolSize: 10,
      color: "primary",
      data: [[1,2,3], [4,5,6], [7,8,9]],
    },
    {
      type: "line3D",
      lineWidth: 2,
      color: "secondary",
      data: [[0,0,0], [1,2,4], [2,4,8]],
    },
    {
      type: "bar3D",
      barSize: 0.05,
      color: "success",
      data: [[0,1,5], [1,1,8], [2,1,3]],
    },
  ],
}

surface3D

Renders a 3D surface from a structured grid of [x, y, z] points. Z-value is mapped to a blue→green→red color gradient.

{
  grid3D: { viewControl: { alpha: 30, beta: 50 } },
  xAxis3D: { type: "value" },
  yAxis3D: { type: "value" },
  zAxis3D: { type: "value" },
  series: [{
    type: "surface3D",
    shapeW: 20,   // grid columns
    shapeH: 20,   // grid rows
    wireframe: { show: true },
    data: (() => {
      const points = []
      for (let i = 0; i < 20; i++) {
        for (let j = 0; j < 20; j++) {
          const x = (i / 19) * 4 - 2
          const y = (j / 19) * 4 - 2
          const z = Math.sin(Math.sqrt(x * x + y * y))
          points.push([x, y, z])
        }
      }
      return points
    })(),
  }],
}

Lines (flow map)

Draws curved arcs between coordinate pairs on a geo map. Useful for migration flows, flight routes, or any directed relationship between locations.

Requires geo in the option and a registered map (see Map / choropleth).

import { registerMap } from "@domphy/chart"

registerMap("world", worldGeoJSON)

{
  geo: { map: "world" },
  series: [{
    type: "lines",
    coordinateSystem: "geo",
    data: [
      { coords: [[-87.6, 41.8], [-118.2, 34.0]], name: "Chicago → LA" },
      { coords: [[-74.0, 40.7], [-122.4, 37.8]], name: "NYC → SF" },
    ],
    lineStyle: { width: 1.5, opacity: 0.7 },
    // Animated dot moving along each line:
    effect: {
      show: true,
      period: 3,      // seconds per traversal
      symbolSize: 6,
    },
    color: "primary",
  }],
}

Without effect.show, lines render as static bezier curves. With it, a dot animates along each arc using SVG animateMotion.


EffectScatter

Scatter chart where each point has a ripple pulse animation. Good for highlighting locations on a geo map or drawing attention to specific data points.

// On a geo map:
{
  geo: { map: "world" },
  series: [{
    type: "effectScatter",
    coordinateSystem: "geo",
    data: [
      [116.4, 39.9],   // [lng, lat] — Beijing
      [-74.0, 40.7],   // New York
      [2.3, 48.9],     // Paris
    ],
    symbolSize: 12,
    rippleEffect: {
      period: 2,       // seconds per ripple cycle
      scale: 4,        // ripple expands to 4× symbol size
      brushType: "fill",
    },
    color: "primary",
  }],
}

// On cartesian axes:
{
  xAxis: { type: "value" },
  yAxis: { type: "value" },
  series: [{
    type: "effectScatter",
    data: [[10, 80], [20, 60], [30, 90]],
    symbolSize: (val) => val[1] / 5,
    rippleEffect: { scale: 3 },
  }],
}

PictorialBar

Bar chart where each bar is replaced by a repeating or scaled SVG symbol.

{
  xAxis: { type: "category", data: ["Mon", "Tue", "Wed", "Thu"] },
  yAxis: { type: "value" },
  series: [{
    type: "pictorialBar",
    symbol: "circle",      // "circle" | "rect" | "triangle" | "diamond" | "arrow" | "pin" | "path://..."
    symbolSize: [18, 18],  // [width, height]
    symbolRepeat: true,    // stack symbols to fill bar height
    symbolClip: true,      // clip last symbol to exact value
    data: [4, 7, 3, 9],
    color: "primary",
  }],
}

Custom SVG path:

{
  type: "pictorialBar",
  symbol: "path://M0,-10 L3,-3 L10,-3 L4,2 L6,10 L0,5 L-6,10 L-4,2 L-10,-3 L-3,-3 Z",  // star
  symbolSize: [20, 20],
  symbolRepeat: 5,    // show exactly 5 symbols per bar, scale to bar height
  data: [3, 5, 2, 4],
}