Skip to content

Commit

Permalink
feat(card): Support for pre-defined layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
RomRider committed Jan 22, 2021
1 parent fb717ef commit c5987f8
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 85 deletions.
31 changes: 31 additions & 0 deletions .devcontainer/ui-lovelace.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
views:
- title: Main
cards:
- type: grid
title: Test Grid Square
square: true
columns: 2
cards:
- type: custom:apexcharts-card
stacked: true
series:
- entity: sensor.random_0_1000
name: test1
type: area
curve: straight
- entity: sensor.random_0_1000
name: test2
type: area
hours_to_show: 0.20
cache: true
layout: minimal
- type: custom:apexcharts-card
stacked: true
series:
- entity: sensor.random_0_1000
name: test1
type: bar
- entity: sensor.random_0_1000
name: test2
type: bar
hours_to_show: 0.25
cache: true

- type: custom:apexcharts-card
stacked: true
series:
Expand All @@ -13,6 +43,7 @@ views:
type: area
hours_to_show: 0.20
cache: true
layout: minimal

- type: custom:apexcharts-card
stacked: true
Expand Down
145 changes: 145 additions & 0 deletions src/apex-layouts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import moment from 'moment';
import { ChartCardConfig } from './types';
import { getMilli, mergeDeep } from './utils';

export function getLayoutConfig(config: ChartCardConfig): unknown {
const def = {
chart: {
stacked: config?.stacked,
type: 'line',
foreColor: 'var(--primary-text-color)',
width: '100%',
// animations: {
// enabled: true,
// easing: 'linear',
// dynamicAnimation: {
// speed: 1000,
// },
// },
zoom: {
enabled: false,
},
toolbar: {
show: false,
},
},
grid: {
strokeDashArray: 3,
},
title: {
text: config?.series[0].name || config?.series[0].entity,
align: 'left',
floating: false,
// offsetX: 10,
style: {
fontSize: '20px',
fontWeight: '500',
fontFamily: 'var(--paper-font-body1_-_font-family)',
// color: '#263238'
},
},
subtitle: {
text: undefined,
align: 'right',
floating: true,
offsetY: 0,
margin: 0,
style: {
fontSize: '40px',
fontWeight: '300',
fontFamily: 'var(--paper-font-body1_-_font-family)',
// color: '#9699a2'
},
},
series: config?.series.map((serie) => {
return {
name: serie.name || serie.entity,
type: serie.type || 'line',
data: [],
};
}),
xaxis: {
type: 'datetime',
range: getMilli(config.hours_to_show),
labels: {
datetimeUTC: false,
},
},
tooltip: {
x: {
formatter:
config.hours_to_show < 24
? function (val) {
return moment(new Date(val)).format('HH:mm:ss');
}
: function (val) {
return moment(new Date(val)).format('MMM Do, HH:mm:ss');
},
},
fixed: {
enabled: true,
postion: 'topRight',
},
},
stroke: {
curve: config.series.map((serie) => {
return serie.curve || 'smooth';
}),
lineCap: 'round',
},
noData: {
text: 'Loading...',
},
};

let conf = {};
switch (config.layout) {
case 'minimal':
conf = {
chart: {
offsetY: 15,
parentHeightOffset: 0,
},
grid: {
show: false,
padding: {
left: 0,
right: 0,
},
},
xaxis: {
labels: {
show: false,
},
axisBorder: {
show: false,
},
axisTicks: {
show: false,
},
crosshairs: {
show: true,
},
tooltip: {
enabled: false,
},
},
yaxis: {
show: false,
showAlways: true,
tooltip: {
enabled: true,
},
},
legend: {
position: 'top',
},
};
break;

default:
break;
}

return mergeDeep(def, conf);
}
94 changes: 9 additions & 85 deletions src/apexcharts-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { compress, decompress, getMilli, log } from './utils';
import ApexCharts from 'apexcharts';
import { styles } from './styles';
import { HassEntity } from 'home-assistant-js-websocket';
import moment from 'moment';
import { getLayoutConfig } from './apex-layouts';

/* eslint no-console: 0 */
console.info(
Expand Down Expand Up @@ -121,7 +121,9 @@ class ChartsCard extends LitElement {

return html`
<ha-card>
<div id="graph"></div>
<div id="wrapper">
<div id="graph"></div>
</div>
</ha-card>
`;
}
Expand All @@ -132,86 +134,7 @@ class ChartsCard extends LitElement {
if (!this._apexChart && this.shadowRoot && this._config) {
this._loaded = true;
const graph = this.shadowRoot.querySelector('#graph');
this._apexChart = new ApexCharts(graph, {
chart: {
stacked: this._config?.stacked,
type: 'line',
foreColor: 'var(--primary-text-color)',
// animations: {
// enabled: true,
// easing: 'linear',
// dynamicAnimation: {
// speed: 1000,
// },
// },
zoom: {
enabled: false,
},
toolbar: {
show: false,
},
},
title: {
text: this._config?.series[0].name || this._config?.series[0].entity,
align: 'left',
floating: false,
// offsetX: 10,
style: {
fontSize: '20px',
fontWeight: '500',
fontFamily: 'var(--paper-font-body1_-_font-family)',
// color: '#263238'
},
},
subtitle: {
text: undefined,
align: 'right',
floating: true,
offsetY: 0,
margin: 0,
style: {
fontSize: '40px',
fontWeight: '300',
fontFamily: 'var(--paper-font-body1_-_font-family)',
// color: '#9699a2'
},
},
series: this._config?.series.map((serie) => {
return {
name: serie.name || serie.entity,
type: serie.type || 'line',
data: [],
};
}),
xaxis: {
type: 'datetime',
range: getMilli(this._config.hours_to_show),
labels: {
datetimeUTC: false,
},
},
tooltip: {
x: {
formatter:
this._config.hours_to_show < 24
? function (val) {
return moment(new Date(val)).format('HH:mm:ss');
}
: function (val) {
return moment(new Date(val)).format('MMM Do, HH:mm:ss');
},
},
},
stroke: {
curve: this._config.series.map((serie) => {
return serie.curve || 'smooth';
}),
lineCap: 'round',
},
noData: {
text: 'Loading...',
},
});
this._apexChart = new ApexCharts(graph, getLayoutConfig(this._config));
this._apexChart.render();
}
}
Expand Down Expand Up @@ -245,9 +168,10 @@ class ChartsCard extends LitElement {
const graphData = {
series: this._history.map((history, index) => {
return {
data: this._config?.series[index].extend_to_end
? [...history?.data, ...[[end.getTime(), history?.data.slice(-1)[0][1]]]]
: history?.data,
data:
this._config?.series[index].extend_to_end && this._config?.series[index].type !== 'bar'
? [...history?.data, ...[[end.getTime(), history?.data.slice(-1)[0][1]]]]
: history?.data,
};
}),
subtitle: {
Expand Down
8 changes: 8 additions & 0 deletions src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ export const styles: CSSResult = css`
display: block;
}
ha-card {
overflow: hidden;
height: 100%;
}
#wrapper {
overflow: hidden;
height: 100%;
}
#graph {
height: 100%;
}
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface ChartCardExternalConfig {
hours_to_show?: number;
cache?: boolean;
stacked?: boolean;
layout?: string;
}

export interface ChartCardSeriesExternalConfig {
Expand Down
30 changes: 30 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,33 @@ export function log(message): void {
// eslint-disable-next-line no-console
console.warn('apexcharts-card: ', message);
}

/**
* Performs a deep merge of `source` into `target`.
* Mutates `target` only but not its objects and arrays.
*
* @author inspired by [jhildenbiddle](https://stackoverflow.com/a/48218209).
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
export function mergeDeep(target: any, source: any): any {
const isObject = (obj) => obj && typeof obj === 'object';

if (!isObject(target) || !isObject(source)) {
return source;
}

Object.keys(source).forEach((key) => {
const targetValue = target[key];
const sourceValue = source[key];

if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
target[key] = targetValue.concat(sourceValue);
} else if (isObject(targetValue) && isObject(sourceValue)) {
target[key] = mergeDeep(Object.assign({}, targetValue), sourceValue);
} else {
target[key] = sourceValue;
}
});

return target;
}

0 comments on commit c5987f8

Please sign in to comment.