mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Bump ChartJS to version 4 (#15531)
This commit is contained in:
parent
e06bd41b5e
commit
24dd45c8cd
@ -103,7 +103,7 @@
|
||||
"@webcomponents/scoped-custom-element-registry": "0.0.9",
|
||||
"@webcomponents/webcomponentsjs": "2.8.0",
|
||||
"app-datepicker": "5.1.1",
|
||||
"chart.js": "3.3.2",
|
||||
"chart.js": "4.3.3",
|
||||
"comlink": "4.4.1",
|
||||
"core-js": "3.32.1",
|
||||
"cropperjs": "1.6.0",
|
||||
|
@ -15,13 +15,20 @@ import { HomeAssistant } from "../../types";
|
||||
|
||||
export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000;
|
||||
|
||||
interface Tooltip extends TooltipModel<any> {
|
||||
export interface ChartResizeOptions {
|
||||
aspectRatio?: number;
|
||||
height?: number;
|
||||
width?: number;
|
||||
}
|
||||
|
||||
interface Tooltip
|
||||
extends Omit<TooltipModel<any>, "tooltipPosition" | "hasValue" | "getProps"> {
|
||||
top: string;
|
||||
left: string;
|
||||
}
|
||||
|
||||
@customElement("ha-chart-base")
|
||||
export default class HaChartBase extends LitElement {
|
||||
export class HaChartBase extends LitElement {
|
||||
public chart?: Chart;
|
||||
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@ -45,14 +52,6 @@ export default class HaChartBase extends LitElement {
|
||||
|
||||
@state() private _hiddenDatasets: Set<number> = new Set();
|
||||
|
||||
private _releaseCanvas() {
|
||||
// release the canvas memory to prevent
|
||||
// safari from running out of memory.
|
||||
if (this.chart) {
|
||||
this.chart.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public disconnectedCallback() {
|
||||
this._releaseCanvas();
|
||||
super.disconnectedCallback();
|
||||
@ -65,6 +64,36 @@ export default class HaChartBase extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
public updateChart = (
|
||||
mode:
|
||||
| "resize"
|
||||
| "reset"
|
||||
| "none"
|
||||
| "hide"
|
||||
| "show"
|
||||
| "default"
|
||||
| "active"
|
||||
| undefined
|
||||
): void => {
|
||||
this.chart?.update(mode);
|
||||
};
|
||||
|
||||
public resize = (options?: ChartResizeOptions): void => {
|
||||
if (options?.aspectRatio && !options.height) {
|
||||
options.height = Math.round(
|
||||
(options.width ?? this.clientWidth) / options.aspectRatio
|
||||
);
|
||||
} else if (options?.aspectRatio && !options.width) {
|
||||
options.width = Math.round(
|
||||
(options.height ?? this.clientHeight) * options.aspectRatio
|
||||
);
|
||||
}
|
||||
this.chart?.resize(
|
||||
options?.width ?? this.clientWidth,
|
||||
options?.height ?? this.clientHeight
|
||||
);
|
||||
};
|
||||
|
||||
protected firstUpdated() {
|
||||
this._setupChart();
|
||||
this.data.datasets.forEach((dataset, index) => {
|
||||
@ -80,14 +109,11 @@ export default class HaChartBase extends LitElement {
|
||||
if (!this.hasUpdated || !this.chart) {
|
||||
return;
|
||||
}
|
||||
if (changedProps.has("plugins")) {
|
||||
if (changedProps.has("plugins") || changedProps.has("chartType")) {
|
||||
this.chart.destroy();
|
||||
this._setupChart();
|
||||
return;
|
||||
}
|
||||
if (changedProps.has("chartType")) {
|
||||
this.chart.config.type = this.chartType;
|
||||
}
|
||||
if (changedProps.has("data")) {
|
||||
if (this._hiddenDatasets.size) {
|
||||
this.data.datasets.forEach((dataset, index) => {
|
||||
@ -131,55 +157,70 @@ export default class HaChartBase extends LitElement {
|
||||
</div>`
|
||||
: ""}
|
||||
<div
|
||||
class="chartContainer"
|
||||
class="animationContainer"
|
||||
style=${styleMap({
|
||||
height: `${this.height ?? this._chartHeight}px`,
|
||||
height: `${this.height || this._chartHeight || 0}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>
|
||||
${this._tooltip
|
||||
? html`<div
|
||||
class="chartTooltip ${classMap({ [this._tooltip.yAlign]: true })}"
|
||||
style=${styleMap({
|
||||
top: this._tooltip.top,
|
||||
left: this._tooltip.left,
|
||||
})}
|
||||
>
|
||||
<div class="title">${this._tooltip.title}</div>
|
||||
${this._tooltip.beforeBody
|
||||
? html`<div class="beforeBody">
|
||||
${this._tooltip.beforeBody}
|
||||
</div>`
|
||||
: ""}
|
||||
<div>
|
||||
<ul>
|
||||
${this._tooltip.body.map(
|
||||
(item, i) =>
|
||||
html`<li>
|
||||
<div
|
||||
class="bullet"
|
||||
style=${styleMap({
|
||||
backgroundColor: this._tooltip!.labelColors[i]
|
||||
.backgroundColor as string,
|
||||
borderColor: this._tooltip!.labelColors[i]
|
||||
.borderColor as string,
|
||||
})}
|
||||
></div>
|
||||
${item.lines.join("\n")}
|
||||
</li>`
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
${this._tooltip.footer.length
|
||||
? html`<div class="footer">
|
||||
${this._tooltip.footer.map((item) => html`${item}<br />`)}
|
||||
</div>`
|
||||
: ""}
|
||||
</div>`
|
||||
: ""}
|
||||
<div
|
||||
class="chartContainer"
|
||||
style=${styleMap({
|
||||
height: `${
|
||||
this.height ?? this._chartHeight ?? this.clientWidth / 2
|
||||
}px`,
|
||||
"padding-left": `${
|
||||
computeRTL(this.hass) ? 0 : this.paddingYAxis
|
||||
}px`,
|
||||
"padding-right": `${
|
||||
computeRTL(this.hass) ? this.paddingYAxis : 0
|
||||
}px`,
|
||||
})}
|
||||
>
|
||||
<canvas></canvas>
|
||||
${this._tooltip
|
||||
? html`<div
|
||||
class="chartTooltip ${classMap({
|
||||
[this._tooltip.yAlign]: true,
|
||||
})}"
|
||||
style=${styleMap({
|
||||
top: this._tooltip.top,
|
||||
left: this._tooltip.left,
|
||||
})}
|
||||
>
|
||||
<div class="title">${this._tooltip.title}</div>
|
||||
${this._tooltip.beforeBody
|
||||
? html`<div class="beforeBody">
|
||||
${this._tooltip.beforeBody}
|
||||
</div>`
|
||||
: ""}
|
||||
<div>
|
||||
<ul>
|
||||
${this._tooltip.body.map(
|
||||
(item, i) =>
|
||||
html`<li>
|
||||
<div
|
||||
class="bullet"
|
||||
style=${styleMap({
|
||||
backgroundColor: this._tooltip!.labelColors[i]
|
||||
.backgroundColor as string,
|
||||
borderColor: this._tooltip!.labelColors[i]
|
||||
.borderColor as string,
|
||||
})}
|
||||
></div>
|
||||
${item.lines.join("\n")}
|
||||
</li>`
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
${this._tooltip.footer.length
|
||||
? html`<div class="footer">
|
||||
${this._tooltip.footer.map((item) => html`${item}<br />`)}
|
||||
</div>`
|
||||
: ""}
|
||||
</div>`
|
||||
: ""}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@ -213,6 +254,7 @@ export default class HaChartBase extends LitElement {
|
||||
|
||||
private _createOptions() {
|
||||
return {
|
||||
maintainAspectRatio: false,
|
||||
...this.options,
|
||||
plugins: {
|
||||
...this.options?.plugins,
|
||||
@ -233,10 +275,10 @@ export default class HaChartBase extends LitElement {
|
||||
return [
|
||||
...(this.plugins || []),
|
||||
{
|
||||
id: "afterRenderHook",
|
||||
afterRender: (chart) => {
|
||||
id: "resizeHook",
|
||||
resize: (chart) => {
|
||||
const change = chart.height - (this._chartHeight ?? 0);
|
||||
if (!this._chartHeight || change > 0 || change < -12) {
|
||||
if (!this._chartHeight || change > 12 || change < -12) {
|
||||
// hysteresis to prevent infinite render loops
|
||||
this._chartHeight = chart.height;
|
||||
}
|
||||
@ -288,21 +330,13 @@ export default class HaChartBase extends LitElement {
|
||||
};
|
||||
}
|
||||
|
||||
public updateChart = (
|
||||
mode:
|
||||
| "resize"
|
||||
| "reset"
|
||||
| "none"
|
||||
| "hide"
|
||||
| "show"
|
||||
| "normal"
|
||||
| "active"
|
||||
| undefined
|
||||
): void => {
|
||||
private _releaseCanvas() {
|
||||
// release the canvas memory to prevent
|
||||
// safari from running out of memory.
|
||||
if (this.chart) {
|
||||
this.chart.update(mode);
|
||||
this.chart.destroy();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
@ -310,11 +344,14 @@ export default class HaChartBase extends LitElement {
|
||||
display: block;
|
||||
position: var(--chart-base-position, relative);
|
||||
}
|
||||
.chartContainer {
|
||||
.animationContainer {
|
||||
overflow: hidden;
|
||||
height: 0;
|
||||
transition: height 300ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
.chartContainer {
|
||||
position: relative;
|
||||
}
|
||||
canvas {
|
||||
max-height: var(--chart-max-height, 400px);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { ChartData, ChartDataset, ChartOptions } from "chart.js";
|
||||
import { html, LitElement, PropertyValues } from "lit";
|
||||
import { property, state } from "lit/decorators";
|
||||
import { property, query, state } from "lit/decorators";
|
||||
import { getGraphColorByIndex } from "../../common/color/colors";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { computeRTL } from "../../common/util/compute_rtl";
|
||||
@ -11,14 +11,18 @@ import {
|
||||
} from "../../common/number/format_number";
|
||||
import { LineChartEntity, LineChartState } from "../../data/history";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { MIN_TIME_BETWEEN_UPDATES } from "./ha-chart-base";
|
||||
import {
|
||||
ChartResizeOptions,
|
||||
HaChartBase,
|
||||
MIN_TIME_BETWEEN_UPDATES,
|
||||
} from "./ha-chart-base";
|
||||
|
||||
const safeParseFloat = (value) => {
|
||||
const parsed = parseFloat(value);
|
||||
return isFinite(parsed) ? parsed : null;
|
||||
};
|
||||
|
||||
class StateHistoryChartLine extends LitElement {
|
||||
export class StateHistoryChartLine extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public data: LineChartEntity[] = [];
|
||||
@ -47,6 +51,12 @@ class StateHistoryChartLine extends LitElement {
|
||||
|
||||
private _chartTime: Date = new Date();
|
||||
|
||||
@query("ha-chart-base") private _chart?: HaChartBase;
|
||||
|
||||
public resize = (options?: ChartResizeOptions): void => {
|
||||
this._chart?.resize(options);
|
||||
};
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<ha-chart-base
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { ChartData, ChartDataset, ChartOptions } from "chart.js";
|
||||
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { formatDateTimeWithSeconds } from "../../common/datetime/format_date_time";
|
||||
import millisecondsToDuration from "../../common/datetime/milliseconds_to_duration";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
@ -8,7 +8,11 @@ import { numberFormatToLocale } from "../../common/number/format_number";
|
||||
import { computeRTL } from "../../common/util/compute_rtl";
|
||||
import { TimelineEntity } from "../../data/history";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { MIN_TIME_BETWEEN_UPDATES } from "./ha-chart-base";
|
||||
import {
|
||||
ChartResizeOptions,
|
||||
HaChartBase,
|
||||
MIN_TIME_BETWEEN_UPDATES,
|
||||
} from "./ha-chart-base";
|
||||
import type { TimeLineData } from "./timeline-chart/const";
|
||||
import { computeTimelineColor } from "./timeline-chart/timeline-color";
|
||||
|
||||
@ -46,6 +50,12 @@ export class StateHistoryChartTimeline extends LitElement {
|
||||
|
||||
private _chartTime: Date = new Date();
|
||||
|
||||
@query("ha-chart-base") private _chart?: HaChartBase;
|
||||
|
||||
public resize = (options?: ChartResizeOptions): void => {
|
||||
this._chart?.resize(options);
|
||||
};
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<ha-chart-base
|
||||
|
@ -6,7 +6,13 @@ import {
|
||||
nothing,
|
||||
PropertyValues,
|
||||
} from "lit";
|
||||
import { customElement, eventOptions, property, state } from "lit/decorators";
|
||||
import {
|
||||
customElement,
|
||||
eventOptions,
|
||||
property,
|
||||
queryAll,
|
||||
state,
|
||||
} from "lit/decorators";
|
||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||
import { restoreScroll } from "../../common/decorators/restore-scroll";
|
||||
import {
|
||||
@ -18,6 +24,9 @@ import { loadVirtualizer } from "../../resources/virtualizer";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import "./state-history-chart-line";
|
||||
import "./state-history-chart-timeline";
|
||||
import type { StateHistoryChartLine } from "./state-history-chart-line";
|
||||
import type { StateHistoryChartTimeline } from "./state-history-chart-timeline";
|
||||
import { ChartResizeOptions } from "./ha-chart-base";
|
||||
|
||||
const CANVAS_TIMELINE_ROWS_CHUNK = 10; // Split up the canvases to avoid hitting the render limit
|
||||
|
||||
@ -75,6 +84,16 @@ export class StateHistoryCharts extends LitElement {
|
||||
// @ts-ignore
|
||||
@restoreScroll(".container") private _savedScrollPos?: number;
|
||||
|
||||
@queryAll("state-history-chart-line, state-history-chart-timeline")
|
||||
private _charts?: StateHistoryChartLine[] | StateHistoryChartTimeline[];
|
||||
|
||||
public resize = (options?: ChartResizeOptions): void => {
|
||||
this._charts?.forEach(
|
||||
(chart: StateHistoryChartLine | StateHistoryChartTimeline) =>
|
||||
chart.resize(options)
|
||||
);
|
||||
};
|
||||
|
||||
protected render() {
|
||||
if (!isComponentLoaded(this.hass, "history")) {
|
||||
return html`<div class="info">
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { customElement, property, state, query } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { getGraphColorByIndex } from "../../common/color/colors";
|
||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||
@ -31,6 +31,7 @@ import {
|
||||
} from "../../data/recorder";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import "./ha-chart-base";
|
||||
import type { ChartResizeOptions, HaChartBase } from "./ha-chart-base";
|
||||
|
||||
export const supportedStatTypeMap: Record<StatisticType, StatisticType> = {
|
||||
mean: "mean",
|
||||
@ -42,7 +43,7 @@ export const supportedStatTypeMap: Record<StatisticType, StatisticType> = {
|
||||
};
|
||||
|
||||
@customElement("statistics-chart")
|
||||
class StatisticsChart extends LitElement {
|
||||
export class StatisticsChart extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public statisticsData?: Statistics;
|
||||
@ -75,8 +76,14 @@ class StatisticsChart extends LitElement {
|
||||
|
||||
@state() private _chartOptions?: ChartOptions;
|
||||
|
||||
@query("ha-chart-base") private _chart?: HaChartBase;
|
||||
|
||||
private _computedStyle?: CSSStyleDeclaration;
|
||||
|
||||
public resize = (options?: ChartResizeOptions): void => {
|
||||
this._chart?.resize(options);
|
||||
};
|
||||
|
||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||
return changedProps.size > 1 || !changedProps.has("hass");
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
import type {
|
||||
BarControllerChartOptions,
|
||||
BarControllerDatasetOptions,
|
||||
} from "chart.js";
|
||||
|
||||
export interface TimeLineData {
|
||||
start: Date;
|
||||
end: Date;
|
||||
|
@ -16,7 +16,7 @@ export interface TextBaroptions extends BarOptions {
|
||||
export class TextBarElement extends BarElement {
|
||||
static id = "textbar";
|
||||
|
||||
draw(ctx) {
|
||||
draw(ctx: CanvasRenderingContext2D) {
|
||||
super.draw(ctx);
|
||||
const options = this.options as TextBaroptions;
|
||||
const { x, y, base, width, text } = (
|
||||
|
@ -2,6 +2,95 @@ import { BarController, BarElement } from "chart.js";
|
||||
import { TimeLineData } from "./const";
|
||||
import { TextBarProps } from "./textbar-element";
|
||||
|
||||
function borderProps(properties) {
|
||||
let reverse;
|
||||
let start;
|
||||
let end;
|
||||
let top;
|
||||
let bottom;
|
||||
if (properties.horizontal) {
|
||||
reverse = properties.base > properties.x;
|
||||
start = "left";
|
||||
end = "right";
|
||||
} else {
|
||||
reverse = properties.base < properties.y;
|
||||
start = "bottom";
|
||||
end = "top";
|
||||
}
|
||||
if (reverse) {
|
||||
top = "end";
|
||||
bottom = "start";
|
||||
} else {
|
||||
top = "start";
|
||||
bottom = "end";
|
||||
}
|
||||
return { start, end, reverse, top, bottom };
|
||||
}
|
||||
|
||||
function setBorderSkipped(properties, options, stack, index) {
|
||||
let edge = options.borderSkipped;
|
||||
const res = {};
|
||||
|
||||
if (!edge) {
|
||||
properties.borderSkipped = res;
|
||||
return;
|
||||
}
|
||||
|
||||
if (edge === true) {
|
||||
properties.borderSkipped = {
|
||||
top: true,
|
||||
right: true,
|
||||
bottom: true,
|
||||
left: true,
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const { start, end, reverse, top, bottom } = borderProps(properties);
|
||||
|
||||
if (edge === "middle" && stack) {
|
||||
properties.enableBorderRadius = true;
|
||||
if ((stack._top || 0) === index) {
|
||||
edge = top;
|
||||
} else if ((stack._bottom || 0) === index) {
|
||||
edge = bottom;
|
||||
} else {
|
||||
res[parseEdge(bottom, start, end, reverse)] = true;
|
||||
edge = top;
|
||||
}
|
||||
}
|
||||
|
||||
res[parseEdge(edge, start, end, reverse)] = true;
|
||||
properties.borderSkipped = res;
|
||||
}
|
||||
|
||||
function parseEdge(edge, a, b, reverse) {
|
||||
if (reverse) {
|
||||
edge = swap(edge, a, b);
|
||||
edge = startEnd(edge, b, a);
|
||||
} else {
|
||||
edge = startEnd(edge, a, b);
|
||||
}
|
||||
return edge;
|
||||
}
|
||||
|
||||
function swap(orig, v1, v2) {
|
||||
return orig === v1 ? v2 : orig === v2 ? v1 : orig;
|
||||
}
|
||||
|
||||
function startEnd(v, start, end) {
|
||||
return v === "start" ? start : v === "end" ? end : v;
|
||||
}
|
||||
|
||||
function setInflateAmount(
|
||||
properties,
|
||||
{ inflateAmount }: { inflateAmount?: string | number },
|
||||
ratio
|
||||
) {
|
||||
properties.inflateAmount =
|
||||
inflateAmount === "auto" ? (ratio === 1 ? 0.33 : 0) : inflateAmount;
|
||||
}
|
||||
|
||||
function parseValue(entry, item, vScale, i) {
|
||||
const startValue = vScale.parse(entry.start, i);
|
||||
const endValue = vScale.parse(entry.end, i);
|
||||
@ -97,7 +186,7 @@ export class TimelineController extends BarController {
|
||||
bars: BarElement[],
|
||||
start: number,
|
||||
count: number,
|
||||
mode: "reset" | "resize" | "none" | "hide" | "show" | "normal" | "active"
|
||||
mode: "reset" | "resize" | "none" | "hide" | "show" | "default" | "active"
|
||||
) {
|
||||
const vScale = this._cachedMeta.vScale!;
|
||||
const iScale = this._cachedMeta.iScale!;
|
||||
@ -114,15 +203,15 @@ export class TimelineController extends BarController {
|
||||
for (let index = start; index < start + count; index++) {
|
||||
const data = dataset.data[index] as TimeLineData;
|
||||
|
||||
// @ts-ignore
|
||||
const y = vScale.getPixelForValue(this.index);
|
||||
|
||||
// @ts-ignore
|
||||
const xStart = iScale.getPixelForValue(data.start.getTime());
|
||||
// @ts-ignore
|
||||
const xEnd = iScale.getPixelForValue(data.end.getTime());
|
||||
const width = xEnd - xStart;
|
||||
|
||||
const parsed = this.getParsed(index);
|
||||
const stack = (parsed._stacks || {})[vScale.axis];
|
||||
|
||||
const height = 10;
|
||||
|
||||
const properties: TextBarProps = {
|
||||
@ -145,7 +234,10 @@ export class TimelineController extends BarController {
|
||||
backgroundColor: data.color,
|
||||
};
|
||||
}
|
||||
const options = properties.options || bars[index].options;
|
||||
|
||||
setBorderSkipped(properties, options, stack, index);
|
||||
setInflateAmount(properties, options, 1);
|
||||
this.updateElement(bars[index], index, properties as any, mode);
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ import {
|
||||
mdiPencilOutline,
|
||||
} from "@mdi/js";
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import { css, html, LitElement, nothing, PropertyValues } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { LitElement, PropertyValues, css, html, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { cache } from "lit/directives/cache";
|
||||
import { dynamicElement } from "../../common/dom/dynamic-element-directive";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
@ -38,15 +38,17 @@ import { haStyleDialog } from "../../resources/styles";
|
||||
import "../../state-summary/state-card-content";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import {
|
||||
computeShowHistoryComponent,
|
||||
computeShowLogBookComponent,
|
||||
DOMAINS_WITH_MORE_INFO,
|
||||
EDITABLE_DOMAINS_WITH_ID,
|
||||
EDITABLE_DOMAINS_WITH_UNIQUE_ID,
|
||||
computeShowHistoryComponent,
|
||||
computeShowLogBookComponent,
|
||||
} from "./const";
|
||||
import "./controls/more-info-default";
|
||||
import "./ha-more-info-history-and-logbook";
|
||||
import type { MoreInfoHistoryAndLogbook } from "./ha-more-info-history-and-logbook";
|
||||
import "./ha-more-info-info";
|
||||
import type { MoreInfoInfo } from "./ha-more-info-info";
|
||||
import "./ha-more-info-settings";
|
||||
import "./more-info-content";
|
||||
|
||||
@ -91,6 +93,9 @@ export class MoreInfoDialog extends LitElement {
|
||||
|
||||
@state() private _infoEditMode = false;
|
||||
|
||||
@query("ha-more-info-info, ha-more-info-history-and-logbook")
|
||||
private _history?: MoreInfoInfo | MoreInfoHistoryAndLogbook;
|
||||
|
||||
public showDialog(params: MoreInfoDialogParams) {
|
||||
this._entityId = params.entityId;
|
||||
if (!this._entityId) {
|
||||
@ -263,6 +268,7 @@ export class MoreInfoDialog extends LitElement {
|
||||
<ha-dialog
|
||||
open
|
||||
@closed=${this.closeDialog}
|
||||
@opened=${this._handleOpened}
|
||||
.heading=${title}
|
||||
hideActions
|
||||
flexContent
|
||||
@ -485,6 +491,10 @@ export class MoreInfoDialog extends LitElement {
|
||||
this.large = !this.large;
|
||||
}
|
||||
|
||||
private _handleOpened() {
|
||||
this._history?.resize({ aspectRatio: 2 });
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
haStyleDialog,
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { css, CSSResultGroup, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import { ChartResizeOptions } from "../../components/chart/ha-chart-base";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import {
|
||||
computeShowHistoryComponent,
|
||||
computeShowLogBookComponent,
|
||||
} from "./const";
|
||||
import "./ha-more-info-history";
|
||||
import type { MoreInfoHistory } from "./ha-more-info-history";
|
||||
import "./ha-more-info-logbook";
|
||||
|
||||
@customElement("ha-more-info-history-and-logbook")
|
||||
@ -14,6 +16,13 @@ export class MoreInfoHistoryAndLogbook extends LitElement {
|
||||
|
||||
@property() public entityId!: string;
|
||||
|
||||
@query("ha-more-info-history")
|
||||
private _history?: MoreInfoHistory;
|
||||
|
||||
public resize(options?: ChartResizeOptions) {
|
||||
this._history?.resize(options);
|
||||
}
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
${computeShowHistoryComponent(this.hass, this.entityId)
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { startOfYesterday, subHours } from "date-fns/esm";
|
||||
import { css, html, LitElement, PropertyValues, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { customElement, property, state, query } from "lit/decorators";
|
||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { computeDomain } from "../../common/entity/compute_domain";
|
||||
import { createSearchParam } from "../../common/url/search-params";
|
||||
import "../../components/chart/state-history-charts";
|
||||
import type { StateHistoryCharts } from "../../components/chart/state-history-charts";
|
||||
import "../../components/chart/statistics-chart";
|
||||
import {
|
||||
computeHistory,
|
||||
@ -20,6 +21,8 @@ import {
|
||||
StatisticsTypes,
|
||||
} from "../../data/recorder";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import type { StatisticsChart } from "../../components/chart/statistics-chart";
|
||||
import { ChartResizeOptions } from "../../components/chart/ha-chart-base";
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
@ -51,12 +54,22 @@ export class MoreInfoHistory extends LitElement {
|
||||
|
||||
private _metadata?: Record<string, StatisticsMetaData>;
|
||||
|
||||
@query("statistics-chart, state-history-charts") private _chart?:
|
||||
| StateHistoryCharts
|
||||
| StatisticsChart;
|
||||
|
||||
public resize = (options?: ChartResizeOptions): void => {
|
||||
if (this._chart) {
|
||||
this._chart.resize(options);
|
||||
}
|
||||
};
|
||||
|
||||
protected render() {
|
||||
if (!this.entityId) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html` ${isComponentLoaded(this.hass, "history")
|
||||
return html`${isComponentLoaded(this.hass, "history")
|
||||
? html`<div class="header">
|
||||
<div class="title">
|
||||
${this.hass.localize("ui.dialogs.more_info_control.history")}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import { computeDomain } from "../../common/entity/compute_domain";
|
||||
import { ChartResizeOptions } from "../../components/chart/ha-chart-base";
|
||||
import { ExtEntityRegistryEntry } from "../../data/entity_registry";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import {
|
||||
@ -12,6 +13,7 @@ import {
|
||||
DOMAINS_WITH_MORE_INFO,
|
||||
} from "./const";
|
||||
import "./ha-more-info-history";
|
||||
import type { MoreInfoHistory } from "./ha-more-info-history";
|
||||
import "./ha-more-info-logbook";
|
||||
import "./more-info-content";
|
||||
|
||||
@ -25,6 +27,13 @@ export class MoreInfoInfo extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public editMode?: boolean;
|
||||
|
||||
@query("ha-more-info-history")
|
||||
private _history?: MoreInfoHistory;
|
||||
|
||||
public resize(options?: ChartResizeOptions) {
|
||||
this._history?.resize(options);
|
||||
}
|
||||
|
||||
protected render() {
|
||||
const entityId = this.entityId;
|
||||
const stateObj = this.hass.states[entityId] as HassEntity | undefined;
|
||||
|
@ -19,7 +19,7 @@ import {
|
||||
numberFormatToLocale,
|
||||
} from "../../../../common/number/format_number";
|
||||
import "../../../../components/chart/ha-chart-base";
|
||||
import type HaChartBase from "../../../../components/chart/ha-chart-base";
|
||||
import type { HaChartBase } from "../../../../components/chart/ha-chart-base";
|
||||
import "../../../../components/ha-card";
|
||||
import { EnergyData, getEnergyDataCollection } from "../../../../data/energy";
|
||||
import {
|
||||
|
19
yarn.lock
19
yarn.lock
@ -2039,6 +2039,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@kurkle/color@npm:^0.3.0":
|
||||
version: 0.3.2
|
||||
resolution: "@kurkle/color@npm:0.3.2"
|
||||
checksum: 79e97b31f8f6efb28c69d373f94b0c7480226fe8ec95221f518ac998e156444a496727ce47de6d728eb5c3369288e794cba82cae34253deb0d472d3bfe080e49
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@leichtgewicht/ip-codec@npm:^2.0.1":
|
||||
version: 2.0.4
|
||||
resolution: "@leichtgewicht/ip-codec@npm:2.0.4"
|
||||
@ -6570,10 +6577,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chart.js@npm:3.3.2":
|
||||
version: 3.3.2
|
||||
resolution: "chart.js@npm:3.3.2"
|
||||
checksum: 0aaebab52cb5eacfc969210f7c304cad7e20b03a37b33f4e0332b5eeb9319e2929b085e0a8654ec33752566a55982ffe6bb3f2ba620c2a9b3bc71806ca7b9cb7
|
||||
"chart.js@npm:4.3.3":
|
||||
version: 4.3.3
|
||||
resolution: "chart.js@npm:4.3.3"
|
||||
dependencies:
|
||||
"@kurkle/color": ^0.3.0
|
||||
checksum: 548605fc0a0a64fdc591a41159a2be86c1b408339d6e57b566c04dc157331b003db285a6139801d1700596acde8f0521bc6a156da29388025581619db6600073
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -9720,7 +9729,7 @@ __metadata:
|
||||
babel-loader: 9.1.3
|
||||
babel-plugin-template-html-minifier: 4.1.0
|
||||
chai: 4.3.8
|
||||
chart.js: 3.3.2
|
||||
chart.js: 4.3.3
|
||||
comlink: 4.4.1
|
||||
core-js: 3.32.1
|
||||
cropperjs: 1.6.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user