Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
85 changes: 73 additions & 12 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 = false;
this.graphHeight = 100;
this.graphWidth = 500;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

this width is set but never changed again if I see this correctly. Is this fine?
In the screenshots I see graphs with different aspect ratios, and they look fine, so I guess its not an issue.
Still leaving the question here if this was intentional. Streching with preserveAspectRatio='none' may not always look great?

this is a nitpick, its probably fine

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

manual testing shows it works just fine, no weirdness, scales correctly, looks great.

}

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

this.graphHeight = 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 +132,31 @@ class MiniGraphCard extends LitElement {
}
}

checkSections() {
return this.layout === 'grid';
}

getCurrentLayout() {
Copy link
Copy Markdown
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
Copy Markdown
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) {
return this.sections && layout.grid_rows <= 3 ? 'small' : '';
}

getGraphHeightSections() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is this dead code?
I cant see any mention of it besides the definition.

It should drive this.graphHeight for sections, or it should be removed. But if sections do need dynamic height, this wire-up seams to be missing

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

this should actually be used, and not deleted.
in section view the graph kinda breaks if height in yaml is set to something very small, eg. everything below 10. the scg canvas kinda bugs out or something.

So the svg viewBox height should be based on the grid rows, instead of using the config height. This method does exactly that, it just needs to be wired it.

So in the end this is the only thing that should be fixed IMHO

const layout = this.getCurrentLayout();
const headerRows = this.getHeaderRows() + (this.getLayoutSize(layout) === '' ? 1 : 0);

return Math.max(layout.grid_rows - headerRows, 1);
}

connectedCallback() {
super.connectedCallback();
if (this.config.update_interval) {
Expand Down Expand Up @@ -181,9 +211,11 @@ class MiniGraphCard extends LitElement {
if (this.config.entities.some((_, index) => this.entity[index] === undefined)) {
return this.renderWarnings();
}
const layout = this.getCurrentLayout();
this.sections = this.checkSections();
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 @@ -438,16 +470,27 @@ class MiniGraphCard extends LitElement {
renderSvgPoint(point, i) {
const color = this.gradient[i] ? this.computeColor(point[V], i) : 'inherit';
return svg`
<circle
<g
class='line--point--group'
?inactive=${this.tooltip.index !== point[3]}
style=${`--mcg-hover: ${color};`}
@mouseover=${() => this.setTooltip(i, point[3], point[V])}
@mouseout=${() => (this.tooltip = {})}
>
<line
class='line--point--border'
x1=${point[X]} y1=${point[Y]} x2=${point[X]} y2=${point[Y]}
stroke-linecap="round" stroke-width=${this.config.line_width * 2}
stroke=${color} vector-effect="non-scaling-stroke"
/>
<line
class='line--point'
?inactive=${this.tooltip.index !== point[3]}
style=${`--mcg-hover: ${color};`}
stroke=${color}
fill=${color}
cx=${point[X]} cy=${point[Y]} r=${this.config.line_width}
@mouseover=${() => this.setTooltip(i, point[3], point[V])}
@mouseout=${() => (this.tooltip = {})}
style="stroke: var(--primary-background-color, white);"
x1=${point[X]} y1=${point[Y]} x2=${point[X]} y2=${point[Y]}
stroke-linecap="round" stroke-width=${this.config.line_width}
vector-effect="non-scaling-stroke"
/>
</g>
Comment on lines +473 to +493
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This has nothing todo with the section view. It has an impact on all kind of cards, so it should probably be in its own PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

that being said.. i dont see any issue with it in manual testing..

`;
}

Expand Down Expand Up @@ -534,7 +577,9 @@ 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}'
preserveAspectRatio='none'
@click=${e => e.stopPropagation()}>
<g>
<defs>
Expand Down Expand Up @@ -1039,6 +1084,22 @@ class MiniGraphCard extends LitElement {
}
}

getHeaderRows() {
return 0
+ ((this.config.show.name || this.config.show.icon) ? 1 : 0)
+ ((this.config.show.state) ? 1 : 0)
+ ((this.config.show.extrema || this.config.show.average) ? 1 : 0);
}

getLayoutOptions() {
return {
grid_rows: 1 + this.getHeaderRows(),
grid_columns: 2,
grid_min_rows: 1 + this.getHeaderRows(),
grid_min_columns: 2,
};
}

getCardSize() {
return 3;
}
Expand Down
43 changes: 35 additions & 8 deletions src/style.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { css } from 'lit-element';

const style = css`
:host {
display: flex;
flex-direction: column;
}
Comment on lines -4 to -7
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

was this intentional? wouldnt this possibly break the card in non section context?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

doesnt seam to break anything.. still.. intentional?

ha-card {
flex-direction: column;
flex: 1;
padding: 16px 0;
position: relative;
overflow: hidden;
height: 100%;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

this height is set for all ha-card, nut just .sections

shuldnt this be in the class below? In ha-card.sections?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

still works fine in masonry view. so this does not seam to be an issue. In that case just remove the empty css class and leave this as it is.

}
ha-card.sections {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

if height is not placed into this class, it probably has no right to exist, dont need empty css classes

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

still works fine in masonry view. so this does not seam to be an issue. In that case just remove the empty css class and leave this as it is.

}
ha-card > div {
padding: 0px 16px 16px 16px;
Expand Down Expand Up @@ -123,6 +122,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 @@ -233,7 +238,11 @@ const style = css`
left: initial;
right: 0;
}
.sections.small .state__time {
display: none;
}
.graph {
flex: auto;
align-self: flex-end;
box-sizing: border-box;
display: flex;
Expand All @@ -245,10 +254,14 @@ const style = css`
display: flex;
flex-direction: row;
position: relative;
height: 100%;
}
.graph__container__svg {
cursor: default;
flex: 1;
position: relative;
width: 100%;
height: 100%;
z-index: 0;
}
svg {
overflow: hidden;
Expand All @@ -264,6 +277,15 @@ const style = css`
.fill[anim="false"][type="fade"] {
animation: reveal-2 .25s cubic-bezier(0.215, 0.61, 0.355, 1) forwards;
}
.line {
vector-effect: non-scaling-stroke;
}
.line--point--group:hover .line--point {
visibility: hidden;
}
.line--point--group {
cursor: pointer;
}
.line--points[anim="false"],
.line[anim="false"] {
animation: pop .25s cubic-bezier(0.215, 0.61, 0.355, 1) forwards;
Expand All @@ -275,13 +297,11 @@ const style = css`
animation: none !important;
transition: all .15s !important;
}
.line--points[tooltip] .line--point[inactive] {
.line--points[tooltip] .line--point--group[inactive] {
opacity: 0;
}
.line--point {
cursor: pointer;
fill: var(--primary-background-color, white);
stroke-width: inherit;
}
.line--point:hover {
fill: var(--mcg-hover, inherit) !important;
Expand Down Expand Up @@ -336,6 +356,7 @@ const style = css`
pointer-events: none;
top: 0; bottom: 0;
opacity: .75;
z-index: 1;
}
.graph__labels > span {
cursor: pointer;
Expand All @@ -351,13 +372,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