diff --git a/src/common/color/colors.ts b/src/common/color/colors.ts index a661562eadbe..aace900bbd73 100644 --- a/src/common/color/colors.ts +++ b/src/common/color/colors.ts @@ -1,3 +1,4 @@ +import memoizeOne from "memoize-one"; import { theme2hex } from "./convert-color"; export const COLORS = [ @@ -74,3 +75,12 @@ export function getGraphColorByIndex( getColorByIndex(index); return theme2hex(themeColor); } + +export const getAllGraphColors = memoizeOne( + (style: CSSStyleDeclaration) => + COLORS.map((_color, index) => getGraphColorByIndex(index, style)), + (newArgs: [CSSStyleDeclaration], lastArgs: [CSSStyleDeclaration]) => + // this is not ideal, but we need to memoize the colors + newArgs[0].getPropertyValue("--graph-color-1") === + lastArgs[0].getPropertyValue("--graph-color-1") +); diff --git a/src/components/chart/ha-chart-base.ts b/src/components/chart/ha-chart-base.ts index 42450c8bb83e..aac85a0e01da 100644 --- a/src/components/chart/ha-chart-base.ts +++ b/src/components/chart/ha-chart-base.ts @@ -20,6 +20,7 @@ import type { ECOption } from "../../resources/echarts"; import { listenMediaQuery } from "../../common/dom/media_query"; import type { Themes } from "../../data/ws-themes"; import { themesContext } from "../../data/context"; +import { getAllGraphColors } from "../../common/color/colors"; export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000; @@ -183,10 +184,9 @@ export class HaChartBase extends LitElement { } const echarts = (await import("../../resources/echarts")).default; - this.chart = echarts.init( - container, - this._themes.darkMode ? "dark" : "light" - ); + echarts.registerTheme("custom", this._createTheme()); + + this.chart = echarts.init(container, "custom"); this.chart.on("legendselectchanged", (params: any) => { if (this.externalHidden) { const isSelected = params.selected[params.name]; @@ -237,24 +237,14 @@ export class HaChartBase extends LitElement { } private _createOptions(): ECOption { - const darkMode = this._themes.darkMode ?? false; - const options = { - backgroundColor: "transparent", animation: !this._reducedMotion, - darkMode, + darkMode: this._themes.darkMode ?? false, aria: { show: true, }, dataZoom: this._getDataZoomConfig(), ...this.options, - legend: this.options?.legend - ? { - // we should create our own theme but this is a quick fix for now - inactiveColor: darkMode ? "#444" : "#ccc", - ...this.options.legend, - } - : undefined, }; const isMobile = window.matchMedia( @@ -274,6 +264,181 @@ export class HaChartBase extends LitElement { return options; } + private _createTheme() { + const style = getComputedStyle(this); + return { + color: getAllGraphColors(style), + backgroundColor: "transparent", + textStyle: { + color: style.getPropertyValue("--primary-text-color"), + }, + title: { + textStyle: { + color: style.getPropertyValue("--primary-text-color"), + }, + subtextStyle: { + color: style.getPropertyValue("--secondary-text-color"), + }, + }, + line: { + lineStyle: { + width: 1.5, + }, + symbolSize: 1, + symbol: "circle", + smooth: false, + }, + bar: { + itemStyle: { + barBorderWidth: 1.5, + }, + }, + categoryAxis: { + axisLine: { + show: false, + }, + axisTick: { + show: false, + }, + axisLabel: { + show: true, + color: style.getPropertyValue("--primary-text-color"), + }, + splitLine: { + show: false, + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + splitArea: { + show: false, + areaStyle: { + color: [ + style.getPropertyValue("--divider-color") + "3F", + style.getPropertyValue("--divider-color") + "7F", + ], + }, + }, + }, + valueAxis: { + axisLine: { + show: true, + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + axisTick: { + show: true, + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + axisLabel: { + show: true, + color: style.getPropertyValue("--primary-text-color"), + }, + splitLine: { + show: true, + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + splitArea: { + show: false, + areaStyle: { + color: [ + style.getPropertyValue("--divider-color") + "3F", + style.getPropertyValue("--divider-color") + "7F", + ], + }, + }, + }, + logAxis: { + axisLine: { + show: true, + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + axisTick: { + show: true, + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + axisLabel: { + show: true, + color: style.getPropertyValue("--primary-text-color"), + }, + splitLine: { + show: true, + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + splitArea: { + show: false, + areaStyle: { + color: [ + style.getPropertyValue("--divider-color") + "3F", + style.getPropertyValue("--divider-color") + "7F", + ], + }, + }, + }, + timeAxis: { + axisLine: { + show: true, + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + axisTick: { + show: true, + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + axisLabel: { + show: true, + color: style.getPropertyValue("--primary-text-color"), + }, + splitLine: { + show: true, + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + splitArea: { + show: false, + areaStyle: { + color: [ + style.getPropertyValue("--divider-color") + "3F", + style.getPropertyValue("--divider-color") + "7F", + ], + }, + }, + }, + legend: { + textStyle: { + color: style.getPropertyValue("--primary-text-color"), + }, + inactiveColor: style.getPropertyValue("--disabled-text-color"), + }, + tooltip: { + axisPointer: { + lineStyle: { + color: style.getPropertyValue("--divider-color"), + }, + crossStyle: { + color: style.getPropertyValue("--divider-color"), + }, + }, + }, + timeline: {}, + }; + } + private _getDefaultHeight() { return Math.max(this.clientWidth / 2, 400); } diff --git a/src/components/chart/state-history-chart-line.ts b/src/components/chart/state-history-chart-line.ts index 9ba683cdf430..66da97fccf7d 100644 --- a/src/components/chart/state-history-chart-line.ts +++ b/src/components/chart/state-history-chart-line.ts @@ -158,9 +158,6 @@ export class StateHistoryChartLine extends LitElement { ) { const dayDifference = differenceInDays(this.endTime, this.startTime); const rtl = computeRTL(this.hass); - const splitLineStyle = this.hass.themes?.darkMode - ? { opacity: 0.15 } - : {}; this._chartOptions = { xAxis: { type: "time", @@ -176,7 +173,6 @@ export class StateHistoryChartLine extends LitElement { }, splitLine: { show: true, - lineStyle: splitLineStyle, }, minInterval: dayDifference >= 89 // quarter @@ -196,9 +192,8 @@ export class StateHistoryChartLine extends LitElement { nameTextStyle: { align: "left", }, - splitLine: { - show: true, - lineStyle: splitLineStyle, + axisLine: { + show: false, }, axisLabel: { margin: 5, diff --git a/src/components/chart/state-history-chart-timeline.ts b/src/components/chart/state-history-chart-timeline.ts index 910b4cd8d3bb..3e4962c3be8c 100644 --- a/src/components/chart/state-history-chart-timeline.ts +++ b/src/components/chart/state-history-chart-timeline.ts @@ -197,9 +197,12 @@ export class StateHistoryChartTimeline extends LitElement { max: this.endTime, axisTick: { show: true, - lineStyle: { - opacity: 0.4, - }, + }, + splitLine: { + show: false, + }, + axisLine: { + show: false, }, axisLabel: getTimeAxisLabelConfig( this.hass.locale, diff --git a/src/components/chart/state-history-charts.ts b/src/components/chart/state-history-charts.ts index b909fc1d0986..45c767cf04df 100644 --- a/src/components/chart/state-history-charts.ts +++ b/src/components/chart/state-history-charts.ts @@ -135,7 +135,7 @@ export class StateHistoryCharts extends LitElement { return html``; } if (!Array.isArray(item)) { - return html`
+ return html`