✨ New Features & 🐛 Bug fixes
Release v3.26
✨Period Comparison: compare against several periods at once (#296)
compare now also accepts a list — one ghost series per entry, each reaching further back via periods_back:
entities:
- entity: sensor.temperature
compare:
- periods_back: 1 # previous period
- periods_back: 2 # two periods ago- Follows the date picker. With the picker on Week, the entries above show last week and two weeks ago; switch to Year and the same config shows last year and two years ago (calendar-aligned for month/year views, leap years handled).
- Each ghost is distinct. Later periods fade progressively by default (0.45 → 0.30 → 0.20 …), legends read "Name (previous period ×2)", and the tooltip shows every ghost's own date plus its own Δ% against the current value. With a single comparison everything looks exactly as in 3.25.
- Editor redesigned to match (as requested in the issue): the Period Comparison section starts empty with an Add Comparison button; each comparison is its own row — period, Periods Back, line style, color, opacity, Δ% — with a delete button. The period dropdown now names units to pair naturally with Periods Back: Day Before / Week Before / Month Before / Year Before (YAML values are unchanged:
yesterday,last_week,last_month,last_year). - Every entry still takes the full style set (
period,color,opacity,line_style,show_fill,show_points,show_in_legend,show_delta), and hiding the main series from the legend hides all of its ghosts. Existing singlecompareconfigs are untouched. hide_on_loadper comparison: an entry withhide_on_load: truestarts hidden when the card loads — click its legend entry to reveal it (and it stays revealed). Handy for keeping rarely-needed periods one click away instead of cluttering the chart. Also available as a Hide on Load toggle on each editor row.
✨Custom auto-scale rules (#297)
Auto Scale can now follow your thresholds instead of the built-in heuristic. Each rule says: when the visible period is up to N hours, use this Group By (and optionally a Points/Hour):
auto_scale_points: true
auto_scale_rules:
- up_to_hours: 24
group_by: hour
- up_to_hours: 168
group_by: date
- up_to_hours: 8784
group_by: month- Date-picker aware. A full month or year selection matches by its nominal length — pick a year in July and your yearly rule still applies, exactly like the built-in auto scale.
- Predictable fallbacks. The smallest matching threshold wins; a period beyond every threshold falls back to the built-in auto scale; an empty list means pure built-in behavior. The same safety guard applies: configs using
offset,forecast_horizonor attribute data keep their Group By untouched. - Editor: with Auto Scale on, a Custom Scale Rules list appears — Add Rule rows with Up to (hours), Group By (the same options as the main Group By select) and a Points/Hour preset dropdown that is enabled only for Interval rules (calendar buckets have a fixed size, so Points/Hour would do nothing there).
🛠 Fixes & reliability
-
Centered date-picker shortcuts no longer get cut off on narrow cards.
-
Pinch zoom actually zooms now.
Release v3.25
✨ Period Comparison
No more duplicating an entity and juggling offset by hand. One option overlays any series with a faded, dashed "ghost" of its previous period:
entities:
- entity: sensor.energy_consumption
compare: previous_period- Periods:
previous_period,yesterday,last_week,last_month,last_year, or a custom number of hours. - Smart shifting:
previous_periodfollows whatever window you are looking at. In the date picker's month view, July is compared with June aligned by calendar date — not by a fixed number of hours. Month-end dates are handled correctly (Mar 31 compares against Feb 28/29). - Tooltip Δ%: hovering shows the current value, the previous-period value, and the change in percent — green for up, red for down. The previous-period row also shows its own date and time (e.g. hovering 15 Jul, 14:00 shows 14 Jul, 14:00 above the comparison value), so you always know exactly which moment you are comparing against.
- One click, both series: hiding a series from the legend hides its ghost too.
- Fully styleable when you want more control:
entities:
- entity: sensor.energy_consumption
compare:
period: last_week
color: "#888888" # default: faded main color
opacity: 0.6 # default 0.45
line_style: dotted # default dashed
show_fill: false
show_delta: true # Δ% in the tooltip
show_in_legend: trueEverything is also configurable from the visual editor: each entity now has a Period Comparison section (timeline charts).
✨ PNG & CSV export
Turn it on and a small download icon appears in the top-right corner of the card:
show_export: true- Download PNG (Chart) — a crisp 2× image of the plot exactly as displayed (works for all chart modes, dark themes included).
- Download PNG (Card) — the whole card in one image: header, chart, state row and legend included. (If your theme uses an external background image the capture falls back to the chart-only export.)
- Download CSV — the visible series' plotted data in a spreadsheet-friendly wide format (UTF-8 with BOM, ISO timestamps in UTC). If you are zoomed in, both PNG and CSV export the zoomed range — you export what you see.
- Files are named after your card header, e.g.
Energy_Overview-20260715-1630.png. - Notes: candlestick CSV exports the bucket value (not OHLC); state-mapped series export their numeric values; the option is templatable like the other display toggles.
✨ Price Entity — consumption × tariff, done right
Chart what your energy actually costs, even on dynamic tariffs (Nordpool, Tibber, EPEX…):
entities:
- entity: sensor.energy_meter
aggregate_func: change
price_entity: sensor.electricity_price
unit: "€"- Every slice of consumption is billed at the price valid at that moment — Σ(kWhᵢ × priceᵢ) — not "average price × total kWh". With a day of 10 kWh cheap + 5 kWh peak power, the difference is real money.
- The price history is fetched automatically alongside your data (long windows use its long-term statistics), and prices are read as a step function — exactly how tariffs behave.
price_attributereads the price from an attribute instead of the state. Tariff changes refresh the card automatically. Period comparison works too: the ghost is billed at its period's prices.- Configure in the editor: Price Entity / Price Attribute under each entity's Advanced → Advanced Calculations section.
✨ Every chart speaks your language now
The remaining hardcoded English labels are gone: tooltip rows in Gauge (Peak/Low), RadialBar (Range/Progress), Radar (Range/Level), Pie/Ranking/Histogram (Share/Range/Count), the candlestick Change/Altitude rows, Scatter's empty-state message and the unknown-chart-mode notice are all translated into the card's 16 languages. Calendar weekday names and box-plot month names now come from your locale automatically.
A second sweep caught the stragglers: the Loading… placeholder, the radar "needs 3 entities" notice, the State option in the attribute dropdown, the date-picker navigation labels read by screen readers, and in the editor the annotation type names (Event marker, Time span, H-line, H-band), the icon-picker labels, the "Disabled when thresholds/trend active" notes and the remaining input placeholders (Off, All, current year, (all together)) — all translated now.
And the big one: all 226 ⓘ help tooltips in the visual editor are now translated into the card's 15 non-English languages. Hover any info icon and read the explanation in your own language — missing entries gracefully fall back to English. (This grows translations.js to ~1.6 MB; it is loaded once and cached by the browser.)
✨ Weeks start on your day
Weekly grouping, the date picker's week view and calendar grid, weekly x-axis ticks and box-plot weekly buckets now follow Home Assistant's First day of the week setting from your user profile. With the default ("Automatic"), the day comes from your language — US users get Sunday-based weeks, most of Europe keeps Monday. No configuration needed on the card.
✨ Templates for show/hide toggles
Display toggles now accept Jinja templates directly — same option, no extra _template keys. Drive card behavior from any helper or sensor:
show_legend: "{{ states('input_boolean.show_legend') == 'on' }}"
entities:
- entity: sensor.power
show_state: "{{ states('input_boolean.show_state') == 'on' }}"
show_graph: "{{ is_state('binary_sensor.presence', 'on') }}"- Works on 15 card-level toggles (
show_legend,show_grid,show_tooltip,show_tooltip_total,tooltip_stacked_total,show_now_line,show_x_axis,show_y_axis,show_y2_axis,show_x_ticks,show_y_ticks,show_y_axis_label,stacked,period_highlight,logarithmic,state_timeline_show_labels) and 18 entity-level toggles (show_state,show_in_legend,show_graph,show_line,show_fill,show_points,smooth,gradient,show_data_labels,show_average,show_trend_icon,show_color_dot,show_timestamp,show_range_values,show_extrema_min,show_extrema_max,extrema_show_timestamp,state_adaptive_color). - Live: the card reacts immediately when the template's result changes — no reload needed.
- Editor-safe: a toggle managed by a template shows locked in the visual editor with a
{…}badge (hover to see the template). Editing other options never overwrites your template. - Data-source and sync options (e.g.
cache,tooltip_sync,show_range_band) intentionally stay non-templatable — they control fetching and cross-card wiring, not display.
✨ State Timeline: hide the labels inside segments
A new toggle removes the state names (e.g. "Clear") drawn inside timeline segments for a clean color-band look:
chart_mode: state_timeline
state_timeline_show_labels: false # default trueAvailable in the editor next to Corner Radius, and it accepts a template too.
✨ "Raw (no grouping)" in the visual editor
group_by: raw draws every recorded sample at its exact timestamp — perfect for binary sensors as step charts, where each on/off transition matters. It is now selectable in the editor's Group By dropdown whenever one of your entities uses graph_type: step (and it always stays visible if your config already uses it).
✨ Pinch zoom & zoom history (mobile-friendly zooming)
Zooming finally feels right on phones and tablets:
- Pinch to zoom — put two fingers on a timeline chart and pinch: the chart zooms around the point between your fingers, live. Opening all the way back out returns to the full view.
- Zoom history — every zoom (brush or pinch) is remembered, up to 20 levels. Double-tap (touch) or double-click (mouse) steps back one level; when there is nothing left to step back to, you land on the full window.
- The long-press-and-drag brush still works exactly as before, and pinch cooperates with cross-card
zoom_sync.
Small behavior change: double-click used to reset the zoom completely — it now steps back one level at a time. If you only zoomed once, nothing changes.