mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Vertically align history charts on left axis (#14919)
Co-authored-by: Bram Kragten <mail@bramkragten.nl> fixes undefined
This commit is contained in:
parent
06368a6f0e
commit
00667f1296
@ -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>
|
||||
|
@ -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: {
|
||||
|
@ -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",
|
||||
},
|
||||
},
|
||||
|
@ -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 ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user