Skip to content

Commit 9ce97da

Browse files
author
David Buezas
committed
Added color schemes, defaults entity, yaxis and show_value for entities
1 parent 09bb4a3 commit 9ce97da

File tree

4 files changed

+123
-17
lines changed

4 files changed

+123
-17
lines changed

readme.md

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
<img src="https://user-images.githubusercontent.com/52346449/142386216-dfc22660-b053-495d-906f-0ebccbdf985f.png" width="300" align="right" >
1313
<br clear="left"/>
1414

15-
16-
17-
1815
## [Post in HomeAssistant community forum](https://community.home-assistant.io/t/plotly-interactive-graph-card/347746)
1916

2017
You may find some extra info there in this link
@@ -133,12 +130,26 @@ entities:
133130
- entity: sensor.humidity
134131
```
135132

133+
## Color schemes
134+
135+
Changes default line colors.
136+
See more here: https://github.com/dbuezas/lovelace-plotly-graph-card/blob/master/src/color-schemes.ts
137+
138+
```yaml
139+
type: custom:plotly-graph
140+
entities:
141+
- sensor.temperature1
142+
- sensor.temperature2
143+
color_scheme: dutch_field
144+
# color_scheme: 1 # or use numbers instead 0 to 24 available
145+
```
146+
136147
### Attribute values
137148

138149
Plot the attributes of an entity by adding `::atribute_name` to the entity name
139150

140151
```yaml
141-
entities:
152+
entities:
142153
- entity: climate.living::temperature
143154
- entity: climate.kitchen::temperature
144155
```
@@ -152,6 +163,7 @@ entities:
152163
lambda: |- # Transforms the data
153164
(ys) => ys.map(y => (y × 9/5) + 32)
154165
unit_of_measurement: °F # Overrides the unit
166+
show_value: true # shows the last known value of each entity in the graph
155167
```
156168

157169
### `lambda:` transforms
@@ -257,15 +269,21 @@ note: `ys[0]` represents the first "known" value, which is the value furthest to
257269
})
258270
```
259271

260-
## Default trace styling
272+
## Default trace & axis styling
273+
274+
default configurations for all entities and all yaxes (e.g yaxis, yaxis2, yaxis3, etc).
261275

262276
```yaml
263-
entities: sensor.temperature1
264-
sensor.temperature2
265-
default_trace:
266-
fill: tozeroy
267-
line:
268-
width: 2
277+
entities:
278+
- sensor.temperature1
279+
- sensor.temperature2
280+
defaults:
281+
entity:
282+
fill: tozeroy
283+
line:
284+
width: 2
285+
yaxis:
286+
fixedrange: true # disables vertical zoom & scroll
269287
```
270288

271289
## layout:

src/color-schemes.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
r=Array.from(document.querySelectorAll(".scheme")).slice(0,14).map(el=>{
3+
const name= el.querySelector("a").name
4+
const list = Array.from(el.querySelectorAll(".swatch div")).map(el=>`"${el.title}"`)
5+
return `${name}: [${list}]`
6+
}).join(',\n')
7+
copy(r)
8+
*/
9+
10+
11+
const colorSchemes = {
12+
// https://vega.github.io/vega/docs/schemes/#categorical
13+
accent: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"],
14+
category10: ["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"],
15+
category20: ["#1f77b4","#aec7e8","#ff7f0e","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"],
16+
category20b: ["#393b79","#5254a3","#6b6ecf","#9c9ede","#637939","#8ca252","#b5cf6b","#cedb9c","#8c6d31","#bd9e39","#e7ba52","#e7cb94","#843c39","#ad494a","#d6616b","#e7969c","#7b4173","#a55194","#ce6dbd","#de9ed6"],
17+
category20c: ["#3182bd","#6baed6","#9ecae1","#c6dbef","#e6550d","#fd8d3c","#fdae6b","#fdd0a2","#31a354","#74c476","#a1d99b","#c7e9c0","#756bb1","#9e9ac8","#bcbddc","#dadaeb","#636363","#969696","#bdbdbd","#d9d9d9"],
18+
dark2: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"],
19+
paired: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"],
20+
pastel1: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"],
21+
pastel2: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"],
22+
set1: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"],
23+
set2: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"],
24+
set3: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"],
25+
tableau10: ["#4c78a8","#f58518","#e45756","#72b7b2","#54a24b","#eeca3b","#b279a2","#ff9da6","#9d755d","#bab0ac"],
26+
tableau20: ["#4c78a8","#9ecae9","#f58518","#ffbf79","#54a24b","#88d27a","#b79a20","#f2cf5b","#439894","#83bcb6","#e45756","#ff9d98","#79706e","#bab0ac","#d67195","#fcbfd2","#b279a2","#d6a5c9","#9e765f","#d8b5a5"],
27+
// https://www.omnisci.com/blog/12-color-palettes-for-telling-better-stories-with-your-data
28+
retro_metro: ["#ea5545", "#f46a9b", "#ef9b20", "#edbf33", "#ede15b", "#bdcf32", "#87bc45", "#27aeef", "#b33dc6"],
29+
dutch_field: ["#e60049", "#0bb4ff", "#50e991", "#e6d800", "#9b19f5", "#ffa300", "#dc0ab4", "#b3d4ff", "#00bfa0"],
30+
river_nights: ["#b30000", "#7c1158", "#4421af", "#1a53ff", "#0d88e6", "#00b7c7", "#5ad45a", "#8be04e", "#ebdc78"],
31+
spring_pastels: ["#fd7f6f", "#7eb0d5", "#b2e061", "#bd7ebe", "#ffb55a", "#ffee65", "#beb9db", "#fdcce5", "#8bd3c7"],
32+
blue_to_yellow: ["#115f9a", "#1984c5", "#22a7f0", "#48b5c4", "#76c68f", "#a6d75b", "#c9e52f", "#d0ee11", "#d0f400"],
33+
grey_to_red: ["#d7e1ee", "#cbd6e4", "#bfcbdb", "#b3bfd1", "#a4a2a8", "#df8879", "#c86558", "#b04238", "#991f17"],
34+
black_to_pink: ["#2e2b28", "#3b3734", "#474440", "#54504c", "#6b506b", "#ab3da9", "#de25da", "#eb44e8", "#ff80ff"],
35+
blue_to_red: ["#1984c5", "#22a7f0", "#63bff0", "#a7d5ed", "#e2e2e2", "#e1a692", "#de6e56", "#e14b31", "#c23728"],
36+
orange_to_purple: ["#ffb400", "#d2980d", "#a57c1b", "#786028", "#363445", "#48446e", "#5e569b", "#776bcd", "#9080ff"],
37+
pink_foam: ["#54bebe", "#76c8c8", "#98d1d1", "#badbdb", "#dedad2", "#e4bcad", "#df979e", "#d7658b", "#c80064"],
38+
salmon_to_aqua: ["#e27c7c", "#a86464", "#6d4b4b", "#503f3f", "#333333", "#3c4e4b", "#466964", "#599e94", "#6cd4c5"],
39+
}
40+
export default colorSchemes
41+
export type ColorSchemeNames = keyof typeof colorSchemes

src/plotly-graph-card.ts

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import getThemedLayout from "./themed-layout";
1313
import isProduction from "./is-production";
1414
import { sleep } from "./utils";
1515
import { Datum } from "plotly.js";
16+
import colorSchemes from "./color-schemes";
1617

1718
const componentName = isProduction ? "plotly-graph" : "plotly-graph-dev";
1819

@@ -261,7 +262,7 @@ export class PlotlyGraph extends HTMLElement {
261262

262263
const units = this.getAllUnitsOfMeasurement();
263264

264-
return entities.map((trace) => {
265+
return entities.flatMap((trace, traceIdx) => {
265266
const entity_id = trace.entity;
266267
const history = histories[entity_id] || {};
267268
const attribute = attributes[entity_id] || {};
@@ -284,11 +285,17 @@ export class PlotlyGraph extends HTMLElement {
284285
if (r.x) xs = r.x;
285286
if (r.y) ys = r.y;
286287
}
287-
} catch (e){
288-
console.error(e)
288+
} catch (e) {
289+
console.error(e);
289290
}
290291
}
291-
return merge(
292+
293+
const schemeName = this.config.color_scheme ?? "category10" 
294+
let colorScheme =
295+
colorSchemes[schemeName] ||
296+
colorSchemes[Object.keys(colorSchemes)[schemeName]]||
297+
colorSchemes.category10;
298+
const mergedTrace = merge(
292299
{
293300
entity_id,
294301
name,
@@ -297,14 +304,37 @@ export class PlotlyGraph extends HTMLElement {
297304
line: {
298305
width: 1,
299306
shape: "hv",
307+
color: colorScheme[traceIdx % colorScheme.length],
300308
},
309+
legendgroup: "group" + traceIdx,
301310
x: xs,
302311
y: ys,
303312
yaxis: "y" + (yaxis_idx == 0 ? "" : yaxis_idx + 1),
304313
},
305-
this.config.default_trace,
314+
this.config.defaults?.entity,
306315
trace
307316
);
317+
const traces: Plotly.Data[] = [mergedTrace];
318+
if (mergedTrace.show_value) {
319+
traces.push({
320+
...mergedTrace,
321+
mode: "text+markers",
322+
// @ts-expect-error (texttemplate missing in plotly typings)
323+
texttemplate: `%{y}${unit}`,
324+
legendgroup: "group" + traceIdx,
325+
showlegend: false,
326+
textposition: "middle right",
327+
marker: {
328+
color: mergedTrace.line.color,
329+
},
330+
textfont: {
331+
color: mergedTrace.line.color,
332+
},
333+
x: mergedTrace.x.slice(-1),
334+
y: mergedTrace.y.slice(-1),
335+
});
336+
}
337+
return traces;
308338
});
309339
}
310340

@@ -318,6 +348,17 @@ export class PlotlyGraph extends HTMLElement {
318348

319349
const layout = merge(
320350
{ uirevision: true },
351+
{
352+
yaxis: this.config.defaults?.yaxis,
353+
yaxis2: this.config.defaults?.yaxis,
354+
yaxis3: this.config.defaults?.yaxis,
355+
yaxis4: this.config.defaults?.yaxis,
356+
yaxis5: this.config.defaults?.yaxis,
357+
yaxis6: this.config.defaults?.yaxis,
358+
yaxis7: this.config.defaults?.yaxis,
359+
yaxis8: this.config.defaults?.yaxis,
360+
yaxis9: this.config.defaults?.yaxis,
361+
},
321362
this.config.no_default_layout ? {} : yAxisTitles,
322363
this.getThemedLayout(),
323364
this.size,

src/types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
import { Datum } from "plotly.js";
2+
import { ColorSchemeNames } from "./color-schemes";
23

34
export type Config = {
45
type: "custom:plotly-graph-card";
56
hours_to_show?: number;
67
refresh_interval?: number; // in seconds
8+
color_scheme?: ColorSchemeNames;
79
entities: (Partial<Plotly.PlotData> & {
810
entity: string;
911
unit_of_measurement?: string;
1012
lambda?: (y: Datum[], x: Date[], raw_entity: History) => Datum[] | {x?:Datum[], y?:Datum[]};
13+
show_value?: boolean;
1114
})[];
12-
default_trace?: Partial<Plotly.PlotData>,
15+
defaults?: {
16+
entity?: Partial<Plotly.PlotData>,
17+
yaxis?: Partial<Plotly.Layout["yaxis"]>,
18+
}
1319
layout?: Partial<Plotly.Layout>;
1420
config?: Partial<Plotly.Config>;
1521
no_theme?: boolean;

0 commit comments

Comments
 (0)