diff --git a/assets/js/components/Battery/BatteryHistoryChart.vue b/assets/js/components/Battery/BatteryHistoryChart.vue index 3ae4ff3fe..f4d8d786e 100644 --- a/assets/js/components/Battery/BatteryHistoryChart.vue +++ b/assets/js/components/Battery/BatteryHistoryChart.vue @@ -9,6 +9,7 @@ import { FONT_FAMILY, forecastXAxes, forecastYAxis, + registerTouchTooltipReset, tooltipStyle, tooltipTable, type TooltipRow, @@ -241,6 +242,7 @@ export default defineComponent({ const el = this.$refs["chartEl"] as HTMLElement; this.chart = markRaw(echarts.init(el)); this.chart.setOption(this.chartOption); + registerTouchTooltipReset(this.chart, el); this.$nextTick(() => this.updateGraphic()); window.addEventListener("resize", this.resize); // initial render done here (not via the watcher), so paging animates from the first click diff --git a/assets/js/components/Forecast/Chart.vue b/assets/js/components/Forecast/Chart.vue deleted file mode 100644 index 27f4115e1..000000000 --- a/assets/js/components/Forecast/Chart.vue +++ /dev/null @@ -1,548 +0,0 @@ - - - diff --git a/assets/js/components/Forecast/chartMixin.ts b/assets/js/components/Forecast/chartMixin.ts index d8c9cecf3..eed9f6bc2 100644 --- a/assets/js/components/Forecast/chartMixin.ts +++ b/assets/js/components/Forecast/chartMixin.ts @@ -1,5 +1,5 @@ import { defineComponent, markRaw } from "vue"; -import { echarts } from "./echarts"; +import { echarts, registerTouchTooltipReset } from "./echarts"; import "./chartStyles.css"; // chartOption is provided by each consuming component's computed @@ -63,12 +63,7 @@ export default defineComponent({ this.chart.on("hideTip", () => { this.tooltipVisible = false; }); - const resetTouch = () => { - this.chart?.dispatchAction({ type: "hideTip" }); - this.tooltipVisible = false; - }; - el.addEventListener("touchend", resetTouch); - el.addEventListener("touchcancel", resetTouch); + registerTouchTooltipReset(this.chart, el, () => (this.tooltipVisible = false)); }, }, }); diff --git a/assets/js/components/Forecast/echarts.ts b/assets/js/components/Forecast/echarts.ts index f0ed5a3b4..4cfc60f47 100644 --- a/assets/js/components/Forecast/echarts.ts +++ b/assets/js/components/Forecast/echarts.ts @@ -117,6 +117,20 @@ export function tooltipStyle( }; } +// hide tooltip when finger lifts; mouse hover unchanged +export function registerTouchTooltipReset( + chart: Pick, + el: HTMLElement, + onReset?: () => void +) { + const reset = () => { + chart.dispatchAction({ type: "hideTip" }); + onReset?.(); + }; + el.addEventListener("touchend", reset); + el.addEventListener("touchcancel", reset); +} + export interface TooltipRow { name?: string; values: string[]; diff --git a/assets/js/components/History/GroupChart.vue b/assets/js/components/History/GroupChart.vue index 1da173649..8d2951dc4 100644 --- a/assets/js/components/History/GroupChart.vue +++ b/assets/js/components/History/GroupChart.vue @@ -11,6 +11,7 @@ import { FONT_FAMILY, forecastGrid, forecastYAxis, + registerTouchTooltipReset, tooltipStyle, tooltipTable, xAxisLabelStyle, @@ -719,6 +720,7 @@ export default defineComponent({ const zr = this.chart.getZr(); zr.on("mousemove", this.onChartMouseMove); zr.on("globalout", this.clearHighlight); + registerTouchTooltipReset(this.chart, el, this.clearHighlight); this.mediaQuery = window.matchMedia("(max-width: 575.98px)"); this.isMobile = this.mediaQuery.matches; this.mediaQuery.addEventListener("change", this.onMediaChange); diff --git a/assets/js/components/Optimize/ChargeChart.vue b/assets/js/components/Optimize/ChargeChart.vue index 7b4e332c3..61d8a3613 100644 --- a/assets/js/components/Optimize/ChargeChart.vue +++ b/assets/js/components/Optimize/ChargeChart.vue @@ -37,6 +37,7 @@ import formatter from "@/mixins/formatter"; import colors from "@/colors"; import LegendList from "../Sessions/LegendList.vue"; import type { Legend } from "../Sessions/types"; +import { touchDismissPlugin } from "../Sessions/chartConfig"; ChartJS.register( CategoryScale, @@ -48,7 +49,8 @@ ChartJS.register( PointElement, Title, Tooltip, - ChartLegendPlugin + ChartLegendPlugin, + touchDismissPlugin ); export default defineComponent({ diff --git a/assets/js/components/Optimize/PriceChart.vue b/assets/js/components/Optimize/PriceChart.vue index db31b0a1a..87361b6a8 100644 --- a/assets/js/components/Optimize/PriceChart.vue +++ b/assets/js/components/Optimize/PriceChart.vue @@ -35,6 +35,7 @@ import formatter from "@/mixins/formatter"; import colors from "@/colors"; import LegendList from "../Sessions/LegendList.vue"; import type { Legend } from "../Sessions/types"; +import { touchDismissPlugin } from "../Sessions/chartConfig"; const tension = 0; @@ -46,7 +47,8 @@ ChartJS.register( PointElement, Title, Tooltip, - ChartLegendPlugin + ChartLegendPlugin, + touchDismissPlugin ); export default defineComponent({ diff --git a/assets/js/components/Optimize/SocChart.vue b/assets/js/components/Optimize/SocChart.vue index 88d8d64d7..cca83377e 100644 --- a/assets/js/components/Optimize/SocChart.vue +++ b/assets/js/components/Optimize/SocChart.vue @@ -41,8 +41,17 @@ import type { EvoptData } from "./TimeSeriesDataTable.vue"; import type { CURRENCY, BatteryDetail } from "@/types/evcc"; import formatter from "@/mixins/formatter"; import colors from "@/colors"; +import { touchDismissPlugin } from "../Sessions/chartConfig"; -ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, ChartLegendPlugin); +ChartJS.register( + CategoryScale, + LinearScale, + BarElement, + Title, + Tooltip, + ChartLegendPlugin, + touchDismissPlugin +); export default defineComponent({ name: "SocChart", diff --git a/assets/js/components/Sessions/chartConfig.ts b/assets/js/components/Sessions/chartConfig.ts index e2b09193f..f01c008b0 100644 --- a/assets/js/components/Sessions/chartConfig.ts +++ b/assets/js/components/Sessions/chartConfig.ts @@ -3,6 +3,7 @@ import { Tooltip, type ChartComponentLike, type ChartType, + type Plugin, type Point, type TooltipItem, } from "chart.js"; @@ -20,6 +21,22 @@ Chart.defaults.font.family = window Chart.defaults.font.size = 14; Chart.defaults.layout.padding = 0; +// hide tooltip when finger lifts; mouse hover unchanged +export const touchDismissPlugin: Plugin = { + id: "touchDismiss", + afterInit(chart) { + const dismiss = () => { + if (!chart.ctx) return; // destroyed + chart.setActiveElements([]); + chart.tooltip?.setActiveElements([], { x: 0, y: 0 }); + chart.update(); + }; + chart.canvas.addEventListener("touchend", dismiss); + chart.canvas.addEventListener("touchcancel", dismiss); + }, +}; +Chart.register(touchDismissPlugin); + // Custom tooltip positioners (Tooltip.positioners as any)["center"] = function () { const { chart } = this;