diff --git a/assets/js/components/Forecast/Co2Chart.vue b/assets/js/components/Forecast/Co2Chart.vue
index 438098327..ea688deea 100644
--- a/assets/js/components/Forecast/Co2Chart.vue
+++ b/assets/js/components/Forecast/Co2Chart.vue
@@ -118,10 +118,3 @@ export default defineComponent({
},
});
-
-
diff --git a/assets/js/components/Forecast/PriceChart.vue b/assets/js/components/Forecast/PriceChart.vue
index 14a99622e..00298fa81 100644
--- a/assets/js/components/Forecast/PriceChart.vue
+++ b/assets/js/components/Forecast/PriceChart.vue
@@ -131,8 +131,8 @@ export default defineComponent({
? { opacity: 0.33 }
: undefined,
})),
- barMaxWidth: 4,
- barMinWidth: 4,
+ barMaxWidth: 2,
+ barMinWidth: 2,
itemStyle: {
color: priceColor,
borderRadius: 2,
@@ -164,10 +164,3 @@ export default defineComponent({
},
});
-
-
diff --git a/assets/js/components/Forecast/SolarChart.vue b/assets/js/components/Forecast/SolarChart.vue
index bd13a76d9..528279bef 100644
--- a/assets/js/components/Forecast/SolarChart.vue
+++ b/assets/js/components/Forecast/SolarChart.vue
@@ -129,10 +129,3 @@ export default defineComponent({
},
});
-
-
diff --git a/assets/js/components/Forecast/chartMixin.ts b/assets/js/components/Forecast/chartMixin.ts
index 4df452935..d8c9cecf3 100644
--- a/assets/js/components/Forecast/chartMixin.ts
+++ b/assets/js/components/Forecast/chartMixin.ts
@@ -1,5 +1,6 @@
import { defineComponent, markRaw } from "vue";
import { echarts } from "./echarts";
+import "./chartStyles.css";
// chartOption is provided by each consuming component's computed
type WithChartOption = { chartOption: Record };
@@ -62,6 +63,12 @@ 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);
},
},
});
diff --git a/assets/js/components/Forecast/chartStyles.css b/assets/js/components/Forecast/chartStyles.css
new file mode 100644
index 000000000..5b9f3e23e
--- /dev/null
+++ b/assets/js/components/Forecast/chartStyles.css
@@ -0,0 +1,7 @@
+.forecast-chart-scroll {
+ overflow-x: auto;
+ padding-bottom: 4px;
+ user-select: none;
+ -webkit-user-select: none;
+ -webkit-touch-callout: none;
+}
diff --git a/assets/js/components/Forecast/echarts.ts b/assets/js/components/Forecast/echarts.ts
index d8f61a122..d56556b54 100644
--- a/assets/js/components/Forecast/echarts.ts
+++ b/assets/js/components/Forecast/echarts.ts
@@ -51,7 +51,7 @@ export function markPointLabel(
return {
animation: true,
- clip: false,
+ clip: true,
symbol: "rect",
symbolSize: 1,
label: {
@@ -76,11 +76,12 @@ export function tooltipStyle(
getChart?: () => { convertToPixel: echarts.ECharts["convertToPixel"] } | null
) {
return {
+ confine: true,
backgroundColor: color,
borderColor: color,
borderWidth: 0,
padding: [5, 10],
- extraCssText: "box-shadow: none; border-radius: 4px; text-align: center;",
+ extraCssText: "box-shadow: none; border-radius: 4px; text-align: center; z-index: 1000;",
position(
point: [number, number],
params: { value: [string, number] }[] | { value: [string, number] },
@@ -110,7 +111,7 @@ export function tooltipStyle(
}
export function forecastGrid() {
- return { top: 36, right: 16, bottom: 4, left: 48, borderWidth: 0 };
+ return { top: 36, right: 16, bottom: 4, left: 34, borderWidth: 0 };
}
export function forecastXAxes(startDate: Date, endDate: Date, weekdayShort: (d: Date) => string) {
@@ -129,7 +130,7 @@ export function forecastXAxes(startDate: Date, endDate: Date, weekdayShort: (d:
formatter: (value: number) => {
const date = new Date(value);
const h = date.getHours();
- if (h % 2 !== 0) return "";
+ if (h % 4 !== 0) return "";
if (h === 0) return `${h}\n${weekdayShort(date)}`;
return `${h}`;
},
@@ -171,7 +172,8 @@ export function forecastYAxis(overrides: Record = {}) {
lineStyle: { color: colors.border || "" },
},
axisLabel: {
- fontSize: 14,
+ fontSize: 10,
+ opacity: 0.5,
...(axisLabel as Record),
},
...rest,
@@ -188,7 +190,7 @@ export function filterForecastSlots(
endDate: Date
): ForecastSlot[] {
if (!Array.isArray(slots)) return [];
- return slots.filter((s) => new Date(s.end) >= startDate && new Date(s.start) <= endDate);
+ return slots.filter((s) => new Date(s.end) > startDate && new Date(s.start) <= endDate);
}
export function minSlotIndex(slots: ForecastSlot[]): number {
diff --git a/assets/js/views/Forecast.vue b/assets/js/views/Forecast.vue
index 65d4f6d65..2410839d4 100644
--- a/assets/js/views/Forecast.vue
+++ b/assets/js/views/Forecast.vue
@@ -157,7 +157,7 @@ import store from "../store";
import { adjustedSolar, ForecastType } from "@/utils/forecast";
import type { ForecastSlot } from "../components/Forecast/types";
-const MIN_HOURS = 38;
+const MIN_HOURS = 76;
const MAX_HOURS = 96;
const SLOTS_PER_HOUR = 4;
@@ -219,7 +219,7 @@ export default defineComponent({
chartWidth(): number {
const ms = this.chartEndDate.getTime() - this.startDate.getTime();
const slots = Math.ceil(ms / (15 * 60 * 1000));
- return slots * 8 + 56;
+ return slots * 4 + 56;
},
currency() {
return store.state?.currency;
@@ -242,7 +242,10 @@ export default defineComponent({
: this.forecast.solar;
},
solarAdjustText() {
- return this.$t("forecast.solarAdjustShort");
+ const text = this.$t("forecast.solarAdjustShort");
+ const scale = this.forecast.solar?.scale || 1;
+ const percentDiff = scale * 100 - 100;
+ return `${text} (${this.fmtPercentage(percentDiff, 0, true)})`;
},
solarSubtitle(): string {
const s = this.solar;