Optimizer chart: day boundaries with weekday at 00:00 (#32894)
This commit is contained in:
parent
d22b67fd18
commit
ba8596be96
3 changed files with 54 additions and 5 deletions
|
|
@ -146,7 +146,7 @@ export default defineComponent({
|
|||
...tooltipStyle(colors.text || ""),
|
||||
formatter: this.tooltipFormatter,
|
||||
},
|
||||
xAxis: slotXAxis(this.times),
|
||||
xAxis: slotXAxis(this.times, this.weekdayShort),
|
||||
yAxis: forecastYAxis({
|
||||
min: undefined,
|
||||
position: "right",
|
||||
|
|
|
|||
35
assets/js/components/Optimize/chart.test.ts
Normal file
35
assets/js/components/Optimize/chart.test.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import { describe, expect, test } from "vite-plus/test";
|
||||
import { isMidnight, slotXAxis } from "./chart";
|
||||
|
||||
// 15min slots starting at the given local hour
|
||||
function times(startHour: number, count: number): number[] {
|
||||
const start = new Date(2025, 0, 1, startHour).getTime();
|
||||
return Array.from({ length: count }, (_, i) => start + i * 15 * 60 * 1000);
|
||||
}
|
||||
|
||||
describe("slotXAxis", () => {
|
||||
const weekdayShort = () => "Thu";
|
||||
// 20:00 to 08:00, midnight at index 16
|
||||
const slots = times(20, 48);
|
||||
const axis = slotXAxis(slots, weekdayShort);
|
||||
const label = (i: number) => axis.axisLabel.formatter(String(slots[i]));
|
||||
|
||||
test("labels full hours only", () => {
|
||||
expect(label(0)).toBe("20"); // 20:00
|
||||
expect(label(1)).toBe(""); // 20:15
|
||||
expect(label(4)).toBe(""); // 21:00, not a step hour
|
||||
expect(label(32)).toBe("4"); // 04:00
|
||||
});
|
||||
|
||||
test("shows the weekday at midnight", () => {
|
||||
expect(label(16)).toBe("0\nThu");
|
||||
});
|
||||
|
||||
test("draws a split line at day boundaries only", () => {
|
||||
expect(isMidnight(slots[16])).toBe(true);
|
||||
expect(axis.splitLine.interval(16)).toBe(true);
|
||||
expect(axis.splitLine.interval(15)).toBe(false);
|
||||
// no line at the axis start, even if the first slot is midnight
|
||||
expect(slotXAxis(times(0, 4), weekdayShort).splitLine.interval(0)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import { xAxisLabelStyle } from "../Forecast/echarts";
|
||||
import colors from "@/colors";
|
||||
import type { BatteryDetail } from "@/types/evcc";
|
||||
|
||||
// loadpoint part of a vehicle entry title: "Carport (blue e-Golf)" → "Carport"
|
||||
|
|
@ -19,22 +20,35 @@ export function slotTimes(timestamp: string, dt: number[]): number[] {
|
|||
return res;
|
||||
}
|
||||
|
||||
// category x axis over slot times, labels at full hours every 4h (6h on mobile)
|
||||
export function slotXAxis(times: number[]) {
|
||||
export function isMidnight(time?: number): boolean {
|
||||
if (time === undefined) return false;
|
||||
const d = new Date(time);
|
||||
return d.getHours() === 0 && d.getMinutes() === 0;
|
||||
}
|
||||
|
||||
// category x axis over slot times, labels at full hours every 4h (6h on mobile),
|
||||
// day boundaries as split line with the weekday shown at 00:00
|
||||
export function slotXAxis(times: number[], weekdayShort: (d: Date) => string) {
|
||||
const step = window.innerWidth < 576 ? 6 : 4;
|
||||
return {
|
||||
type: "category",
|
||||
data: times.map(String),
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
splitLine: { show: false },
|
||||
splitLine: {
|
||||
show: true,
|
||||
// split lines sit at the left edge of their slot
|
||||
interval: (index: number) => index > 0 && isMidnight(times[index]),
|
||||
lineStyle: { color: colors.muted || "", type: "solid" },
|
||||
},
|
||||
axisLabel: {
|
||||
...xAxisLabelStyle(),
|
||||
interval: 0,
|
||||
formatter: (value: string) => {
|
||||
const d = new Date(Number(value));
|
||||
if (d.getMinutes() !== 0 || d.getHours() % step !== 0) return "";
|
||||
return String(d.getHours());
|
||||
const label = String(d.getHours());
|
||||
return d.getHours() === 0 ? `${label}\n${weekdayShort(d)}` : label;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue