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
7,231 changes: 3,948 additions & 3,283 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"dependencies": {
"@ctrl/tinycolor": "^3.4.0",
"@material/mwc-ripple": "^0.25.3",
"apexcharts": "^3.35.0",
"apexcharts": "^3.36.0",
"array-flat-polyfill": "^1.0.1",
"custom-card-helpers": "^1.9.0",
"home-assistant-js-websocket": "^7.0.2",
Expand Down
27 changes: 22 additions & 5 deletions src/apex-layouts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export function getLayoutConfig(
position: 'bottom',
show: true,
formatter: getLegendFormatter(config, hass),
markers: getLegendMarkers(config)
},
stroke: {
curve: getStrokeCurve(config, false),
Expand All @@ -88,6 +89,9 @@ export function getLayoutConfig(
},
};

if (def.chart.type==='line' && def.series.some(s=>s.type==='rangeArea'))
def.chart.type='rangeArea';

let conf = {};
switch (config.layout) {
case 'minimal':
Expand Down Expand Up @@ -171,13 +175,17 @@ export function getBrushLayoutConfig(
text: 'Loading...',
},
};

if (def.chart.type==='line' && def.series.some(s=>s.type==='rangeArea'))
def.chart.type='rangeArea';

return config.brush?.apex_config ? mergeDeep(def, evalApexConfig(config.brush.apex_config)) : def;
}

function getFillOpacity(config: ChartCardConfig, brush: boolean): number[] {
const series = brush ? config.series_in_brush : config.series_in_graph;
return series.map((serie) => {
return serie.opacity !== undefined ? serie.opacity : serie.type === 'area' ? DEFAULT_AREA_OPACITY : 1;
return serie.opacity !== undefined ? serie.opacity : (serie.type === 'area'|| serie.type==='rangeArea') ? DEFAULT_AREA_OPACITY : 1;
});
}

Expand All @@ -188,7 +196,7 @@ function getSeries(config: ChartCardConfig, hass: HomeAssistant | undefined, bru
return {
name: computeName(index, series, undefined, hass?.states[serie.entity]),
type: serie.type,
data: [],
data: (serie.type??config.chart_type)==='rangeArea'?[[0,[0,0]]]:[],
};
});
} else {
Expand Down Expand Up @@ -272,6 +280,7 @@ function getXTooltipFormatter(
} as any).format(val);
}
: function (val, _a, _b, hours_12 = hours12) {
if (!val) return "";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return new Intl.DateTimeFormat(lang, {
year: 'numeric',
Expand All @@ -288,6 +297,7 @@ function getXTooltipFormatter(

function getYTooltipFormatter(config: ChartCardConfig, hass: HomeAssistant | undefined) {
return function (value, opts, conf = config, hass2 = hass) {
if (!opts) return value;
let lValue = value;
if (conf.series_in_graph[opts.seriesIndex]?.invert && lValue) {
lValue = -lValue;
Expand Down Expand Up @@ -387,7 +397,10 @@ function getLegendFormatter(config: ChartCardConfig, hass: HomeAssistant | undef
undefined,
hass2?.states[conf.series_in_graph[opts.seriesIndex].entity],
);
if (!conf.series_in_graph[opts.seriesIndex].show.legend_value) {
if (!conf.series_in_graph[opts.seriesIndex].show.legend) {
return '';
}
else if (!conf.series_in_graph[opts.seriesIndex].show.legend_value) {
return [name];
} else {
let value = TIMESERIES_TYPES.includes(config.chart_type)
Expand Down Expand Up @@ -427,6 +440,10 @@ function getLegendFormatter(config: ChartCardConfig, hass: HomeAssistant | undef
};
}

function getLegendMarkers(config: ChartCardConfig) {
return {width: config.series_in_graph.map(serie => serie.show.legend?12:0)};
}

function getStrokeCurve(config: ChartCardConfig, brush: boolean) {
const series = brush ? config.series_in_brush : config.series_in_graph;
return series.map((serie) => {
Expand All @@ -441,14 +458,14 @@ function getDataLabels_enabledOnSeries(config: ChartCardConfig) {
}

function getStrokeWidth(config: ChartCardConfig, brush: boolean) {
if (config.chart_type !== undefined && config.chart_type !== 'line')
if (config.chart_type !== undefined && config.chart_type !== 'line' && config.chart_type !== 'rangeArea')
return config.apex_config?.stroke?.width === undefined ? 3 : config.apex_config?.stroke?.width;
const series = brush ? config.series_in_brush : config.series_in_graph;
return series.map((serie) => {
if (serie.stroke_width !== undefined) {
return serie.stroke_width;
}
return [undefined, 'line', 'area'].includes(serie.type) ? 5 : 0;
return [undefined, 'line', 'area', 'rangeArea'].includes(serie.type) ? 5 : 0;
});
}

Expand Down
30 changes: 19 additions & 11 deletions src/apexcharts-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {
DEFAULT_FLOAT_PRECISION,
DEFAULT_SHOW_IN_CHART,
DEFAULT_SHOW_IN_HEADER,
DEFAULT_SHOW_LEGEND,
DEFAULT_SHOW_LEGEND_VALUE,
DEFAULT_SHOW_NAME_IN_HEADER,
DEFAULT_SHOW_OFFSET_IN_NAME,
Expand Down Expand Up @@ -422,13 +423,16 @@ class ChartsCard extends LitElement {
}
if (!serie.show) {
serie.show = {
legend: DEFAULT_SHOW_LEGEND,
legend_value: DEFAULT_SHOW_LEGEND_VALUE,
in_header: DEFAULT_SHOW_IN_HEADER,
in_chart: DEFAULT_SHOW_IN_CHART,
name_in_header: DEFAULT_SHOW_NAME_IN_HEADER,
offset_in_name: DEFAULT_SHOW_OFFSET_IN_NAME,
};
} else {
serie.show.legend =
serie.show.legend === undefined ? DEFAULT_SHOW_LEGEND : serie.show.legend;
serie.show.legend_value =
serie.show.legend_value === undefined ? DEFAULT_SHOW_LEGEND_VALUE : serie.show.legend_value;
serie.show.in_chart = serie.show.in_chart === undefined ? DEFAULT_SHOW_IN_CHART : serie.show.in_chart;
Expand Down Expand Up @@ -810,7 +814,7 @@ class ChartsCard extends LitElement {
);
} else {
// not raw
this._headerState[index] = graph.lastState;
this._headerState[index] = Array.isArray(graph.lastState)?graph.lastState[0]:graph.lastState;
}
}
if (!this._config?.series[index].show.in_chart && !this._config?.series[index].show.in_brush) {
Expand Down Expand Up @@ -866,7 +870,7 @@ class ChartsCard extends LitElement {
}
data = 0;
} else {
const lastState = graph.lastState;
const lastState = Array.isArray(graph.lastState)?graph.lastState[0]:graph.lastState;
data = lastState || 0;
if (this._config?.series[index].show.in_header !== 'raw') {
this._headerState[index] = lastState;
Expand Down Expand Up @@ -904,7 +908,7 @@ class ChartsCard extends LitElement {
gradient: {
type: 'vertical',
colorStops: this._config.series_in_graph.map((serie, index) => {
if (!serie.color_threshold || ![undefined, 'area', 'line'].includes(serie.type)) return [];
if (!serie.color_threshold || ![undefined, 'area', 'rangeArea', 'line'].includes(serie.type)) return [];
const min = this._graphs?.[serie.index]?.min;
const max = this._graphs?.[serie.index]?.max;
if (min === undefined || max === undefined) return [];
Expand All @@ -919,7 +923,7 @@ class ChartsCard extends LitElement {
gradient: {
type: 'vertical',
colorStops: this._config.series_in_brush.map((serie, index) => {
if (!serie.color_threshold || ![undefined, 'area', 'line'].includes(serie.type)) return [];
if (!serie.color_threshold || ![undefined, 'area', 'rangeArea', 'line'].includes(serie.type)) return [];
const min = this._graphs?.[serie.index]?.min;
const max = this._graphs?.[serie.index]?.max;
if (min === undefined || max === undefined) return [];
Expand Down Expand Up @@ -1180,15 +1184,19 @@ class ChartsCard extends LitElement {
let max: number | null = null;
minMax?.forEach((elt) => {
if (!elt) return;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const val_min = Array.isArray(elt.min[1])?Math.min(elt.min[1][0]!,elt.min[1][1]!):elt.min[1]
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const val_max = Array.isArray(elt.max[1])?Math.max(elt.max[1][0]!,elt.max[1][1]!):elt.max[1]
if (min === undefined || min === null) {
min = elt.min[1];
} else if (elt.min[1] !== null && min > elt.min[1]) {
min = elt.min[1];
min = val_min;
} else if (val_min !== null && min > val_min) {
min = val_min;
}
if (max === undefined || max === null) {
max = elt.max[1];
} else if (elt.max[1] !== null && max < elt.max[1]) {
max = elt.max[1];
max = val_max;
} else if (val_max !== null && max < val_max) {
max = val_max;
}
});
if (yaxis.align_to !== undefined) {
Expand Down Expand Up @@ -1312,7 +1320,7 @@ class ChartsCard extends LitElement {
return [];
}
let color: string | undefined = undefined;
const defaultOp = serie.opacity !== undefined ? serie.opacity : serie.type === 'area' ? DEFAULT_AREA_OPACITY : 1;
const defaultOp = serie.opacity !== undefined ? serie.opacity : (serie.type === 'area' || serie.type === 'rangeArea') ? DEFAULT_AREA_OPACITY : 1;
let opacity = thres.opacity === undefined ? defaultOp : thres.opacity;
if (thres.value > max && arr[index - 1]) {
const factor = (max - arr[index - 1].value) / (thres.value - arr[index - 1].value);
Expand Down
3 changes: 2 additions & 1 deletion src/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const DEFAULT_DURATION = '1h';
export const DEFAULT_FUNC = 'raw';
export const DEFAULT_GROUP_BY_FILL = 'last';
export const DEFAULT_FILL_RAW = 'null';
export const DEFAULT_SHOW_LEGEND = true;
export const DEFAULT_SHOW_LEGEND_VALUE = true;
export const DEFAULT_SHOW_IN_HEADER = true;
export const DEFAULT_SHOW_IN_CHART = true;
Expand Down Expand Up @@ -40,7 +41,7 @@ export const DEFAULT_COLORS = [
];

export const NO_VALUE = 'N/A';
export const TIMESERIES_TYPES = ['line', 'scatter', undefined];
export const TIMESERIES_TYPES = ['rangeArea', 'line', 'scatter', undefined];
export const PLAIN_COLOR_TYPES = ['scatter', 'radialBar', 'pie', 'donut'];

export const DEFAULT_MIN = 0;
Expand Down
Loading