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;