Option configuration
Initialise a chart, read the option tree, and drive series from a dataset instead of hand-built arrays.
Initialise and setOption
<div id="main" style="width: 100%; height: 360px;"></div>
<script type="module">
import * as echarts from 'https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.esm.min.js';
const chart = echarts.init(document.getElementById('main'), null, {
renderer: 'canvas', // or 'svg' for large static dashboards and print
useDirtyRect: true // cheaper partial repaints while animating
});
chart.setOption({
xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu'] },
yAxis: { type: 'value' },
series: [{ type: 'line', data: [120, 200, 150, 80], smooth: true }]
});
window.addEventListener('resize', () => chart.resize());
// call chart.dispose() when the container is removed for good
</script>- The container must have a resolved height before
init— an emptydivcollapses to 0 and you get a blank canvas. setOptionis incremental by default: calling it again merges into the existing configuration.echarts.getInstanceByDom(el)returns an existing instance instead of stacking a second one on the same node.
The option tree
| Key | What it controls |
|---|---|
title | Heading text, subtext and their positions |
grid | Plot area insets — the usual fix for clipped axis labels |
xAxis / yAxis | Axis type, data, ticks, labels; each accepts an array for multiple axes |
series | The data itself plus everything visual about how it is drawn |
tooltip | Hover box; trigger: 'axis' shows all series at one x |
legend | Toggleable names, driven from series name values |
dataset | Tabular data that series reference by index |
dataZoom / toolbox | Zoom and drag controls, export to image |
color | The palette applied across series |
media | Responsive rule sets keyed on container width |
chart.setOption({
title: { text: 'Weekly signups', left: 'center' },
tooltip: { trigger: 'axis' },
legend: { bottom: 0 },
grid: { left: 48, right: 24, top: 56, bottom: 48 },
xAxis: { type: 'category', boundaryGap: false },
yAxis: { type: 'value', name: 'users' },
series: [
{ name: 'Free', type: 'line', areaStyle: {}, smooth: true, data: [820, 932, 901, 1290] },
{ name: 'Paid', type: 'line', areaStyle: {}, smooth: true, data: [120, 132, 141, 154] }
]
});Dataset and encode
A dataset keeps rows in one place and lets each series declare which column is the dimension and which are the values. When the data is refreshed, you update one array rather than one array per series.
chart.setOption({
dataset: {
source: [
['week', 'free', 'paid'],
['W1', 820, 120],
['W2', 932, 132],
['W3', 901, 141],
['W4', 1290, 154]
]
},
xAxis: { type: 'category' },
yAxis: { type: 'value' },
series: [
{ type: 'bar', name: 'Free', encode: { x: 'week', y: 'free' } },
{ type: 'bar', name: 'Paid', encode: { x: 'week', y: 'paid' } },
{ type: 'line', name: 'Total',
encode: { x: 'week', y: ['free', 'paid'] }, // two value columns map to x,y
datasetIndex: 0 }
]
});dataset.sourceaccepts an array of arrays or an array of objects.encodemaps roles:x,y,itemName,value,tooltip,seriesName.- A second
datasetentry becomes accessible withdatasetIndex, which is how you overlay summaries on raw rows.
💡
The option object is a plain description of the chart, so it can be produced by any code path — a template literal, a server response or a form builder. Keep it serialisable and keep business logic out of it.
FAQ
Why is my chart blank or 0px tall?
The container had no height when
init ran, or the element was hidden (display: none in a tab). Give it a height, and call chart.resize() after the tab becomes visible.Canvas or SVG renderer?
Canvas is the default and performs better with thousands of moving points. SVG produces sharper output at arbitrary zoom and lets you style elements with CSS — useful for small charts, exports and printing.
Related
Common chart types Interaction, resize and data updates
Last refreshed 2026-09-18.