Skip to content

Commit 90334c1

Browse files
committed
Fix #132. Negative years (e.g zooming out) break fetching and rendering
Fix parsing of negative iso dates Default x axis type to date to avoid the axis defaulting to numbers when all traces are empty.
1 parent 9998e35 commit 90334c1

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

src/cache/Cache.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ export function getEntityKey(entity: EntityConfig) {
9898
}
9999
throw new Error(`Entity malformed:${JSON.stringify(entity)}`);
100100
}
101+
102+
const MIN_SAFE_TIMESTAMP = Date.parse("0001-01-02T00:00:00.000Z");
101103
export default class Cache {
102104
ranges: Record<string, TimestampRange[]> = {};
103105
histories: Record<string, EntityState[]> = {};
@@ -132,6 +134,7 @@ export default class Cache {
132134
significant_changes_only: boolean,
133135
minimal_response: boolean
134136
) {
137+
range = range.map((n) => Math.max(MIN_SAFE_TIMESTAMP, n)); // HA API can't handle negative years
135138
return (this.busy = this.busy
136139
.catch(() => {})
137140
.then(async () => {

src/plotly-graph-card.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,28 @@ export class PlotlyGraph extends HTMLElement {
263263
return [start, end + msPad];
264264
}
265265
getVisibleRange() {
266-
return this.contentEl.layout.xaxis!.range!.map((date) =>
267-
// if autoscale is used after scrolling, plotly returns the dates as numbers instead of strings
268-
Number.isFinite(date) ? date : +parseISO(date)
269-
);
266+
console.log(this.contentEl.layout.xaxis!.range);
267+
return this.contentEl.layout.xaxis!.range!.map((date) => {
268+
// if autoscale is used after scrolling, plotly returns the dates as timestamps (numbers) instead of iso strings
269+
if (Number.isFinite(date)) return date;
270+
if (date.startsWith("-")) {
271+
/*
272+
The function parseISO can't handle negative dates.
273+
To work around that, I'm parsing it without the minus, and then manually calculating the timestamp from that.
274+
The arithmetic has a twist because timestamps start on 1970 and not on year zero,
275+
so the distance to a the year zero has to be calculated by subtracting the "zero year" timestamp.
276+
positive_date = -date (which is negative)
277+
timestamp = (year 0) - (time from year 0)
278+
timestamp = (year 0) - (positive_date - year 0)
279+
timestamp = 2 * (year 0) - positive_date
280+
timestamp = 2 * (year 0) - (-date)
281+
*/
282+
return (
283+
2 * +parseISO("0000-01-01 00:00:00.000") - +parseISO(date.slice(1))
284+
);
285+
}
286+
return +parseISO(date);
287+
});
270288
}
271289
async enterBrowsingMode() {
272290
this.isBrowsing = true;

src/themed-layout.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const defaultLayout: Partial<Plotly.Layout> = {
1414
dragmode: "pan",
1515
xaxis: {
1616
autorange: false,
17+
type: "date",
1718
// automargin: true, // it makes zooming very jumpy
1819
},
1920
yaxis: {

0 commit comments

Comments
 (0)