diff --git a/src/components/chart/axis-label.ts b/src/components/chart/axis-label.ts index 1f8f9a8154..37e8e97a63 100644 --- a/src/components/chart/axis-label.ts +++ b/src/components/chart/axis-label.ts @@ -5,12 +5,41 @@ import { formatDateMonthYear, formatDateVeryShort, formatDateWeekdayShort, + formatDateYear, } from "../../common/datetime/format_date"; import { formatTime, formatTimeWithSeconds, } from "../../common/datetime/format_time"; +export function getPeriodicAxisLabelConfig( + period: string, + locale: FrontendLocaleData, + config: HassConfig +): + | { + formatter: (value: number) => string; + } + | undefined { + if (period === "month") { + return { + formatter: (value: number) => { + const date = new Date(value); + return date.getMonth() === 0 + ? `{bold|${formatDateMonthYear(date, locale, config)}}` + : formatDateMonth(date, locale, config); + }, + }; + } + if (period === "year") { + return { + formatter: (value: number) => + formatDateYear(new Date(value), locale, config), + }; + } + return undefined; +} + export function formatTimeLabel( value: number | Date, locale: FrontendLocaleData, diff --git a/src/components/chart/ha-chart-base.ts b/src/components/chart/ha-chart-base.ts index 4d664b5eb2..62f801d14b 100644 --- a/src/components/chart/ha-chart-base.ts +++ b/src/components/chart/ha-chart-base.ts @@ -651,7 +651,7 @@ export class HaChartBase extends LitElement { hideOverlap: true, ...axis.axisLabel, }, - minInterval, + minInterval: axis.minInterval ?? minInterval, } as XAXisOption; }); } diff --git a/src/components/chart/statistics-chart.ts b/src/components/chart/statistics-chart.ts index b203d09890..d6a4c6749e 100644 --- a/src/components/chart/statistics-chart.ts +++ b/src/components/chart/statistics-chart.ts @@ -32,6 +32,7 @@ import { } from "../../data/recorder"; import type { ECOption } from "../../resources/echarts/echarts"; import type { HomeAssistant } from "../../types"; +import { getPeriodicAxisLabelConfig } from "./axis-label"; import type { CustomLegendOption } from "./ha-chart-base"; import "./ha-chart-base"; @@ -293,6 +294,22 @@ export class StatisticsChart extends LitElement { type: "time", min: startTime, max: this.endTime, + ...(this.period === "month" && { + minInterval: 28 * 24 * 3600 * 1000, + axisLabel: getPeriodicAxisLabelConfig( + "month", + this.hass.locale, + this.hass.config + ), + }), + ...(this.period === "year" && { + minInterval: 365 * 24 * 3600 * 1000, + axisLabel: getPeriodicAxisLabelConfig( + "year", + this.hass.locale, + this.hass.config + ), + }), }, { id: "hiddenAxis", diff --git a/src/panels/lovelace/cards/energy/common/energy-chart-options.ts b/src/panels/lovelace/cards/energy/common/energy-chart-options.ts index 745a9d2e19..8a68511a35 100644 --- a/src/panels/lovelace/cards/energy/common/energy-chart-options.ts +++ b/src/panels/lovelace/cards/energy/common/energy-chart-options.ts @@ -35,6 +35,7 @@ import { formatTime } from "../../../../../common/datetime/format_time"; import type { ECOption } from "../../../../../resources/echarts/echarts"; import { filterXSS } from "../../../../../common/util/xss"; import type { StatisticPeriod } from "../../../../../data/recorder"; +import { getPeriodicAxisLabelConfig } from "../../../../../components/chart/axis-label"; import { getSuggestedPeriod } from "../../../../../data/energy"; // Number of days of padding when showing time axis in months @@ -109,17 +110,7 @@ export function getCommonOptions( type: "time", min: subDays(start, MONTH_TIME_AXIS_PADDING), max: addDays(suggestedMax, MONTH_TIME_AXIS_PADDING), - axisLabel: { - formatter: { - year: "{yearStyle|{MMMM} {yyyy}}", - month: "{MMMM}", - }, - rich: { - yearStyle: { - fontWeight: "bold", - }, - }, - }, + axisLabel: getPeriodicAxisLabelConfig("month", locale, config), // For shorter month ranges, force splitting to ensure time axis renders // as whole month intervals. Limit the number of forced ticks to 6 months // (so a max calendar difference of 5) to reduce clutter.