Skip to content

Commit 2550b71

Browse files
FrnchFrggdbuezas
andauthored
Support card-mod by meeting its expectations (#99)
* Support `card-mod` by meeting its expectations `card-mod` expects that the `<ha-card/>`, or one of its ancestors, has an attribute named `config` or `_config` where the initial card configuration is stored. It searches for a `card_mod:` section in it. `plotly-graph` uses such a `config` attribute, but stores its own internal understanding of what the YAML config meant, which means in particular that the `card_mod:` section is filtered out (and for that matter any configuration that `plotly-graph` is not aware of). Store the vetted configuration in `parsed_config` instead, and remember the initial unfiltered configuration in the `config` attribute for `card_mod` and others to use. Fixes #86. * Fix pristine config type Co-authored-by: David Buezas <[email protected]>
1 parent 73a76d4 commit 2550b71

File tree

1 file changed

+23
-21
lines changed

1 file changed

+23
-21
lines changed

src/plotly-graph-card.ts

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ export class PlotlyGraph extends HTMLElement {
5858
cardEl!: HTMLElement;
5959
buttonEl!: HTMLButtonElement;
6060
titleEl!: HTMLElement;
61-
config!: Config;
61+
config!: InputConfig;
62+
parsed_config!: Config;
6263
cache = new Cache();
6364
size: { width?: number; height?: number } = {};
6465
hass?: HomeAssistant; // set externally
@@ -179,7 +180,7 @@ export class PlotlyGraph extends HTMLElement {
179180
)!;
180181
}
181182
getAutoFetchRange() {
182-
const ms = this.config.hours_to_show * 60 * 60 * 1000;
183+
const ms = this.parsed_config.hours_to_show * 60 * 60 * 1000;
183184
return [+new Date() - ms, +new Date()] as [number, number];
184185
}
185186
getVisibleRange() {
@@ -218,6 +219,7 @@ export class PlotlyGraph extends HTMLElement {
218219
// render an error card.
219220
async setConfig(config: InputConfig) {
220221
config = JSON.parse(JSON.stringify(config));
222+
this.config = config;
221223
const schemeName = config.color_scheme ?? "category10";
222224
const colorScheme = isColorSchemeArray(schemeName)
223225
? schemeName
@@ -322,17 +324,17 @@ export class PlotlyGraph extends HTMLElement {
322324
minimal_response: config.minimal_response ?? true,
323325
};
324326

325-
const was = this.config;
326-
this.config = newConfig;
327-
const is = this.config;
327+
const was = this.parsed_config;
328+
this.parsed_config = newConfig;
329+
const is = this.parsed_config;
328330
if (!this.contentEl) return;
329331
if (is.hours_to_show !== was.hours_to_show) {
330332
this.exitBrowsingMode();
331333
}
332334
await this.fetch(this.getAutoFetchRange());
333335
}
334336
fetch = async (range: TimestampRange) => {
335-
for (const entity of this.config.entities) {
337+
for (const entity of this.parsed_config.entities) {
336338
if ((entity as any).autoPeriod) {
337339
if (isEntityIdStatisticsConfig(entity) && entity.autoPeriod) {
338340
entity.period = "5minute";
@@ -350,13 +352,13 @@ export class PlotlyGraph extends HTMLElement {
350352
for (const [fromMS, aPeriod] of mapping) {
351353
if (timeSpan >= fromMS) entity.period = aPeriod;
352354
}
353-
this.config.layout = merge(this.config.layout, {
355+
this.parsed_config.layout = merge(this.parsed_config.layout, {
354356
xaxis: { title: `Period: ${entity.period}` },
355357
});
356358
}
357359
}
358360
}
359-
const visibleEntities = this.config.entities.filter(
361+
const visibleEntities = this.parsed_config.entities.filter(
360362
(_, i) => this.contentEl.data[i]?.visible !== "legendonly"
361363
);
362364
while (!this.hass) await sleep(100);
@@ -366,8 +368,8 @@ export class PlotlyGraph extends HTMLElement {
366368
!this.isBrowsing,
367369
visibleEntities,
368370
this.hass,
369-
this.config.minimal_response,
370-
this.config.significant_changes_only
371+
this.parsed_config.minimal_response,
372+
this.parsed_config.significant_changes_only
371373
);
372374
this.msgEl.innerText = "";
373375
} catch (e: any) {
@@ -377,7 +379,7 @@ export class PlotlyGraph extends HTMLElement {
377379
await this.plot();
378380
};
379381
getAllUnitsOfMeasurement() {
380-
const all = this.config.entities.map((entity) =>
382+
const all = this.parsed_config.entities.map((entity) =>
381383
this.getUnitOfMeasurement(entity)
382384
);
383385
return Array.from(new Set(all));
@@ -401,13 +403,13 @@ export class PlotlyGraph extends HTMLElement {
401403
haTheme = mapValues(haTheme, (_, key) => styles.getPropertyValue(key));
402404
return getThemedLayout(
403405
haTheme,
404-
this.config.no_theme,
405-
this.config.no_default_layout
406+
this.parsed_config.no_theme,
407+
this.parsed_config.no_default_layout
406408
);
407409
}
408410

409411
getData(): Plotly.Data[] {
410-
const entities = this.config.entities;
412+
const entities = this.parsed_config.entities;
411413

412414
const units = this.getAllUnitsOfMeasurement();
413415
const show_value_traces: Plotly.Data[] = [];
@@ -480,7 +482,7 @@ export class PlotlyGraph extends HTMLElement {
480482
) {
481483
const timeMargin =
482484
mergedTrace.show_value.right_margin *
483-
((this.config.hours_to_show * 1000 * 60 * 60) / 100);
485+
((this.parsed_config.hours_to_show * 1000 * 60 * 60) / 100);
484486
show_value_traces.push({
485487
...mergedTrace,
486488
marker: {
@@ -508,10 +510,10 @@ export class PlotlyGraph extends HTMLElement {
508510

509511
const layout = merge(
510512
{ uirevision: true },
511-
this.config.no_default_layout ? {} : yAxisTitles,
513+
this.parsed_config.no_default_layout ? {} : yAxisTitles,
512514
this.getThemedLayout(),
513515
this.size,
514-
this.config.layout
516+
this.parsed_config.layout
515517
);
516518
return layout;
517519
}
@@ -525,15 +527,15 @@ export class PlotlyGraph extends HTMLElement {
525527
"lasso2d",
526528
"select2d",
527529
],
528-
...this.config.config,
530+
...this.parsed_config.config,
529531
};
530532
}
531533
async plot() {
532-
if (!this.config) return;
534+
if (!this.parsed_config) return;
533535
if (!this.hass) return;
534536
if (!this.isConnected) return;
535-
this.titleEl.innerText = this.config.title || "";
536-
const refresh_interval = this.config.refresh_interval;
537+
this.titleEl.innerText = this.parsed_config.title || "";
538+
const refresh_interval = this.parsed_config.refresh_interval;
537539
clearTimeout(this.handles.refreshTimeout!);
538540
if (refresh_interval > 0) {
539541
this.handles.refreshTimeout = window.setTimeout(

0 commit comments

Comments
 (0)