Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: sections support #1139

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.yaml
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ globals:
window: true
Event: true
customElements: true
document: true
135 changes: 131 additions & 4 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class MiniGraphCard extends LitElement {
this.stateChanged = false;
this.initial = true;
this._md5Config = undefined;
this.sections = this.checkSections();
this.graphHeight = 100;
this.graphWidth = 500;
}

static get styles() {
Expand Down Expand Up @@ -105,12 +108,17 @@ class MiniGraphCard extends LitElement {
this._md5Config = SparkMD5.hash(JSON.stringify(this.config));
const entitiesChanged = !compareArray(this.config.entities || [], config.entities);

const layout = this.getCurrentLayout();

this.graphWidth = this.sections ? layout.grid_columns * 120 : 500;
this.graphHeight = this.sections ? this.getGraphHeightSections() * 56 : this.config.height;

if (!this.Graph || entitiesChanged) {
if (this._hass) this.hass = this._hass;
this.Graph = this.config.entities.map(
entity => new Graph(
500,
this.config.height,
this.graphWidth,
this.graphHeight,
[this.config.show.fill ? 0 : this.config.line_width, this.config.line_width],
this.config.hours_to_show,
this.config.points_per_hour,
Expand All @@ -127,6 +135,68 @@ class MiniGraphCard extends LitElement {
}
}

checkSections() {
let root = document.querySelector('home-assistant');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really the best way to check for the view layout? The main frontend suggests, there might be this.layout?

See here: https://github.com/home-assistant/frontend/blob/67217b9dd0f5ad43aafb3bba2fe2821407b25243/src/panels/lovelace/cards/hui-entity-card.ts#L139

Also, maybe this.options.layout_options will only defined in sections view?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.layout does not seem to be defined when the graphs are created in getConfig. I could try to modify graphs height in render as it seems that this.layout is defined there.

As for the this.options.layout_options there could be a situation where user copies card to a different dashboard that is not necessarily a sections but maybe I am overthinking.

root = root && root.shadowRoot;
root = root && root.querySelector('home-assistant-main');
root = root && root.shadowRoot;
root = root && root.querySelector('ha-drawer');
root = root && root.querySelector('partial-panel-resolver');
root = root && root.shadowRoot || root;
root = root && root.querySelector('ha-panel-lovelace');
root = root && root.shadowRoot;
root = root && root.querySelector('hui-root');
if (root) {
const ll = root.lovelace;
ll.current_view = root.___curView;
const panelType = ll.rawConfig.views[ll.current_view].type;
return panelType === 'sections';
}
return false;
}

getCurrentLayout() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder: isn't this taken care of by home assistant? If we report a minimum row count via getLayoutOptions, shouldn't this be reflected in this.config.layout_options?

See also here, maybe: https://github.com/home-assistant/frontend/blob/67217b9dd0f5ad43aafb3bba2fe2821407b25243/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts#L68

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it only clamps the values for setting the card size and for the visual editor, values set by user in this.config.layout_options stays untouched even when they're lower than minimum set in getLayoutOptions.

const layout = this.getLayoutOptions();
const layoutConfigured = this.config.layout_options !== undefined;
const columns = Math.max(layoutConfigured
? this.config.layout_options.grid_columns : layout.grid_columns, layout.grid_min_columns);
const rows = Math.max(layoutConfigured
? this.config.layout_options.grid_rows : layout.grid_rows, layout.grid_min_rows);
return { grid_columns: columns, grid_rows: rows };
}

getLayoutSize(layout) {
if (!this.sections) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reduce?

return this.sections && layout.grid_rows === 2 ? 'small' : '';

And if that is enough, maybe remove the function and do the logic in the render directly... (Because it seems used only once.)

return '';
}
if (layout.grid_rows === 2) {
return 'small';
}
return '';
}

getGraphHeightSections() {
akloeckner marked this conversation as resolved.
Show resolved Hide resolved
const layout = this.getCurrentLayout();
if (!this.config.show.name
&& !this.config.show.state
&& !this.config.show.icon
&& this.config.show.extrema) {
return Math.max(layout.grid_rows - 1, 1);
}
if (!this.config.show.name
&& !this.config.show.state
&& !this.config.show.icon) {
return layout.grid_rows;
}
if (this.config.show.extrema) {
return Math.max(layout.grid_rows - 3, 1);
}
if (layout.grid_rows >= 3) {
return Math.max(layout.grid_rows - 2, 1);
}
return Math.max(layout.grid_rows - 1, 1);
}

connectedCallback() {
super.connectedCallback();
if (this.config.update_interval) {
Expand Down Expand Up @@ -181,9 +251,10 @@ class MiniGraphCard extends LitElement {
if (this.config.entities.some((_, index) => this.entity[index] === undefined)) {
return this.renderWarnings();
}
const layout = this.getCurrentLayout();
return html`
<ha-card
class="flex"
class="flex ${this.sections ? 'sections' : ''} ${this.getLayoutSize(layout)}"
?group=${config.group}
?fill=${config.show.graph && config.show.fill}
?points=${config.show.points === 'hover'}
Expand Down Expand Up @@ -509,7 +580,7 @@ class MiniGraphCard extends LitElement {
renderSvg() {
const { height } = this.config;
return svg`
<svg width='100%' height=${height !== 0 ? '100%' : 0} viewBox='0 0 500 ${height}'
<svg width='100%' height=${height !== 0 || this.sections ? '100%' : 0} viewBox='0 0 ${this.graphWidth} ${this.graphHeight}'
akloeckner marked this conversation as resolved.
Show resolved Hide resolved
@click=${e => e.stopPropagation()}>
<g>
<defs>
Expand Down Expand Up @@ -1014,6 +1085,62 @@ class MiniGraphCard extends LitElement {
}
}

getLayoutOptions() {
akloeckner marked this conversation as resolved.
Show resolved Hide resolved
if (!this.config.show.state
&& this.config.show.extrema) {
return {
grid_rows: 2,
grid_columns: 2,
grid_min_rows: 3,
grid_min_columns: 2,
};
}
if (!this.config.show.name
&& !this.config.show.state
&& !this.config.show.icon) {
return {
grid_rows: 2,
grid_columns: 2,
grid_min_rows: 1,
grid_min_columns: 2,
};
}
if (!this.config.show.name
&& !this.config.show.state
&& !this.config.show.icon
&& this.config.show.extrema) {
return {
grid_rows: 2,
grid_columns: 2,
grid_min_rows: 2,
grid_min_columns: 2,
};
}
if (this.config.show.extrema
&& !this.config.show.fill) {
return {
grid_rows: 5,
grid_columns: 2,
grid_min_rows: 5,
grid_min_columns: 2,
};
}
if (this.config.show.extrema) {
return {
grid_rows: 4,
grid_columns: 2,
grid_min_rows: 4,
grid_min_columns: 2,
};
}
return {
grid_rows: 2,
grid_columns: 2,
grid_min_rows: 2,
grid_min_columns: 2,
};
}

getCardSize() {
return 3;
}
Expand Down
26 changes: 26 additions & 0 deletions src/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ const style = css`
position: relative;
overflow: hidden;
}
ha-card.sections {
akloeckner marked this conversation as resolved.
Show resolved Hide resolved
min-height: calc((var(--row-size, 1)*(var(--row-height) + var(--row-gap))) - var(--row-gap));
max-height: calc((var(--row-size, 1)*(var(--row-height) + var(--row-gap))) - var(--row-gap));
}
ha-card > div {
padding: 0px 16px 16px 16px;
}
Expand Down Expand Up @@ -49,6 +53,9 @@ const style = css`
order: -1;
padding: 0 16px 8px 16px;
}
ha-card[fill].sections .graph__legend {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do the margins and paddings need tweaking? If it's kind of a refactor but yields the same layout, let's consider to change this also in non-section view to keep consistency.

padding: 0 16px 0px 16px;
}
ha-card[fill] .info {
padding-bottom: 16px;
}
Expand Down Expand Up @@ -120,6 +127,12 @@ const style = css`
justify-content: space-between;
flex-wrap: nowrap;
}
.sections.small .states {
padding: 0px 16px 0px 16px;
}
.sections.small .header {
padding: 0px 16px 0px 16px;
}
.states .icon {
align-self: center;
margin-left: 0;
Expand Down Expand Up @@ -230,6 +243,9 @@ const style = css`
left: initial;
right: 0;
}
.sections.small .state__time {
display: none;
}
.graph {
align-self: flex-end;
box-sizing: border-box;
Expand All @@ -238,6 +254,10 @@ const style = css`
margin-top: auto;
width: 100%;
}
.sections .graph {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, too: if this is useful also in non-section views, let's consider to just add it to the regular styles.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is only useful for section view. It makes graph position itself so that it's not clipping out of bounds.

position: absolute;
bottom: 0;
}
.graph__container {
display: flex;
flex-direction: row;
Expand Down Expand Up @@ -348,13 +368,19 @@ const style = css`
padding-top: 16px;
flex-wrap: wrap;
}
.sections .graph__legend {
padding-top: 8px;
}
.graph__legend__item {
cursor: pointer;
display: flex;
min-width: 0;
margin: .4em;
align-items: center
}
.sections .graph__legend__item {
margin: .4em .4em 0px .4em;
}
.graph__legend__item span {
opacity: .75;
margin-left: .4em;
Expand Down