mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 08:16:36 +00:00
Make part of the chart rendering async for large datasets (#24260)
This commit is contained in:
parent
cdd17eed2e
commit
c52217c1ce
@ -6,7 +6,6 @@ import type { DataZoomComponentOption } from "echarts/components";
|
|||||||
import type { EChartsType } from "echarts/core";
|
import type { EChartsType } from "echarts/core";
|
||||||
import type {
|
import type {
|
||||||
ECElementEvent,
|
ECElementEvent,
|
||||||
SetOptionOpts,
|
|
||||||
XAXisOption,
|
XAXisOption,
|
||||||
YAXisOption,
|
YAXisOption,
|
||||||
} from "echarts/types/dist/shared";
|
} from "echarts/types/dist/shared";
|
||||||
@ -25,6 +24,7 @@ import type { HomeAssistant } from "../../types";
|
|||||||
import { isMac } from "../../util/is_mac";
|
import { isMac } from "../../util/is_mac";
|
||||||
import "../ha-icon-button";
|
import "../ha-icon-button";
|
||||||
import { formatTimeLabel } from "./axis-label";
|
import { formatTimeLabel } from "./axis-label";
|
||||||
|
import { ensureArray } from "../../common/array/ensure-array";
|
||||||
|
|
||||||
export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000;
|
export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000;
|
||||||
|
|
||||||
@ -68,12 +68,16 @@ export class HaChartBase extends LitElement {
|
|||||||
|
|
||||||
private _listeners: (() => void)[] = [];
|
private _listeners: (() => void)[] = [];
|
||||||
|
|
||||||
|
private _originalZrFlush?: () => void;
|
||||||
|
|
||||||
public disconnectedCallback() {
|
public disconnectedCallback() {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
while (this._listeners.length) {
|
while (this._listeners.length) {
|
||||||
this._listeners.pop()!();
|
this._listeners.pop()!();
|
||||||
}
|
}
|
||||||
this.chart?.dispose();
|
this.chart?.dispose();
|
||||||
|
this.chart = undefined;
|
||||||
|
this._originalZrFlush = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public connectedCallback() {
|
public connectedCallback() {
|
||||||
@ -86,7 +90,7 @@ export class HaChartBase extends LitElement {
|
|||||||
listenMediaQuery("(prefers-reduced-motion)", (matches) => {
|
listenMediaQuery("(prefers-reduced-motion)", (matches) => {
|
||||||
if (this._reducedMotion !== matches) {
|
if (this._reducedMotion !== matches) {
|
||||||
this._reducedMotion = matches;
|
this._reducedMotion = matches;
|
||||||
this.chart?.setOption({ animation: !this._reducedMotion });
|
this._setChartOptions({ animation: !this._reducedMotion });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -96,7 +100,7 @@ export class HaChartBase extends LitElement {
|
|||||||
if ((isMac && ev.key === "Meta") || (!isMac && ev.key === "Control")) {
|
if ((isMac && ev.key === "Meta") || (!isMac && ev.key === "Control")) {
|
||||||
this._modifierPressed = true;
|
this._modifierPressed = true;
|
||||||
if (!this.options?.dataZoom) {
|
if (!this.options?.dataZoom) {
|
||||||
this.chart?.setOption({ dataZoom: this._getDataZoomConfig() });
|
this._setChartOptions({ dataZoom: this._getDataZoomConfig() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -105,7 +109,7 @@ export class HaChartBase extends LitElement {
|
|||||||
if ((isMac && ev.key === "Meta") || (!isMac && ev.key === "Control")) {
|
if ((isMac && ev.key === "Meta") || (!isMac && ev.key === "Control")) {
|
||||||
this._modifierPressed = false;
|
this._modifierPressed = false;
|
||||||
if (!this.options?.dataZoom) {
|
if (!this.options?.dataZoom) {
|
||||||
this.chart?.setOption({ dataZoom: this._getDataZoomConfig() });
|
this._setChartOptions({ dataZoom: this._getDataZoomConfig() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -131,10 +135,8 @@ export class HaChartBase extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let chartOptions: ECOption = {};
|
let chartOptions: ECOption = {};
|
||||||
const chartUpdateParams: SetOptionOpts = { lazyUpdate: true };
|
|
||||||
if (changedProps.has("data")) {
|
if (changedProps.has("data")) {
|
||||||
chartOptions.series = this.data;
|
chartOptions.series = this.data;
|
||||||
chartUpdateParams.replaceMerge = ["series"];
|
|
||||||
}
|
}
|
||||||
if (changedProps.has("options")) {
|
if (changedProps.has("options")) {
|
||||||
chartOptions = { ...chartOptions, ...this._createOptions() };
|
chartOptions = { ...chartOptions, ...this._createOptions() };
|
||||||
@ -142,7 +144,7 @@ export class HaChartBase extends LitElement {
|
|||||||
chartOptions.dataZoom = this._getDataZoomConfig();
|
chartOptions.dataZoom = this._getDataZoomConfig();
|
||||||
}
|
}
|
||||||
if (Object.keys(chartOptions).length > 0) {
|
if (Object.keys(chartOptions).length > 0) {
|
||||||
this.chart.setOption(chartOptions, chartUpdateParams);
|
this._setChartOptions(chartOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,6 +511,31 @@ export class HaChartBase extends LitElement {
|
|||||||
return Math.max(this.clientWidth / 2, 200);
|
return Math.max(this.clientWidth / 2, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _setChartOptions(options: ECOption) {
|
||||||
|
if (!this.chart) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this._originalZrFlush) {
|
||||||
|
const dataSize = ensureArray(this.data).reduce(
|
||||||
|
(acc, series) => acc + (series.data as any[]).length,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (dataSize > 10000) {
|
||||||
|
// for large datasets zr.flush takes 30-40% of the render time
|
||||||
|
// so we delay it a bit to avoid blocking the main thread
|
||||||
|
const zr = this.chart.getZr();
|
||||||
|
this._originalZrFlush = zr.flush.bind(zr);
|
||||||
|
zr.flush = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this._originalZrFlush?.();
|
||||||
|
}, 10);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const replaceMerge = options.series ? ["series"] : [];
|
||||||
|
this.chart.setOption(options, { replaceMerge });
|
||||||
|
}
|
||||||
|
|
||||||
private _handleZoomReset() {
|
private _handleZoomReset() {
|
||||||
this.chart?.dispatchAction({ type: "dataZoom", start: 0, end: 100 });
|
this.chart?.dispatchAction({ type: "dataZoom", start: 0, end: 100 });
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user