Skip to content

Cookbook B1 AI Simple Chart

MyHomeMyData edited this page May 7, 2026 · 1 revision

Cookbook B1 — First Chart Session: Bar Chart with AI

What you will build

A styled bar chart showing monthly electricity costs, including a reference line at the annual average — created through a two-message exchange with Claude.

This article documents a real AI session. You will see the exact prompts used, what Claude returned, and how one refinement iteration turned a basic output into a polished chart.

Prerequisites

  • Completed Cookbook B0 — you have the context primer ready to paste
  • An ioBroker state to hold the chart, for example 0_userdata.0.flexcharts.mychart (string type)
  • flexcharts accessible at http://localhost:8082/flexcharts/echarts.html

The session

Step 1 — Start with the primer

Open a new conversation at claude.ai. Select Claude Sonnet if you have a choice of models.

Paste the primer from Cookbook B0 as your first message and send it. Claude will confirm it understood the output rules.

Claude's reply to the primer will be a short acknowledgement — something like: "Understood. I'll output only the ECharts option as a valid JSON object, ready to paste as an ioBroker state value. What chart would you like?" The exact wording varies; what matters is that Claude confirmed the rules.


Step 2 — The first prompt (deliberately vague)

Send this as your next message:

Create a bar chart showing monthly electricity costs for a household in 2024.

No data values, no colors, no formatting details — this is intentionally vague to see what Claude produces on its own.

Claude's response:

{
  "title": {
    "text": "Stromkosten 2024",
    "left": "center"
  },
  "tooltip": {
    "trigger": "axis",
    "formatter": "{b}: {c} €"
  },
  "xAxis": {
    "type": "category",
    "data": ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"],
    "axisLabel": { "rotate": 30 }
  },
  "yAxis": {
    "type": "value",
    "name": "",
    "min": 0
  },
  "series": [
    {
      "type": "bar",
      "data": [87, 79, 74, 61, 52, 48, 46, 49, 57, 68, 81, 91],
      "itemStyle": { "color": "#f0a030" },
      "label": {
        "show": true,
        "position": "top",
        "formatter": "{c} €"
      }
    }
  ],
  "grid": {
    "bottom": "15%"
  }
}

What to notice:

  • The output is a clean JSON object, ready to paste — no wrapper, no const option =
  • Claude went well beyond the bare minimum: it added a title, a € unit label, value labels on each bar, a tooltip formatter, and rotated the x-axis labels — all without being asked
  • It chose a plausible seasonal distribution for the values (higher in winter, lower in summer) even though no data was provided
  • It answered in German ("Stromkosten 2024", German month abbreviations) — matching the implied locale of the prompt
  • What's missing: a reference line for the average, and the color and value range are not yet what we want

Step 3 — Paste and view

Copy Claude's JSON, open 0_userdata.0.flexcharts.mychart in the ioBroker Objects editor, paste the value, and save (ack unchecked).

Open the chart in the browser:

http://localhost:8082/flexcharts/echarts.html?source=state&id=0_userdata.0.flexcharts.mychart&sse

Already a usable chart — but the colors, value range, and the missing average line leave room for one targeted refinement round.


Step 4 — The refinement prompt

Send this follow-up message in the same Claude conversation:

Improve the chart:
- Use real-looking monthly values in the range 60–140 € with seasonal variation (higher in winter)
- Add a horizontal reference line at the annual average
- Color the bars blue, the reference line orange, dashed
- Format Y-axis labels and tooltip values with a € suffix
- Add a title "Electricity Costs 2024"

Claude's response:

{
  "title": {
    "text": "Electricity Costs 2024",
    "left": "center"
  },
  "tooltip": {
    "trigger": "axis",
    "formatter": "{b}: {c} €"
  },
  "xAxis": {
    "type": "category",
    "data": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
    "axisLabel": { "rotate": 30 }
  },
  "yAxis": {
    "type": "value",
    "min": 0,
    "axisLabel": { "formatter": "{value} €" }
  },
  "series": [
    {
      "name": "Monthly Cost",
      "type": "bar",
      "data": [138, 129, 112, 88, 72, 64, 61, 66, 79, 95, 118, 135],
      "itemStyle": { "color": "#3a7bd5" },
      "label": {
        "show": true,
        "position": "top",
        "formatter": "{c} €"
      }
    },
    {
      "name": "Annual Average",
      "type": "line",
      "data": [96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96],
      "symbol": "none",
      "lineStyle": {
        "color": "#f07020",
        "type": "dashed",
        "width": 2
      },
      "itemStyle": { "color": "#f07020" },
      "label": {
        "show": true,
        "position": "insideEndTop",
        "formatter": "Ø 96 €",
        "offset": [0, -10],
        "color": "#f07020",
        "onlyOnce": true
      }
    }
  ],
  "legend": {
    "top": "8%",
    "data": ["Monthly Cost", "Annual Average"]
  },
  "grid": {
    "bottom": "15%",
    "top": "18%"
  }
}

What changed:

  • Title switched to English ("Electricity Costs 2024"), month labels follow
  • Values now span the requested 60–140 € range with a stronger seasonal swing (61 € in July, 138 € in January)
  • Bars are now blue (#3a7bd5) instead of orange
  • Average reference line added — Claude implemented it as a flat line series (constant value repeated 12 times) rather than ECharts' markLine. Both work; this approach makes the average a named legend entry
  • Claude computed the average itself: the 12 values sum to 1157, giving a true average of 96.4 — Claude labeled it as 96 €, which is correct to one significant digit
  • axisLabel.formatter added to the y-axis; a legend added for both series

Step 5 — Paste and view the final chart

Replace the state value with Claude's second response and save (ack unchecked). Refresh the browser tab (or let SSE do it automatically).

The chart is complete. Two messages from a standing start.


What made this work

Step Why it worked
Primer first Claude knew to output raw JSON — no manual cleanup needed
Vague first prompt Even without data or styling instructions, Claude produced a fully functional chart with sensible defaults — seasonal values, labels, tooltip formatting
Refinement in one message Five separate requirements in one follow-up — Claude applied all of them at once, including computing the average
Same conversation Claude remembered the primer rules and the existing option structure — no re-explanation needed

Taking it further

  • Real data from states: replace the hardcoded values with a script that reads ioBroker states (see Cookbook A1 for the pattern)
  • SSE auto-update: add &sse&triggerid=<stateId> to the URL to refresh the chart when data changes
  • Interactive charts: ask Claude to add an event handler — tell it to use the two-element array format from Cookbook B0

What's next

  • Cookbook A1 — connect a chart to live ioBroker states with SSE