mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-09 01:17:48 +00:00
Show sankey chart in vertical layout on mobile (#26439)
* Show sankey chart in vertical layout on mobile * ts fix
This commit is contained in:
parent
49c7dad6eb
commit
a7db401b62
@ -387,24 +387,25 @@ export class HaChartBase extends LitElement {
|
|||||||
lastTipX = e.x;
|
lastTipX = e.x;
|
||||||
lastTipY = e.y;
|
lastTipY = e.y;
|
||||||
this.chart?.setOption({
|
this.chart?.setOption({
|
||||||
xAxis: ensureArray(this.chart?.getOption().xAxis as any).map(
|
xAxis: ensureArray(
|
||||||
(axis: XAXisOption) =>
|
(this.chart?.getOption().xAxis as any) ?? []
|
||||||
axis.show
|
).map((axis: XAXisOption) =>
|
||||||
? {
|
axis.show
|
||||||
...axis,
|
? {
|
||||||
axisPointer: {
|
...axis,
|
||||||
...axis.axisPointer,
|
axisPointer: {
|
||||||
status: "show",
|
...axis.axisPointer,
|
||||||
handle: {
|
status: "show",
|
||||||
color: style.getPropertyValue("primary-color"),
|
handle: {
|
||||||
margin: 0,
|
color: style.getPropertyValue("primary-color"),
|
||||||
size: 20,
|
margin: 0,
|
||||||
...axis.axisPointer?.handle,
|
size: 20,
|
||||||
show: true,
|
...axis.axisPointer?.handle,
|
||||||
},
|
show: true,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
: axis
|
}
|
||||||
|
: axis
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -417,21 +418,22 @@ export class HaChartBase extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.chart?.setOption({
|
this.chart?.setOption({
|
||||||
xAxis: ensureArray(this.chart?.getOption().xAxis as any).map(
|
xAxis: ensureArray(
|
||||||
(axis: XAXisOption) =>
|
(this.chart?.getOption().xAxis as any) ?? []
|
||||||
axis.show
|
).map((axis: XAXisOption) =>
|
||||||
? {
|
axis.show
|
||||||
...axis,
|
? {
|
||||||
axisPointer: {
|
...axis,
|
||||||
...axis.axisPointer,
|
axisPointer: {
|
||||||
handle: {
|
...axis.axisPointer,
|
||||||
...axis.axisPointer?.handle,
|
handle: {
|
||||||
show: false,
|
...axis.axisPointer?.handle,
|
||||||
},
|
show: false,
|
||||||
status: "hide",
|
|
||||||
},
|
},
|
||||||
}
|
status: "hide",
|
||||||
: axis
|
},
|
||||||
|
}
|
||||||
|
: axis
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
this.chart?.dispatchAction({
|
this.chart?.dispatchAction({
|
||||||
|
@ -186,14 +186,16 @@ export class HaSankeyChart extends LitElement {
|
|||||||
""
|
""
|
||||||
);
|
);
|
||||||
const wordWidth = measureTextWidth(longestWord, FONT_SIZE);
|
const wordWidth = measureTextWidth(longestWord, FONT_SIZE);
|
||||||
|
const availableWidth = params.rect.width + 6;
|
||||||
const fontSize = Math.min(
|
const fontSize = Math.min(
|
||||||
FONT_SIZE,
|
FONT_SIZE,
|
||||||
(params.rect.width / wordWidth) * FONT_SIZE
|
(availableWidth / wordWidth) * FONT_SIZE
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
fontSize: fontSize > 1 ? fontSize : 0,
|
fontSize: fontSize > 1 ? fontSize : 0,
|
||||||
width: params.rect.width,
|
width: availableWidth,
|
||||||
align: "center",
|
align: "center",
|
||||||
|
dy: -2, // shift up or the lowest row labels may be cut off
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
src/mixins/mobile-aware-mixin.ts
Normal file
34
src/mixins/mobile-aware-mixin.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import type { LitElement } from "lit";
|
||||||
|
import { state } from "lit/decorators";
|
||||||
|
import type { Constructor } from "../types";
|
||||||
|
import { isMobileClient } from "../util/is_mobile";
|
||||||
|
import { listenMediaQuery } from "../common/dom/media_query";
|
||||||
|
|
||||||
|
export const MobileAwareMixin = <T extends Constructor<LitElement>>(
|
||||||
|
superClass: T
|
||||||
|
) => {
|
||||||
|
class MobileAwareClass extends superClass {
|
||||||
|
@state() protected _isMobileSize = false;
|
||||||
|
|
||||||
|
protected _isMobileClient = isMobileClient;
|
||||||
|
|
||||||
|
private _unsubMql?: () => void;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._unsubMql = listenMediaQuery(
|
||||||
|
"all and (max-width: 450px), all and (max-height: 500px)",
|
||||||
|
(matches) => {
|
||||||
|
this._isMobileSize = matches;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._unsubMql?.();
|
||||||
|
this._unsubMql = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MobileAwareClass;
|
||||||
|
};
|
@ -23,6 +23,7 @@ import type { Link, Node } from "../../../../components/chart/ha-sankey-chart";
|
|||||||
import { getGraphColorByIndex } from "../../../../common/color/colors";
|
import { getGraphColorByIndex } from "../../../../common/color/colors";
|
||||||
import { formatNumber } from "../../../../common/number/format_number";
|
import { formatNumber } from "../../../../common/number/format_number";
|
||||||
import { getEntityContext } from "../../../../common/entity/context/get_entity_context";
|
import { getEntityContext } from "../../../../common/entity/context/get_entity_context";
|
||||||
|
import { MobileAwareMixin } from "../../../../mixins/mobile-aware-mixin";
|
||||||
|
|
||||||
const DEFAULT_CONFIG: Partial<EnergySankeyCardConfig> = {
|
const DEFAULT_CONFIG: Partial<EnergySankeyCardConfig> = {
|
||||||
group_by_floor: true,
|
group_by_floor: true,
|
||||||
@ -31,7 +32,7 @@ const DEFAULT_CONFIG: Partial<EnergySankeyCardConfig> = {
|
|||||||
|
|
||||||
@customElement("hui-energy-sankey-card")
|
@customElement("hui-energy-sankey-card")
|
||||||
class HuiEnergySankeyCard
|
class HuiEnergySankeyCard
|
||||||
extends SubscribeMixin(LitElement)
|
extends SubscribeMixin(MobileAwareMixin(LitElement))
|
||||||
implements LovelaceCard
|
implements LovelaceCard
|
||||||
{
|
{
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
@ -70,7 +71,11 @@ class HuiEnergySankeyCard
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||||
return changedProps.has("_config") || changedProps.has("_data");
|
return (
|
||||||
|
changedProps.has("_config") ||
|
||||||
|
changedProps.has("_data") ||
|
||||||
|
changedProps.has("_isMobileSize")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
@ -373,13 +378,17 @@ class HuiEnergySankeyCard
|
|||||||
|
|
||||||
const hasData = nodes.some((node) => node.value > 0);
|
const hasData = nodes.some((node) => node.value > 0);
|
||||||
|
|
||||||
|
const vertical =
|
||||||
|
this._config.layout === "vertical" ||
|
||||||
|
(this._config.layout !== "horizontal" && this._isMobileSize);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card .header=${this._config.title}>
|
<ha-card .header=${this._config.title}>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
${hasData
|
${hasData
|
||||||
? html`<ha-sankey-chart
|
? html`<ha-sankey-chart
|
||||||
.data=${{ nodes, links }}
|
.data=${{ nodes, links }}
|
||||||
.vertical=${this._config.layout === "vertical"}
|
.vertical=${vertical}
|
||||||
.valueFormatter=${this._valueFormatter}
|
.valueFormatter=${this._valueFormatter}
|
||||||
></ha-sankey-chart>`
|
></ha-sankey-chart>`
|
||||||
: html`${this.hass.localize(
|
: html`${this.hass.localize(
|
||||||
|
@ -213,7 +213,7 @@ export interface EnergyCarbonGaugeCardConfig extends EnergyCardBaseConfig {
|
|||||||
export interface EnergySankeyCardConfig extends EnergyCardBaseConfig {
|
export interface EnergySankeyCardConfig extends EnergyCardBaseConfig {
|
||||||
type: "energy-sankey";
|
type: "energy-sankey";
|
||||||
title?: string;
|
title?: string;
|
||||||
layout?: "vertical" | "horizontal";
|
layout?: "vertical" | "horizontal" | "auto";
|
||||||
group_by_floor?: boolean;
|
group_by_floor?: boolean;
|
||||||
group_by_area?: boolean;
|
group_by_area?: boolean;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user