From 9dfa15beaec1ff66f2b592156545b7f124e54bac Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Thu, 12 Dec 2024 12:59:58 +0100 Subject: [PATCH 01/16] feat: add grid lines --- README.md | 1 + src/main.js | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index de2e2a3..d4c2a95 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,7 @@ We recommend looking at the [Example usage section](#example-usage) to understan | state_map | [state map object](#state-map-object) | | v0.8.0 | List of entity states to convert (order matters as position becomes a value on the graph). | value_factor | number | 0 | v0.9.4 | Scale value by order of magnitude (e.g. convert Watts to kilo Watts), use negative value to scale down. | logarithmic | boolean | `false` | v0.10.0 | Use a Logarithmic scale for the graph +| grid_line_type | string | | v0.12.x | Show grids lines using `hour` / `day` / `week` and the value of hours_to_show #### Entities object diff --git a/src/main.js b/src/main.js index 46496c4..804b9fc 100644 --- a/src/main.js +++ b/src/main.js @@ -507,11 +507,12 @@ class MiniGraphCard extends LitElement { } renderSvg() { - const { height } = this.config; + const { height, grid_line_type = false } = this.config; return svg` e.stopPropagation()}> + ${grid_line_type ? this.renderGridLines() : ''} ${this.renderSvgGradient(this.gradient)} @@ -525,6 +526,40 @@ class MiniGraphCard extends LitElement { `; } + renderGridLines() { + const { + height, hours_to_show, grid_line_type, line_width, + } = this.config; + + const containerWidth = 500; + let numLines; + let xRatio; + + switch (grid_line_type) { + case 'hour': + default: + numLines = hours_to_show; + xRatio = containerWidth / numLines; + break; + case 'day': + numLines = Math.round(hours_to_show / 24); + xRatio = (containerWidth / numLines); + break; + case 'week': + numLines = Math.round(hours_to_show / 168); + xRatio = containerWidth / numLines; + break; + } + const lines = []; + + for (let i = 0.5; i < numLines; i += 1) { + const x = xRatio * i; + lines.push(svg``); + } + + return lines; + } + setTooltip(entity, index, value, label = null) { const { group_by, From e875f7c296b34f5e6965372e753b02bbb76e02c5 Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Thu, 12 Dec 2024 13:16:21 +0100 Subject: [PATCH 02/16] style: better looking grid lines --- src/main.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main.js b/src/main.js index 804b9fc..a068c81 100644 --- a/src/main.js +++ b/src/main.js @@ -528,7 +528,7 @@ class MiniGraphCard extends LitElement { renderGridLines() { const { - height, hours_to_show, grid_line_type, line_width, + height, hours_to_show, grid_line_type, } = this.config; const containerWidth = 500; @@ -552,9 +552,13 @@ class MiniGraphCard extends LitElement { } const lines = []; - for (let i = 0.5; i < numLines; i += 1) { - const x = xRatio * i; - lines.push(svg``); + for (let i = 0; i < numLines; i += 1) { + const x = xRatio * (i + 0.5); + if (i % 2 === 0) { + lines.push(svg``); + } else { + lines.push(svg``); + } } return lines; From 70105efafa2bad314c3caf7660af9b02769a8b0d Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 13 Dec 2024 10:15:04 +0100 Subject: [PATCH 03/16] refactor: move grid_line_type to show options & add 5minute variant --- README.md | 3 +-- src/main.js | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d4c2a95..e88226c 100644 --- a/README.md +++ b/README.md @@ -115,8 +115,6 @@ We recommend looking at the [Example usage section](#example-usage) to understan | state_map | [state map object](#state-map-object) | | v0.8.0 | List of entity states to convert (order matters as position becomes a value on the graph). | value_factor | number | 0 | v0.9.4 | Scale value by order of magnitude (e.g. convert Watts to kilo Watts), use negative value to scale down. | logarithmic | boolean | `false` | v0.10.0 | Use a Logarithmic scale for the graph -| grid_line_type | string | | v0.12.x | Show grids lines using `hour` / `day` / `week` and the value of hours_to_show - #### Entities object Entities may be listed directly (as per `sensor.temperature` in the example below), or defined using @@ -169,6 +167,7 @@ All properties are optional. | labels_secondary | `hover` | `true` / `false` / `hover` | Display secondary Y-axis labels. | name_adaptive_color | `false` | `true` / `false` | Make the name color adapt with the primary entity color. | icon_adaptive_color | `false` | `true` / `false` | Make the icon color adapt with the primary entity color. +| grid_line_type | string | | v0.12.x | Show grids lines using `5minute` / `hour` / `day` / `week` and the value of hours_to_show #### Line color object See [dynamic line color](#dynamic-line-color) for example usage. diff --git a/src/main.js b/src/main.js index a068c81..6dbc187 100644 --- a/src/main.js +++ b/src/main.js @@ -507,7 +507,8 @@ class MiniGraphCard extends LitElement { } renderSvg() { - const { height, grid_line_type = false } = this.config; + const { height, show } = this.config; + const grid_line_type = show.grid_line_type ? show.grid_line_type : false; return svg` e.stopPropagation()}> @@ -528,28 +529,32 @@ class MiniGraphCard extends LitElement { renderGridLines() { const { - height, hours_to_show, grid_line_type, + height, hours_to_show, show, } = this.config; + const grid_line_type = show.grid_line_type ? show.grid_line_type : false; const containerWidth = 500; let numLines; - let xRatio; + + let rounded_hours_to_show = Math.round(hours_to_show); + if (rounded_hours_to_show < 1) rounded_hours_to_show = 1; switch (grid_line_type) { + case '5minute': + numLines = rounded_hours_to_show * 12; + break; case 'hour': default: - numLines = hours_to_show; - xRatio = containerWidth / numLines; + numLines = rounded_hours_to_show; break; case 'day': - numLines = Math.round(hours_to_show / 24); - xRatio = (containerWidth / numLines); + numLines = Math.round(rounded_hours_to_show / 24); break; case 'week': - numLines = Math.round(hours_to_show / 168); - xRatio = containerWidth / numLines; + numLines = Math.round(rounded_hours_to_show / 168); break; } + const xRatio = containerWidth / numLines; const lines = []; for (let i = 0; i < numLines; i += 1) { From 5956678a6dc37ec8b9880edd4cb2a47f8791460f Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 13 Dec 2024 10:28:27 +0100 Subject: [PATCH 04/16] style: use ha variable color & let user decide thick / thin lines frequency --- README.md | 3 ++- src/main.js | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e88226c..7c233de 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,8 @@ All properties are optional. | labels_secondary | `hover` | `true` / `false` / `hover` | Display secondary Y-axis labels. | name_adaptive_color | `false` | `true` / `false` | Make the name color adapt with the primary entity color. | icon_adaptive_color | `false` | `true` / `false` | Make the icon color adapt with the primary entity color. -| grid_line_type | string | | v0.12.x | Show grids lines using `5minute` / `hour` / `day` / `week` and the value of hours_to_show +| grid_line_type | `hour` | `5minute` / `hour` / `day` / `week` | Show grids lines using and the value of hours_to_show. +| grid_line_frequency | 2 | | Define the frequecy of thin / thick lines you want. #### Line color object See [dynamic line color](#dynamic-line-color) for example usage. diff --git a/src/main.js b/src/main.js index 6dbc187..7abbfa0 100644 --- a/src/main.js +++ b/src/main.js @@ -532,6 +532,7 @@ class MiniGraphCard extends LitElement { height, hours_to_show, show, } = this.config; const grid_line_type = show.grid_line_type ? show.grid_line_type : false; + const grid_line_frequency = show.grid_line_frequency ? show.grid_line_frequency : 2; const containerWidth = 500; let numLines; @@ -559,10 +560,10 @@ class MiniGraphCard extends LitElement { for (let i = 0; i < numLines; i += 1) { const x = xRatio * (i + 0.5); - if (i % 2 === 0) { - lines.push(svg``); + if (i % grid_line_frequency > 0) { + lines.push(svg``); } else { - lines.push(svg``); + lines.push(svg``); } } From 6e6492bb30eec43fca9dde6fc1630fe0d165190f Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 13 Dec 2024 10:36:09 +0100 Subject: [PATCH 05/16] fix: redundant stroke --- src/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.js b/src/main.js index 7abbfa0..ac79cf5 100644 --- a/src/main.js +++ b/src/main.js @@ -561,9 +561,9 @@ class MiniGraphCard extends LitElement { for (let i = 0; i < numLines; i += 1) { const x = xRatio * (i + 0.5); if (i % grid_line_frequency > 0) { - lines.push(svg``); + lines.push(svg``); } else { - lines.push(svg``); + lines.push(svg``); } } From 9dd491a2eab37e443146cfa99f3bc82ac48906fe Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 13 Dec 2024 10:46:26 +0100 Subject: [PATCH 06/16] update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7c233de..9607e49 100644 --- a/README.md +++ b/README.md @@ -167,8 +167,8 @@ All properties are optional. | labels_secondary | `hover` | `true` / `false` / `hover` | Display secondary Y-axis labels. | name_adaptive_color | `false` | `true` / `false` | Make the name color adapt with the primary entity color. | icon_adaptive_color | `false` | `true` / `false` | Make the icon color adapt with the primary entity color. -| grid_line_type | `hour` | `5minute` / `hour` / `day` / `week` | Show grids lines using and the value of hours_to_show. -| grid_line_frequency | 2 | | Define the frequecy of thin / thick lines you want. +| grid_line_type | `hour` | `5minute` / `hour` / `day` / `week` | Show grid lines in function of hours_to_show value. +| grid_line_frequency | 2 | | Grid lines: thin / thick lines amount ratio. #### Line color object See [dynamic line color](#dynamic-line-color) for example usage. From cdc74515fc430522b2858beef6baebc712ef7a9a Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 13 Dec 2024 11:06:22 +0100 Subject: [PATCH 07/16] feat: safety check on grid lines ratio & update readme --- README.md | 4 ++-- src/main.js | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9607e49..1650516 100644 --- a/README.md +++ b/README.md @@ -167,8 +167,8 @@ All properties are optional. | labels_secondary | `hover` | `true` / `false` / `hover` | Display secondary Y-axis labels. | name_adaptive_color | `false` | `true` / `false` | Make the name color adapt with the primary entity color. | icon_adaptive_color | `false` | `true` / `false` | Make the icon color adapt with the primary entity color. -| grid_line_type | `hour` | `5minute` / `hour` / `day` / `week` | Show grid lines in function of hours_to_show value. -| grid_line_frequency | 2 | | Grid lines: thin / thick lines amount ratio. +| grid_lines_type | `hour` | `5minute` / `hour` / `day` / `week` | Show grid lines in function of hours_to_show value. +| grid_lines_ratio | 2 | | Show grid lines dependently on `hours_to_show` value. #### Line color object See [dynamic line color](#dynamic-line-color) for example usage. diff --git a/src/main.js b/src/main.js index ac79cf5..06d76a3 100644 --- a/src/main.js +++ b/src/main.js @@ -508,12 +508,12 @@ class MiniGraphCard extends LitElement { renderSvg() { const { height, show } = this.config; - const grid_line_type = show.grid_line_type ? show.grid_line_type : false; + const grid_lines_type = show.grid_lines_type ? show.grid_lines_type : false; return svg` e.stopPropagation()}> - ${grid_line_type ? this.renderGridLines() : ''} + ${grid_lines_type ? this.renderGridLines() : ''} ${this.renderSvgGradient(this.gradient)} @@ -531,8 +531,10 @@ class MiniGraphCard extends LitElement { const { height, hours_to_show, show, } = this.config; - const grid_line_type = show.grid_line_type ? show.grid_line_type : false; - const grid_line_frequency = show.grid_line_frequency ? show.grid_line_frequency : 2; + const grid_lines_type = show.grid_lines_type ? show.grid_lines_type : false; + const grid_lines_ratio = (show.grid_lines_ratio && Number.isInteger(show.grid_lines_ratio)) + ? show.grid_lines_ratio + : 2; const containerWidth = 500; let numLines; @@ -540,7 +542,7 @@ class MiniGraphCard extends LitElement { let rounded_hours_to_show = Math.round(hours_to_show); if (rounded_hours_to_show < 1) rounded_hours_to_show = 1; - switch (grid_line_type) { + switch (grid_lines_type) { case '5minute': numLines = rounded_hours_to_show * 12; break; @@ -560,7 +562,7 @@ class MiniGraphCard extends LitElement { for (let i = 0; i < numLines; i += 1) { const x = xRatio * (i + 0.5); - if (i % grid_line_frequency > 0) { + if (i % grid_lines_ratio > 0) { lines.push(svg``); } else { lines.push(svg``); From d905261d07511cdd5424009cd9d4810bd71e4253 Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 13 Dec 2024 11:15:00 +0100 Subject: [PATCH 08/16] fix readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1650516..19a4ccf 100644 --- a/README.md +++ b/README.md @@ -167,8 +167,8 @@ All properties are optional. | labels_secondary | `hover` | `true` / `false` / `hover` | Display secondary Y-axis labels. | name_adaptive_color | `false` | `true` / `false` | Make the name color adapt with the primary entity color. | icon_adaptive_color | `false` | `true` / `false` | Make the icon color adapt with the primary entity color. -| grid_lines_type | `hour` | `5minute` / `hour` / `day` / `week` | Show grid lines in function of hours_to_show value. -| grid_lines_ratio | 2 | | Show grid lines dependently on `hours_to_show` value. +| grid_lines_type | `hour` | `5minute` / `hour` / `day` / `week` | Show grid lines dependently on `hours_to_show` value. +| grid_lines_ratio | 2 | | Grid lines: thin / thick lines amount ratio #### Line color object See [dynamic line color](#dynamic-line-color) for example usage. From a95079618d4b8b4559776be0fbd3c7546051f4bb Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 13 Dec 2024 11:22:39 +0100 Subject: [PATCH 09/16] style: better grid lines customizability --- src/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.js b/src/main.js index 06d76a3..dcc8b3f 100644 --- a/src/main.js +++ b/src/main.js @@ -563,9 +563,9 @@ class MiniGraphCard extends LitElement { for (let i = 0; i < numLines; i += 1) { const x = xRatio * (i + 0.5); if (i % grid_lines_ratio > 0) { - lines.push(svg``); + lines.push(svg``); } else { - lines.push(svg``); + lines.push(svg``); } } From 8d47c1ce847bbd116206cc3faa64ed673161d336 Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 13 Dec 2024 14:47:13 +0100 Subject: [PATCH 10/16] style: better classes & doc --- README.md | 4 +++- src/main.js | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 19a4ccf..82932c2 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ All properties are optional. | name_adaptive_color | `false` | `true` / `false` | Make the name color adapt with the primary entity color. | icon_adaptive_color | `false` | `true` / `false` | Make the icon color adapt with the primary entity color. | grid_lines_type | `hour` | `5minute` / `hour` / `day` / `week` | Show grid lines dependently on `hours_to_show` value. -| grid_lines_ratio | 2 | | Grid lines: thin / thick lines amount ratio +| grid_lines_ratio | 2 | | Grid lines: thin / thick lines amount ratio (0 - no thin lines) #### Line color object See [dynamic line color](#dynamic-line-color) for example usage. @@ -260,6 +260,8 @@ The following theme variables can be set in your HA theme to customize the appea |------|:-------:|-------------| | mcg-title-letter-spacing | | Letter spacing of the card title (`name` option). | mcg-title-font-weight | 500 | Font weight of the card title. +| mcg-grid-line-thick-color | rgb(from var(--divider-color) R G B /0.5) | Grid "thick" line color. +| mcg-grid-line-thin-color | var(--divider-color) | Grid "thin" line color. ### Example usage diff --git a/src/main.js b/src/main.js index dcc8b3f..dd46a7f 100644 --- a/src/main.js +++ b/src/main.js @@ -563,9 +563,9 @@ class MiniGraphCard extends LitElement { for (let i = 0; i < numLines; i += 1) { const x = xRatio * (i + 0.5); if (i % grid_lines_ratio > 0) { - lines.push(svg``); + lines.push(svg``); } else { - lines.push(svg``); + lines.push(svg``); } } From abbddebf162dcc303b780f6b56bd69a827f1aa95 Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Sat, 14 Dec 2024 01:10:50 +0100 Subject: [PATCH 11/16] refactor: render grid lines algo from ildar170975 --- src/main.js | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/main.js b/src/main.js index dd46a7f..42aa427 100644 --- a/src/main.js +++ b/src/main.js @@ -537,32 +537,35 @@ class MiniGraphCard extends LitElement { : 2; const containerWidth = 500; - let numLines; - - let rounded_hours_to_show = Math.round(hours_to_show); - if (rounded_hours_to_show < 1) rounded_hours_to_show = 1; + let spanInHours; switch (grid_lines_type) { case '5minute': - numLines = rounded_hours_to_show * 12; + spanInHours = 1 / 12; break; case 'hour': default: - numLines = rounded_hours_to_show; + spanInHours = 1; break; case 'day': - numLines = Math.round(rounded_hours_to_show / 24); + spanInHours = 24; break; case 'week': - numLines = Math.round(rounded_hours_to_show / 168); - break; + spanInHours = 168; } - const xRatio = containerWidth / numLines; + + let numLines = hours_to_show / spanInHours; + const spanFactor = Math.ceil(hours_to_show / spanInHours) / (hours_to_show / spanInHours); + const thickPart = containerWidth * spanFactor / Math.ceil(numLines); + const thinPart = thickPart / (grid_lines_ratio + 1); + numLines = numLines * (grid_lines_ratio + 1); + const lines = []; + for (let i = 0; i < numLines - 1; i += 1) { + const x = containerWidth - thinPart * (i + 1); + // const timeLabel = hours_to_show / numLines * (i + 1); - for (let i = 0; i < numLines; i += 1) { - const x = xRatio * (i + 0.5); - if (i % grid_lines_ratio > 0) { + if ((i + 1) % (grid_lines_ratio + 1) > 0) { lines.push(svg``); } else { lines.push(svg``); From e8355eaf9e233b031d8d9afbd7212fdfcd58348c Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Sat, 14 Dec 2024 01:17:29 +0100 Subject: [PATCH 12/16] fix: build --- src/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.js b/src/main.js index 42aa427..c961b88 100644 --- a/src/main.js +++ b/src/main.js @@ -558,7 +558,7 @@ class MiniGraphCard extends LitElement { const spanFactor = Math.ceil(hours_to_show / spanInHours) / (hours_to_show / spanInHours); const thickPart = containerWidth * spanFactor / Math.ceil(numLines); const thinPart = thickPart / (grid_lines_ratio + 1); - numLines = numLines * (grid_lines_ratio + 1); + numLines *= (grid_lines_ratio + 1); const lines = []; for (let i = 0; i < numLines - 1; i += 1) { From 09fc231efaf75a03d45c8adb0185344e417f30c5 Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Sun, 15 Dec 2024 00:45:36 +0100 Subject: [PATCH 13/16] refactor: simplify grid line strokes --- src/main.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.js b/src/main.js index c961b88..fa85e12 100644 --- a/src/main.js +++ b/src/main.js @@ -565,11 +565,13 @@ class MiniGraphCard extends LitElement { const x = containerWidth - thinPart * (i + 1); // const timeLabel = hours_to_show / numLines * (i + 1); + let stroke; if ((i + 1) % (grid_lines_ratio + 1) > 0) { - lines.push(svg``); + stroke = 'var(--mcg-grid-line-thin-color, var(--divider-color))'; } else { - lines.push(svg``); + stroke = 'var(--mcg-grid-line-thick-color, rgb(from var(--divider-color) R G B /0.5))'; } + lines.push(svg``); } return lines; From c7a0a8b736a7aa93d7ce8cbedb114ceb04d6b76e Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 20 Dec 2024 22:51:52 +0100 Subject: [PATCH 14/16] refactor: move all grid lines to different g tag --- src/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.js b/src/main.js index fa85e12..923a83b 100644 --- a/src/main.js +++ b/src/main.js @@ -512,8 +512,8 @@ class MiniGraphCard extends LitElement { return svg` e.stopPropagation()}> + ${grid_lines_type ? this.renderGridLines() : ''} - ${grid_lines_type ? this.renderGridLines() : ''} ${this.renderSvgGradient(this.gradient)} @@ -574,7 +574,7 @@ class MiniGraphCard extends LitElement { lines.push(svg``); } - return lines; + return svg`${lines}`; } setTooltip(entity, index, value, label = null) { From 9b7c87988d66527c5f35b8ca7d856576664560bf Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 20 Dec 2024 22:53:14 +0100 Subject: [PATCH 15/16] add missing class --- src/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.js b/src/main.js index 923a83b..c09ea0c 100644 --- a/src/main.js +++ b/src/main.js @@ -574,7 +574,7 @@ class MiniGraphCard extends LitElement { lines.push(svg``); } - return svg`${lines}`; + return svg`${lines}`; } setTooltip(entity, index, value, label = null) { From fd1bfe26cc16696dfa3b0ba468d4a060c66381a8 Mon Sep 17 00:00:00 2001 From: Julien Deveaux Date: Fri, 20 Dec 2024 23:26:46 +0100 Subject: [PATCH 16/16] fix: class grid-lines to grid--lines --- src/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.js b/src/main.js index c09ea0c..721fe0a 100644 --- a/src/main.js +++ b/src/main.js @@ -574,7 +574,7 @@ class MiniGraphCard extends LitElement { lines.push(svg``); } - return svg`${lines}`; + return svg`${lines}`; } setTooltip(entity, index, value, label = null) {