-
Notifications
You must be signed in to change notification settings - Fork 4
Cookbook A1 Stacked Area Chart
A stacked area chart showing weekly energy consumption for three categories — Household, Wallbox, and Heat pump. The chart updates live in the browser whenever its data changes, with smooth ECharts animations and no page reload.
You will go through two stages:
- Part A — Static chart: Store the complete chart definition as JSON in a single ioBroker state. Edit the numbers by hand and watch the chart react instantly via SSE.
- Part B — Connected chart: Create three dedicated data states (one per energy series). A small JavaScript script reads them and rebuilds the chart automatically whenever a value changes.
The browser URL is the same in both parts — only the content of the chart state changes.
- flexcharts adapter installed and running (web extension on port 8082)
- JavaScript adapter (
javascript.0) running
Run this short script once in the JavaScript adapter to create the output state. You can stop or delete the script afterwards — it is only needed for the initial setup.
createState('0_userdata.0.flexcharts.energy.chart', '', {
name: 'Energy chart',
type: 'string',
role: 'json',
read: true,
write: true
});Open the ioBroker Admin UI, go to Objects → 0_userdata.0 → flexcharts → energy → chart, click the edit icon (pencil), and paste the following JSON as the state value. Then save.
{
"title": { "text": "Weekly Energy Consumption", "left": "center" },
"tooltip": { "trigger": "axis", "axisPointer": { "type": "cross", "label": { "backgroundColor": "#6a7985" } } },
"legend": { "data": ["Household", "Wallbox", "Heat pump"], "top": "8%" },
"toolbox": { "feature": { "saveAsImage": {} } },
"xAxis": [{ "type": "category", "boundaryGap": false,
"data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] }],
"yAxis": [{ "type": "value", "name": "kWh" }],
"series": [
{ "name": "Household", "type": "line", "stack": "Total",
"areaStyle": {}, "emphasis": { "focus": "series" },
"data": [12, 11, 13, 12, 14, 9, 10] },
{ "name": "Wallbox", "type": "line", "stack": "Total",
"areaStyle": {}, "emphasis": { "focus": "series" },
"data": [0, 22, 0, 0, 22, 0, 0] },
{ "name": "Heat pump", "type": "line", "stack": "Total",
"areaStyle": {}, "emphasis": { "focus": "series" },
"data": [8, 9, 10, 9, 8, 6, 7] }
]
}Note: This is standard JSON — all keys and string values must use double quotes. The
"areaStyle": {}property turns each line into a filled area.
http://localhost:8082/flexcharts/echarts.html?source=state&id=0_userdata.0.flexcharts.energy.chart&sse
Replace localhost and 8082 with your ioBroker address and port. The chart should appear immediately.
What &sse does: The browser keeps a persistent connection open to ioBroker (Server-Sent Events). Whenever the state 0_userdata.0.flexcharts.energy.chart changes, ioBroker sends a notification to the browser. The browser then fetches the new chart definition and calls setOption() — no page reload, just a smooth animation.
Go back to Objects, open 0_userdata.0.flexcharts.energy.chart, and change one of the numbers in a data array — for example, change the Wallbox value for Wednesday from 0 to 35. Save, and watch the chart animate to the new values.
Editing the full chart JSON by hand is fine for exploration, but cumbersome in practice. In this part you separate the data from the chart structure:
- Three states hold the actual energy values, one per series
- A script subscribes to those states and updates the data in the chart state whenever a value changes
- The chart definition you created in Part A remains the master — the script only touches the
dataarrays, nothing else - The browser URL stays exactly the same
Run this script once, then stop it:
createState('0_userdata.0.energy.consumption.household', '[12, 11, 13, 12, 14, 9, 10]', {
name: 'Household kWh per day (Mon–Sun)', type: 'string', role: 'json', read: true, write: true
});
createState('0_userdata.0.energy.consumption.wallbox', '[0, 22, 0, 0, 22, 0, 0]', {
name: 'Wallbox kWh per day (Mon–Sun)', type: 'string', role: 'json', read: true, write: true
});
createState('0_userdata.0.energy.consumption.heatpump', '[8, 9, 10, 9, 8, 6, 7]', {
name: 'Heat pump kWh per day (Mon–Sun)', type: 'string', role: 'json', read: true, write: true
});Each state holds a JSON array of 7 numbers: one per day of the week, Monday through Sunday.
Create a new script in the JavaScript adapter and paste the code below. Keep this script running — it subscribes to the three data states and updates the chart whenever any of them changes.
const stateHousehold = '0_userdata.0.energy.consumption.household';
const stateWallbox = '0_userdata.0.energy.consumption.wallbox';
const stateHeatpump = '0_userdata.0.energy.consumption.heatpump';
const chartState = '0_userdata.0.flexcharts.energy.chart';
// Ensure the output state exists, then inject the initial data.
createState(chartState, '', { name: 'Energy chart', type: 'string', role: 'json', read: true, write: true }, () => {
buildAndSaveChart();
});
// Update the chart whenever any of the three data states changes.
// ack: false means the value was written manually (Objects editor) or by a script.
// Change to ack: true if the states are written by a device adapter.
for (const id of [stateHousehold, stateWallbox, stateHeatpump]) {
on({ id: id, ack: false }, () => { buildAndSaveChart(); });
}
function buildAndSaveChart() {
const household = JSON.parse(getState(stateHousehold).val || '[]');
const wallbox = JSON.parse(getState(stateWallbox).val || '[]');
const heatpump = JSON.parse(getState(stateHeatpump).val || '[]');
// Read the chart definition from the state — the script only updates the data arrays.
// All visual settings (colors, title, axes, layout) remain exactly as you defined them in Part A.
const option = JSON.parse(getState(chartState).val || '{}');
const dataMap = { 'Household': household, 'Wallbox': wallbox, 'Heat pump': heatpump };
for (const s of option.series || []) {
if (s.name in dataMap) s.data = dataMap[s.name];
}
// Write the updated chart back to the state.
// SSE detects this change and triggers setOption() in the browser — no page reload.
setState(chartState, JSON.stringify(option), true);
}The browser URL is unchanged:
http://localhost:8082/flexcharts/echarts.html?source=state&id=0_userdata.0.flexcharts.energy.chart&sse
Now go to the Objects view and edit one of the energy states — for example change the Wallbox array to [0, 30, 0, 0, 0, 15, 0]. Save, and watch the chart update with a smooth animation.
Important: When saving a state value in the ioBroker Objects editor, make sure the Acknowledged (ack) checkbox is not checked. The update script listens for unacknowledged changes (
ack: false). If you save with ack enabled, the script will not react and the chart will not update.
Objects editor
│ change value in energy state
▼
javascript.0 script ←── on() subscription fires
│ reads all three states, builds option JSON
│ setState(chartState, ...)
▼
0_userdata.0.flexcharts.energy.chart (state)
│ state change detected by SSE
▼
flexcharts (ioBroker web extension)
│ sends SSE notification to browser
▼
Browser
│ fetches new chart definition
│ calls myChart.setOption(...)
▼
ECharts renders updated chart with animation
- Cookbook A2 — Add a pie chart to the same state showing total energy distribution
-
Cookbook A3 — Make the pie react to hover events on the area chart using
javascript-stringify
Cookbook A — From Scratch
Cookbook B — AI-Assisted