mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Add drag to zoom & double click in echarts (#24401)
This commit is contained in:
parent
3b272ae411
commit
1fdadbf1b8
@ -31,6 +31,7 @@ import "../chips/ha-assist-chip";
|
||||
export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000;
|
||||
const LEGEND_OVERFLOW_LIMIT = 10;
|
||||
const LEGEND_OVERFLOW_LIMIT_MOBILE = 6;
|
||||
const DOUBLE_TAP_TIME = 300;
|
||||
|
||||
@customElement("ha-chart-base")
|
||||
export class HaChartBase extends LitElement {
|
||||
@ -65,6 +66,8 @@ export class HaChartBase extends LitElement {
|
||||
|
||||
private _isTouchDevice = "ontouchstart" in window;
|
||||
|
||||
private _lastTapTime?: number;
|
||||
|
||||
// @ts-ignore
|
||||
private _resizeController = new ResizeController(this, {
|
||||
callback: () => this.chart?.resize(),
|
||||
@ -110,6 +113,12 @@ export class HaChartBase extends LitElement {
|
||||
if (!this.options?.dataZoom) {
|
||||
this._setChartOptions({ dataZoom: this._getDataZoomConfig() });
|
||||
}
|
||||
// drag to zoom
|
||||
this.chart?.dispatchAction({
|
||||
type: "takeGlobalCursor",
|
||||
key: "dataZoomSelect",
|
||||
dataZoomSelectActive: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -119,6 +128,11 @@ export class HaChartBase extends LitElement {
|
||||
if (!this.options?.dataZoom) {
|
||||
this._setChartOptions({ dataZoom: this._getDataZoomConfig() });
|
||||
}
|
||||
this.chart?.dispatchAction({
|
||||
type: "takeGlobalCursor",
|
||||
key: "dataZoomSelect",
|
||||
dataZoomSelectActive: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -160,9 +174,7 @@ export class HaChartBase extends LitElement {
|
||||
return html`
|
||||
<div
|
||||
class="container ${classMap({ "has-height": !!this.height })}"
|
||||
style=${styleMap({
|
||||
height: this.height,
|
||||
})}
|
||||
style=${styleMap({ height: this.height })}
|
||||
>
|
||||
<div
|
||||
class="chart-container"
|
||||
@ -288,12 +300,22 @@ export class HaChartBase extends LitElement {
|
||||
this.chart.on("click", (e: ECElementEvent) => {
|
||||
fireEvent(this, "chart-click", e);
|
||||
});
|
||||
this.chart.on("mousemove", (e: ECElementEvent) => {
|
||||
if (e.componentType === "series" && e.componentSubType === "custom") {
|
||||
// custom series do not support cursor style so we need to set it manually
|
||||
this.chart?.getZr()?.setCursorStyle("default");
|
||||
}
|
||||
});
|
||||
this.chart.getZr().on("dblclick", this._handleClickZoom);
|
||||
if (this._isTouchDevice) {
|
||||
this.chart.getZr().on("click", (e: ECElementEvent) => {
|
||||
if (!e.zrByTouch) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
this._lastTapTime &&
|
||||
Date.now() - this._lastTapTime < DOUBLE_TAP_TIME
|
||||
) {
|
||||
this._handleClickZoom(e);
|
||||
} else {
|
||||
this._lastTapTime = Date.now();
|
||||
}
|
||||
});
|
||||
}
|
||||
this.chart.setOption({
|
||||
...this._createOptions(),
|
||||
series: this._getSeries(),
|
||||
@ -350,20 +372,12 @@ export class HaChartBase extends LitElement {
|
||||
: undefined;
|
||||
}
|
||||
return {
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
},
|
||||
axisLine: { show: false },
|
||||
splitLine: { show: true },
|
||||
...axis,
|
||||
axisLabel: {
|
||||
formatter: this._formatTimeLabel,
|
||||
rich: {
|
||||
bold: {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
},
|
||||
rich: { bold: { fontWeight: "bold" } },
|
||||
hideOverlap: true,
|
||||
...axis.axisLabel,
|
||||
},
|
||||
@ -374,14 +388,18 @@ export class HaChartBase extends LitElement {
|
||||
const options = {
|
||||
animation: !this._reducedMotion,
|
||||
darkMode: this._themes.darkMode ?? false,
|
||||
aria: {
|
||||
show: true,
|
||||
},
|
||||
aria: { show: true },
|
||||
dataZoom: this._getDataZoomConfig(),
|
||||
...this.options,
|
||||
legend: {
|
||||
show: false,
|
||||
toolbox: {
|
||||
top: Infinity,
|
||||
left: Infinity,
|
||||
feature: {
|
||||
dataZoom: { show: true, yAxisIndex: false, filterMode: "none" },
|
||||
},
|
||||
iconStyle: { opacity: 0 },
|
||||
},
|
||||
...this.options,
|
||||
legend: { show: false },
|
||||
xAxis,
|
||||
};
|
||||
|
||||
@ -413,42 +431,28 @@ export class HaChartBase extends LitElement {
|
||||
fontFamily: "Roboto, Noto, sans-serif",
|
||||
},
|
||||
title: {
|
||||
textStyle: {
|
||||
color: style.getPropertyValue("--primary-text-color"),
|
||||
},
|
||||
textStyle: { color: style.getPropertyValue("--primary-text-color") },
|
||||
subtextStyle: {
|
||||
color: style.getPropertyValue("--secondary-text-color"),
|
||||
},
|
||||
},
|
||||
line: {
|
||||
lineStyle: {
|
||||
width: 1.5,
|
||||
},
|
||||
lineStyle: { width: 1.5 },
|
||||
symbolSize: 1,
|
||||
symbol: "circle",
|
||||
smooth: false,
|
||||
},
|
||||
bar: {
|
||||
itemStyle: {
|
||||
barBorderWidth: 1.5,
|
||||
},
|
||||
},
|
||||
bar: { itemStyle: { barBorderWidth: 1.5 } },
|
||||
categoryAxis: {
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLabel: {
|
||||
show: true,
|
||||
color: style.getPropertyValue("--primary-text-color"),
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
splitArea: {
|
||||
show: false,
|
||||
@ -463,15 +467,11 @@ export class HaChartBase extends LitElement {
|
||||
valueAxis: {
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
axisTick: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
@ -479,9 +479,7 @@ export class HaChartBase extends LitElement {
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
splitArea: {
|
||||
show: false,
|
||||
@ -496,15 +494,11 @@ export class HaChartBase extends LitElement {
|
||||
logAxis: {
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
axisTick: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
@ -512,9 +506,7 @@ export class HaChartBase extends LitElement {
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
splitArea: {
|
||||
show: false,
|
||||
@ -529,15 +521,11 @@ export class HaChartBase extends LitElement {
|
||||
timeAxis: {
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
axisTick: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
@ -545,9 +533,7 @@ export class HaChartBase extends LitElement {
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
splitArea: {
|
||||
show: false,
|
||||
@ -560,9 +546,7 @@ export class HaChartBase extends LitElement {
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
textStyle: {
|
||||
color: style.getPropertyValue("--primary-text-color"),
|
||||
},
|
||||
textStyle: { color: style.getPropertyValue("--primary-text-color") },
|
||||
inactiveColor: style.getPropertyValue("--disabled-text-color"),
|
||||
pageIconColor: style.getPropertyValue("--primary-text-color"),
|
||||
pageIconInactiveColor: style.getPropertyValue("--disabled-text-color"),
|
||||
@ -578,12 +562,8 @@ export class HaChartBase extends LitElement {
|
||||
fontSize: 12,
|
||||
},
|
||||
axisPointer: {
|
||||
lineStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
crossStyle: {
|
||||
color: style.getPropertyValue("--divider-color"),
|
||||
},
|
||||
lineStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
crossStyle: { color: style.getPropertyValue("--divider-color") },
|
||||
},
|
||||
},
|
||||
timeline: {},
|
||||
@ -609,7 +589,7 @@ export class HaChartBase extends LitElement {
|
||||
}
|
||||
if (!this._originalZrFlush) {
|
||||
const dataSize = ensureArray(this.data).reduce(
|
||||
(acc, series) => acc + (series.data as any[]).length,
|
||||
(acc, series) => acc + ((series.data as any[]) || []).length,
|
||||
0
|
||||
);
|
||||
if (dataSize > 10000) {
|
||||
@ -628,6 +608,23 @@ export class HaChartBase extends LitElement {
|
||||
this.chart.setOption(options, { replaceMerge });
|
||||
}
|
||||
|
||||
private _handleClickZoom = (e: ECElementEvent) => {
|
||||
if (!this.chart) {
|
||||
return;
|
||||
}
|
||||
const range = this._isZoomed
|
||||
? [0, 100]
|
||||
: [
|
||||
(e.offsetX / this.chart.getWidth()) * 100 - 15,
|
||||
(e.offsetX / this.chart.getWidth()) * 100 + 15,
|
||||
];
|
||||
this.chart.dispatchAction({
|
||||
type: "dataZoom",
|
||||
start: range[0],
|
||||
end: range[1],
|
||||
});
|
||||
};
|
||||
|
||||
private _handleZoomReset() {
|
||||
this.chart?.dispatchAction({ type: "dataZoom", start: 0, end: 100 });
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
GridComponent,
|
||||
DataZoomComponent,
|
||||
VisualMapComponent,
|
||||
ToolboxComponent,
|
||||
} from "echarts/components";
|
||||
|
||||
// Features like Universal Transition and Label Layout
|
||||
@ -69,6 +70,7 @@ echarts.use([
|
||||
LabelLayout,
|
||||
UniversalTransition,
|
||||
CanvasRenderer,
|
||||
ToolboxComponent,
|
||||
]);
|
||||
|
||||
export default echarts;
|
||||
|
Loading…
x
Reference in New Issue
Block a user