Vertically align history charts on left axis (#14919)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
fixes undefined
This commit is contained in:
karwosts 2023-01-25 07:42:20 -08:00 committed by GitHub
parent 06368a6f0e
commit 00667f1296
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 0 deletions

View File

@ -10,6 +10,8 @@ import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
import { clamp } from "../../common/number/clamp";
import { computeRTL } from "../../common/util/compute_rtl";
import { HomeAssistant } from "../../types";
export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000;
@ -22,6 +24,8 @@ interface Tooltip extends TooltipModel<any> {
export default class HaChartBase extends LitElement {
public chart?: Chart;
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: "chart-type", reflect: true })
public chartType: ChartType = "line";
@ -33,6 +37,8 @@ export default class HaChartBase extends LitElement {
@property({ type: Number }) public height?: number;
@property({ type: Number }) public paddingYAxis = 0;
@state() private _chartHeight?: number;
@state() private _tooltip?: Tooltip;
@ -128,6 +134,8 @@ export default class HaChartBase extends LitElement {
style=${styleMap({
height: `${this.height ?? this._chartHeight}px`,
overflow: this._chartHeight ? "initial" : "hidden",
"padding-left": `${computeRTL(this.hass) ? 0 : this.paddingYAxis}px`,
"padding-right": `${computeRTL(this.hass) ? this.paddingYAxis : 0}px`,
})}
>
<canvas></canvas>

View File

@ -2,6 +2,8 @@ import type { ChartData, ChartDataset, ChartOptions } from "chart.js";
import { html, LitElement, PropertyValues } from "lit";
import { property, state } from "lit/decorators";
import { getGraphColorByIndex } from "../../common/color/colors";
import { fireEvent } from "../../common/dom/fire_event";
import { computeRTL } from "../../common/util/compute_rtl";
import {
formatNumber,
numberFormatToLocale,
@ -30,17 +32,25 @@ class StateHistoryChartLine extends LitElement {
@property({ attribute: false }) public endTime!: Date;
@property({ type: Number }) public paddingYAxis = 0;
@property({ type: Number }) public chartIndex?;
@state() private _chartData?: ChartData<"line">;
@state() private _chartOptions?: ChartOptions;
@state() private _yWidth = 0;
private _chartTime: Date = new Date();
protected render() {
return html`
<ha-chart-base
.hass=${this.hass}
.data=${this._chartData}
.options=${this._chartOptions}
.paddingYAxis=${this.paddingYAxis - this._yWidth}
chart-type="line"
></ha-chart-base>
`;
@ -84,6 +94,16 @@ class StateHistoryChartLine extends LitElement {
display: true,
text: this.unit,
},
afterUpdate: (y) => {
if (this._yWidth !== Math.floor(y.width)) {
this._yWidth = Math.floor(y.width);
fireEvent(this, "y-width-changed", {
value: this._yWidth,
chartIndex: this.chartIndex,
});
}
},
position: computeRTL(this.hass) ? "right" : "left",
},
},
plugins: {

View File

@ -2,6 +2,7 @@ import type { ChartData, ChartDataset, ChartOptions } from "chart.js";
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
import { customElement, property, state } from "lit/decorators";
import { formatDateTimeWithSeconds } from "../../common/datetime/format_date_time";
import { fireEvent } from "../../common/dom/fire_event";
import { numberFormatToLocale } from "../../common/number/format_number";
import { computeRTL } from "../../common/util/compute_rtl";
import { TimelineEntity } from "../../data/history";
@ -32,18 +33,26 @@ export class StateHistoryChartTimeline extends LitElement {
@property({ attribute: false }) public endTime!: Date;
@property({ type: Number }) public paddingYAxis = 0;
@property({ type: Number }) public chartIndex?;
@state() private _chartData?: ChartData<"timeline">;
@state() private _chartOptions?: ChartOptions<"timeline">;
@state() private _yWidth = 0;
private _chartTime: Date = new Date();
protected render() {
return html`
<ha-chart-base
.hass=${this.hass}
.data=${this._chartData}
.options=${this._chartOptions}
.height=${this.data.length * 30 + 30}
.paddingYAxis=${this.paddingYAxis - this._yWidth}
chart-type="timeline"
></ha-chart-base>
`;
@ -131,6 +140,15 @@ export class StateHistoryChartTimeline extends LitElement {
scaleInstance.width = narrow ? 105 : 185;
}
},
afterUpdate: (y) => {
if (this._yWidth !== Math.floor(y.width)) {
this._yWidth = Math.floor(y.width);
fireEvent(this, "y-width-changed", {
value: this._yWidth,
chartIndex: this.chartIndex,
});
}
},
position: computeRTL(this.hass) ? "right" : "left",
},
},

View File

@ -31,6 +31,12 @@ const chunkData = (inputArray: any[], chunks: number) =>
return results;
}, []);
declare global {
interface HASSDomEvents {
"y-width-changed": { value: number; chartIndex: number };
}
}
@customElement("state-history-charts")
class StateHistoryCharts extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -56,6 +62,12 @@ class StateHistoryCharts extends LitElement {
@state() private _computedEndTime!: Date;
@state() private _maxYWidth = 0;
@state() private _childYWidths: number[] = [];
@state() private _chartCount = 0;
// @ts-ignore
@restoreScroll(".container") private _savedScrollPos?: number;
@ -99,6 +111,8 @@ class StateHistoryCharts extends LitElement {
).concat(this.historyData.line)
: this.historyData.line;
this._chartCount = combinedItems.length;
return this.virtualize
? html`<div class="container ha-scrollbar" @scroll=${this._saveScrollPos}>
<lit-virtualizer
@ -130,7 +144,10 @@ class StateHistoryCharts extends LitElement {
.identifier=${item.identifier}
.showNames=${this.showNames}
.endTime=${this._computedEndTime}
.paddingYAxis=${this._maxYWidth}
.names=${this.names}
.chartIndex=${index}
@y-width-changed=${this._yWidthChanged}
></state-history-chart-line>
</div> `;
}
@ -144,6 +161,9 @@ class StateHistoryCharts extends LitElement {
.names=${this.names}
.narrow=${this.narrow}
.chunked=${this.virtualize}
.paddingYAxis=${this._maxYWidth}
.chartIndex=${index}
@y-width-changed=${this._yWidthChanged}
></state-history-chart-timeline>
</div> `;
};
@ -152,6 +172,21 @@ class StateHistoryCharts extends LitElement {
return !(changedProps.size === 1 && changedProps.has("hass"));
}
protected updated(changedProps: PropertyValues) {
if (changedProps.has("_chartCount")) {
if (this._chartCount < this._childYWidths.length) {
this._childYWidths.length = this._chartCount;
this._maxYWidth =
this._childYWidths.length === 0 ? 0 : Math.max(...this._childYWidths);
}
}
}
private _yWidthChanged(e: CustomEvent<HASSDomEvents["y-width-changed"]>) {
this._childYWidths[e.detail.chartIndex] = e.detail.value;
this._maxYWidth = Math.max(...this._childYWidths);
}
private _isHistoryEmpty(): boolean {
const historyDataEmpty =
!this.historyData ||