Skip to content

✈️ Performance Improvements & πŸ› Bug Fix

Choose a tag to compare

@cataseven cataseven released this 08 Aug 16:06
· 6 commits to main since this release
2f523bc

v4.01

✈️ Performance Improvements

This release ships a comprehensive round of server-load optimizations across the card's entire data pipeline β€” dramatically fewer and smaller database queries, requests shared between cards, and smarter refresh timers β€” cutting a typical dashboard's Home Assistant database traffic significantly faster

##🏷️ x_axis_datetime_format no longer vanishes from auto_scale_rules

Editing any setting in the visual editor used to silently strip x_axis_datetime_format from every rule in auto_scale_rules β€” the editor rebuilt the rule rows without knowing about the new key (#339 follow-up). The key now survives editor edits, like datetime_format and x_axis_interval always did.

v4.00 (If you are updating from v3.xx)

πŸ—‚οΈ A reorganized, searchable card editor

The visual editor has been restructured around what you're actually configuring. New main section: CARD SETTINGS and SEARCH BAR

search
  • Chart Settings (formerly General Settings) now holds only chart-related options, with Chart Mode pinned at the top β€” always visible, no matter which tab you're on.
  • A new top-level Card Settings panel collects everything about the card itself, in three tabs: Header & Icon, Card Styling and Localization. No more digging through a "Card" tab inside the chart options.
  • A search box at the top of the editor filters every setting live β€” type "opacity" or "border" and only the matching fields stay visible, with their panels opened for you. This covers entity settings too: entity cards with a match open up showing just the hits, and typing an entity's name reveals that entity's full settings. Options that don't apply to the current chart mode stay hidden, and clearing the search puts everything back the way it was.
  • Each tab shows a small badge with the number of options you've changed in it, so you can see at a glance where your configuration lives.

Nothing moved in YAML β€” every option keeps its name and place; only the editor's layout changed.

πŸ”’ Hide the numbers inside heatmap and calendar cells

A new Cell Values toggle (next to Grid in the editor's Chart tab) controls the numbers printed inside Heatmap and Calendar boxes:

show_cell_values: false

Off gives a clean, colour-only grid β€” the exact values stay one hover away in the tooltip, and the Calendar's day numbers stay visible. Defaults to on, so existing cards look exactly the same.

🏷️ Format the X-axis labels yourself

A new x_axis_datetime_format option gives you the axis labels you actually want, independent of the tooltip's datetime_format. It takes the same tokens (MMM, DD, ddd, YYYY, …) and also works per rule inside auto_scale_rules, so each zoom level can have its own label style:

auto_scale_rules:
  - up_to_hours: 768
    group_by: date
    x_axis_interval: 1d
    x_axis_datetime_format: "ddd DD"     # Mon 27, Tue 28, …
  - up_to_hours: 8784
    group_by: month
    x_axis_interval: 1M
    x_axis_datetime_format: "MMM"        # Jan, Feb, … (no year)

The tick density adapts to the pattern length, so short formats like MMM fit more labels on the axis. Leave it unset and the axis formats itself exactly as before.

πŸ“‘ group_by now works on attribute data sources

If your entity reads its points from an attribute array β€” electricity prices are the classic case β€” the calendar group_by modes now actually regroup them. A Nord Pool sensor publishing 96 quarter-hourly prices turns into clean hourly bars with just:

group_by: hour
entities:
  - entity: sensor.nord_pool_prices
    graph_type: bar
    aggregate_func: avg
    data_attribute: data
    data_time_field: start
    data_value_field: value

The details:

  • Works with hour, date, week, month and year. The regroup only happens when the requested cell is genuinely coarser than the array's own spacing, so an array that is already hourly stays untouched under group_by: hour β€” existing cards render pixel-identical.
  • aggregate_func decides how each cell is combined: avg for price levels, max for peaks, and so on. Mind that sum over quarter-hourly prices adds four prices per hour β€” that is rarely what you want for a tariff.
  • The state row and legend stats follow the grouped values, so with avg the shown maximum becomes the highest hourly average rather than the highest raw quarter.
  • interval (the default) and raw keep passing the array through exactly as published. The fixed 2h–12h modes are not supported for attribute arrays; the card now says so once in the console instead of staying silent.

πŸ›  Fixes & reliability

⚑ Long-range charts load much faster

A round of performance work aimed at charts showing weeks, months or a year of history:

None of this changes what is drawn: the whole release was gated on pixel-identical renders across the full chart-mode battery.

πŸ“ The second Y axis now shares the grid

On a dual-axis chart, the right axis used to pick its own "nice" numbers and place them at its own heights β€” so its labels floated between the grid lines, and its bottom label didn't line up with the left axis. The right axis now labels the same grid rows as the left one, with its own values interpolated at each row. Every right-hand label sits exactly on a grid line, top and bottom aligned with the left axis. The values may carry a decimal (e.g. 15.3 instead of 15) β€” that is the price of perfect alignment, and the y_axis_decimals option controls how many.

0️⃣ Zero now sits on the axis β€” and both Y axes agree on it

With a bar chart on the primary axis and a line or area on the secondary, the two zeros didn't line up: bars sat on the plot floor while the second series floated about 7% higher, because the automatic "breathing room" below the lowest value was cancelled for bars but not for lines. The rule is now the same for every chart type: when your data never goes below zero, the axis never does either. Zero sits exactly on the plot floor, on both axes, in every combination.

This visibly changes any line or area chart whose values touch zero β€” the line now rests on the axis instead of hovering slightly above it (and thanks to the clipping fix below, it renders at full thickness there). Charts with negative values, and axes with explicit card-level bounds, keep their exact current behaviour.

↔️ Year and month views span the full chart width

On a line or area chart grouped by month or year, the first and last points used to sit half a slot in from the chart edges β€” a year view showed roughly half a month of empty space before January and after December. Line charts now stretch edge to edge: January's point sits on the left border, December's on the right, and the month labels move with them, so every label still sits directly under its point.

Bar and candlestick charts are untouched β€” bars need their full slots β€” and so are mixed cards that contain one. The now marker keeps its position inside the current month under the new spacing.

βœ‚οΈ Lines at the plot edge are no longer half-clipped

A line sitting exactly on a chart boundary β€” a value pinned at its upper_bound, an auto-scaled peak touching the top, or a step chart's vertical jump at the very edge of the window β€” was drawn at half its thickness, because the plot's clipping box cut the stroke straight down its centre. The clip now leaves room for half the line width on every side, so edge-hugging lines render at full thickness. Nothing else moves: the change is a few pixels wide and only where a line actually touches the boundary.

πŸ”„ Inverted series flip their fill gradient too

With invert: true the area fill kept fading top-to-bottom, so an inverted series ended up strongest at the x-axis and weakest at its own line β€” the mirror image of what every normal series shows. The gradient now flips with the series: strongest at the line, fading toward the axis, exactly like bars have always done for negative values.

πŸ“ height: auto + rows: auto no longer shrinks on reload

A card with height: auto and grid_options.rows: auto looked right after saving, but shrank after a page refresh: on a cold load the dashboard measured the card before its data had arrived β€” a near-empty shell β€” and locked the row count to that. Three guards now make the height deterministic: the chart reserves its 200 px plot area from the first paint instead of trusting a transient measurement, and the card tells the dashboard a sane minimum row count up front. Saving and refreshing now agree on the same height. Set an explicit height (or fixed rows) as before if you want a specific size.