SuperAPI AI Directory

echarts-dashboard-patterns

General & other

View repository

Updated 10-15 21:52

About this skill

ECharts Dashboard Patterns

Do not make ECharts options into a fixed set of numbers. Match them to the actual container size, data density, label length, legend position, and the meaning of missing data, and verify with the rendered result.

First, distinguish the request mode. If it is a review/diagnosis request, read the chart and rendered result and report only findings with evidence, and do not modify files or refactor surrounding charts. Only for generation/modification requests, apply the patterns below to the actual implementation.

Quick Start

  1. Check the installed ECharts version and the existing option builder, theme, and renderer.
  2. Decide in one sentence the question the chart must answer and the series that must be shown.
  3. Prepare not only representative data but also long labels, the maximum number of series, and missing intervals.
  4. Select only the patterns below that are needed for the current problem. In review mode, use them as diagnostic criteria, and apply them to code only in generation/modification mode.
  5. Render the actual chart at the target width and the narrowest supported width. If in generation/modification mode, fix the confirmed problems within scope.
  6. If there were changes, verify tests/build and resize behavior appropriate to the scope.

Core Patterns

Time-axis density

splitNumberis not an exact tick count but a hint. Set a readable target value of about 3-8 to match the chart width and time range, and hideOverlapas a safety net.

xAxis: {
  type: 'time',
  splitNumber: targetTickCount,
  axisLabel: {
    hideOverlap: true,
    formatter: rangeIncludesMultipleDays ? '{MM}/{dd}\n{HH}:{mm}' : '{HH}:{mm}',
  },
}

Do not shrink the text excessively just to expose all labels. First check whether the actual time range and timezone match, and on narrow screens reduce the tick count or simplify the format.

Legend and grid ownership

For axis labels, use grid.containLabel: true. The legend is a separate area outside the grid, so secure space based on the actual width and whether it wraps, not the number of items.

legend: { type: legendMayOverflow ? 'scroll' : 'plain', bottom: 0 },
grid: {
  containLabel: true,
  top: 24,
  right: 16,
  bottom: legendHeight + 16,
  left: 16,
},

56px, 4개 이상 Values like this are only a starting point, not a contract. If translated labels, fonts, icons, or container width change, render again and decide.

Multiple y-axes

Make each axis clearly own different units and series. Verify the right axis margin with the longest formatted label, and if there are two or more axes on the same side, use offset. It is easier to read if grid lines are placed on only one primary axis.

yAxis: [
  { type: 'value', name: latencyUnit },
  {
    type: 'value',
    name: trafficUnit,
    position: 'right',
    splitLine: { show: false },
  },
]

Do not force different scales onto the same axis, and verify in the actual render the series order, opacity, and zso that visually strong bars do not obscure the key line.

Intentional gaps

Do not fill meaningless values with 0 or carry them forward from the previous value. Normalize values such as NaN, and empty strings from API results into the '-' sentinel that ECharts documents as missing data, and specify whether to connect them.

const toMetricValue = (value: unknown) => {
  if (value === null || value === undefined || value === '') return '-'
  const numeric = Number(value)
  return Number.isFinite(numeric) ? numeric : '-'
}

series: [{
  type: 'line',
  connectNulls: false,
  data: points.map(([time, value]) => [time, toMetricValue(value)]),
}]

If the missingness means insufficient samples or collection interruption, explain it in an appropriate place among the legend, supplementary text, or tooltip. Do not hide gaps with different causes under a single visual rule.

Human-readable series names

Map raw metric labels to stable display names just before display. If there is an existing BFF or server presentation layer, follow that boundary, but do not create a new server layer just to solve this problem. Keep unknown values as-is so the series does not disappear.

const SERIES_LABELS: Record<string, string> = {
  cache_hit: 'Cache Hit',
  retrieval: 'Retrieval',
  ranking: 'Ranking',
}

const displayName = SERIES_LABELS[rawName] ?? rawName

Shared option builders

Extract a common builder only when the same tooltip, grid, and axis policy actually repeats across two or more charts. Before creating a new abstraction, check whether existing helpers can be extended.

A shallow spread is grid, axisLabel, tooltip It can overwrite an entire nested object such as . Have the common builder return a new object, and explicitly merge chart-specific differences. Do not refactor surrounding charts in a request that changes only one chart.

Responsive Behavior

  • The container's CSS size must be clear, and do not initialize it while its height is 0.
  • For layout changes, do not assume only window resize; follow the existing project pattern ResizeObserver or an equivalent means to call chart.resize().
  • A chart first rendered in a hidden tab may need a resize after it becomes visible.
  • Do not unconditionally remove information on small screens. Set priorities for ticks, legends, grids, and tooltips, and verify that the core series remain.

Verification Loop

At minimum, verify the following states with actual rendering.

  • Target width and narrowest supported width
  • Longest axis/legend labels and maximum number of series
  • Normal values, empty results, missing-data gaps, extreme values
  • Legend scroll, tooltip, hover/emphasis, container resize
  • Axis unit truncation, legend-grid collision, horizontal overflow, absence of a 0-height canvas

If possible, use existing Storybook, dashboard routes, and visual tests. If there is no rendering environment, do not claim completion based only on option checks; specify the viewports and states you could not verify.

Output Contract

If it is a review, start with important findings and state that you did not change any files. If it is a create/modify request, state the change results first. Then briefly list only the viewports/data states actually rendered and the tests run. If visual verification was not possible, state that fact and the remaining risks.

Gotchas

  • splitNumberis not a guaranteed value, and hideOverlapalone does not make a good axis.
  • containLabelhelps with axis labels but does not calculate external legend space.
  • connectNulls: falseis meaningful only when the input is normalized to actual missing values.
  • Dual-axis can easily imply correlation. Make units and series ownership clear.
  • If test fixtures contain only short English labels, real collisions will be missed.
  • Do not expand scope with unrequested BFF, design system, or chart library replacements.