-
Notifications
You must be signed in to change notification settings - Fork 4
Cookbook A3 Interactive Charts
An interactive combined chart: an area chart in the lower half and a pie chart in the upper half. When the mouse moves over a day in the area chart, the pie automatically updates to show the energy distribution for exactly that day.
The key new concept: the chart state now holds an array of two strings — the chart option and a browser-side event handler. flexcharts injects both into the page on load.
Completed Cookbook A1 and Cookbook A2. The chart state and energy data states must be in place.
Up to now the chart state contained a single option string. In A3 it becomes a JSON array:
| Index | Content |
|---|---|
[0] |
Chart option — the same kind of string as before |
[1] |
Event handler — JavaScript code that runs in the browser after the chart is rendered |
flexcharts detects the array automatically: arr[0] is injected as the chart option, arr[1] is evaluated in the browser. For SSE updates, only arr[0] is refreshed — the event handler is registered once on initial load and stays active.
Open 0_userdata.0.flexcharts.energy.chart in the Objects editor and replace its value with the JSON array below. Save (ack unchecked).
[
"{title:{text:'Weekly Energy Consumption',left:'center'},tooltip:{trigger:'axis',showContent:false},legend:{top:'8%'},toolbox:{feature:{saveAsImage:{}}},color:['#5b8dd9','#00a3a3','#3a5fa0'],dataset:{source:[['category','Mon','Tue','Wed','Thu','Fri','Sat','Sun'],['Household',12,11,13,12,14,9,10],['Wallbox',0,22,0,0,22,0,0],['Heat pump',8,9,10,9,8,6,7]]},xAxis:{type:'category'},yAxis:{gridIndex:0},grid:{top:'55%'},series:[{type:'line',smooth:true,seriesLayoutBy:'row',areaStyle:{},emphasis:{focus:'series'}},{type:'line',smooth:true,seriesLayoutBy:'row',areaStyle:{},emphasis:{focus:'series'}},{type:'line',smooth:true,seriesLayoutBy:'row',areaStyle:{},emphasis:{focus:'series'}},{type:'pie',id:'pie',radius:'22%',center:['50%','33%'],emphasis:{focus:'self'},label:{formatter:'{b}: {@Mon} kWh ({d}%)'},encode:{itemName:'category',value:'Mon',tooltip:'Mon'}}]}",
"myChart.on('updateAxisPointer',function(e){let t=e.axesInfo[0];if(t){let i=t.value+1;myChart.setOption({series:{id:'pie',label:{formatter:'{b}: {@['+i+']} kWh ({d}%)'},encode:{value:i,tooltip:i}}})}});"
]What changed compared to A2:
- The data is now in a shared dataset (
dataset.source) — a table with one row per energy category and one column per day. The area chart series and the pie chart both read from this single table. -
tooltip: {trigger: 'axis', showContent: false}— the axis pointer fires when the mouse moves, but no floating tooltip is shown. The pie acts as the visual feedback instead. -
[1]— the event handler string: listens forupdateAxisPointerevents and updates the pie'sencodeto show the column matching the hovered day.
The URL is unchanged:
http://localhost:8082/flexcharts/echarts.html?source=state&id=0_userdata.0.flexcharts.energy.chart&sse
Move the mouse over the area chart. The pie updates instantly to show the distribution for each day.
Instead of individual data arrays per series (as in A1/A2), A3 uses a single dataset.source table:
Mon Tue Wed Thu Fri Sat Sun
Household 12 11 13 12 14 9 10
Wallbox 0 22 0 0 22 0 0
Heat pump 8 9 10 9 8 6 7
Each line series uses seriesLayoutBy: 'row' to read one row from this table. The pie series uses encode: {itemName: 'category', value: 'Mon'} to read a column — initially Monday.
The event handler string in arr[1] is evaluated in the browser once after the chart is initialized:
myChart.on('updateAxisPointer', function(e) {
let t = e.axesInfo[0];
if (t) {
let i = t.value + 1; // axis index 0–6 → dataset column 1–7
myChart.setOption({
series: {
id: 'pie',
label: { formatter: '{b}: {@[' + i + ']} kWh ({d}%)' },
encode: { value: i, tooltip: i }
}
});
}
});When the mouse moves over the area chart, updateAxisPointer fires with the hovered axis position. t.value is the day index (0 = Mon, …, 6 = Sun). Adding 1 gives the dataset column index. The pie's encode.value is updated to that column — ECharts re-reads the dataset and redraws the pie for that day.
You may have noticed that the option string uses unquoted keys and single quotes — not strict JSON:
{title:{text:'Weekly Energy Consumption',...}, ...}This is valid JavaScript object notation. flexcharts evaluates it in the browser using new Function('return ' + optionString)(), which handles any valid JavaScript expression. This is the same format produced by the npm package javascript-stringify, which is used in source=script scripts (see Template 3 and Template 4) when the chart option contains JavaScript functions that JSON.stringify() cannot serialize — for example a custom tooltip formatter like value => value.toFixed(2).
For the charts in this cookbook, all formatters use ECharts template strings ('{b}: {c}') rather than JavaScript functions, so JSON.stringify() is sufficient.
To keep the interactive chart updated from real data states (like in A1/A2), a script would:
- Read the three energy states
- Parse the chart state as a JSON array:
const arr = JSON.parse(getState(chartState).val) - Parse the option string:
const option = new Function('return ' + arr[0])() - Update
option.dataset.sourcewith the fresh data - Serialize back:
arr[0] = JSON.stringify(option)(note: usejavascript-stringifyif the option contains functions) - Write:
setState(chartState, JSON.stringify(arr), true)
SSE then delivers only the updated option (arr[0]) to the browser — the event handler in arr[1] is not re-evaluated and remains active.
For fully code-driven charts, the source=script pattern (using onMessage) gives you more flexibility: the script generates the option at request time, can access URL parameters, and can use javascript-stringify for options containing real JavaScript functions. The script returns [strify.stringify(option), eventHandlerString] — the same array format as the state, just produced dynamically. See Template 4 for a complete example.
The examples in this cookbook are a small sample of what ECharts can do. Apache provides a rich set of tools to help you explore and build further:
| Resource | What it's for |
|---|---|
| Examples gallery | Hundreds of interactive chart examples with live editors — the best starting point for new chart ideas |
| Option reference | Complete documentation of every chart option, series type, and property |
| Handbook | Tutorials covering concepts like datasets, events, theming, and responsive charts |
| Theme Builder | Visual editor for custom themes — export as JSON and pass to flexcharts (see Template 5) |
The workflow that works well: find a chart in the Examples gallery that matches what you want, open its editor, adapt the data and options, then transfer the result to a flexcharts state or script.
These three articles covered the core flexcharts patterns:
| Article | Pattern | Key concept |
|---|---|---|
| A1 | State as master, simple option string | SSE, createState, data injection |
| A2 | State as master, extended option string | Combined chart types, computed totals |
| A3 | State as master, array [option, eventHandler]
|
Browser events, shared dataset, JavaScript syntax |
For more examples and advanced patterns, see the flexcharts templates and the flexcharts README.
Cookbook A — From Scratch
Cookbook B — AI-Assisted