diff --git a/.devcontainer/ui-lovelace.yaml b/.devcontainer/ui-lovelace.yaml index fd5a1c3..9de1ee2 100644 --- a/.devcontainer/ui-lovelace.yaml +++ b/.devcontainer/ui-lovelace.yaml @@ -970,3 +970,24 @@ views: graph_span: 1m series: - entity: sensor.counter_no_significant_update + + - type: custom:apexcharts-card + header: + show: true + title: Significant Updates + graph_span: 1h + apex_config: + xaxis: + labels: + formatter: > + EVAL:function(value) { + return "42"; + } + yaxis: + labels: + formatter: | + EVAL:function(value) { + return "42"; + } + series: + - entity: sensor.random0_100 diff --git a/README.md b/README.md index 654f6f2..5ada603 100644 --- a/README.md +++ b/README.md @@ -439,6 +439,22 @@ apex_config: enabled: true ``` +Some options in ApexCharts can take a javascript function as an argument. To make this possible, you'll have to prefix your function with `EVAL:`. + +:warning: While using this `EVAL:` feature, there is no safeguard so use at your own risk. + +Here is an example: + +```yaml +apex_config: + yaxis: + labels: + formatter: | + EVAL:function(value) { + return "42"; + } +``` + ### Layouts For now, only `minimal` is supported: It will remove the grid, the axis and display the legend at the top. But you can use the `apex_config` to do whatever you want. diff --git a/src/apex-layouts.ts b/src/apex-layouts.ts index 8233dd0..78ffaae 100644 --- a/src/apex-layouts.ts +++ b/src/apex-layouts.ts @@ -93,7 +93,9 @@ export function getLayoutConfig(config: ChartCardConfig, hass: HomeAssistant | u break; } - return config.apex_config ? mergeDeep(mergeDeep(def, conf), config.apex_config) : mergeDeep(def, conf); + return config.apex_config + ? mergeDeep(mergeDeep(def, conf), evalApexConfig(config.apex_config)) + : mergeDeep(def, conf); } export function getBrushLayoutConfig( @@ -164,7 +166,7 @@ export function getBrushLayoutConfig( text: 'Loading...', }, }; - return config.brush?.apex_config ? mergeDeep(def, config.brush.apex_config) : def; + return config.brush?.apex_config ? mergeDeep(def, evalApexConfig(config.brush.apex_config)) : def; } function getFillOpacity(config: ChartCardConfig, brush: boolean): number[] { @@ -432,3 +434,17 @@ function getFillType(config: ChartCardConfig, brush: boolean) { }); } } + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function evalApexConfig(apexConfig: any): any { + const eval2 = eval; + Object.keys(apexConfig).forEach((key) => { + if (typeof apexConfig[key] === 'string' && apexConfig[key].trim().startsWith('EVAL:')) { + apexConfig[key] = eval2(`(${apexConfig[key].trim().slice(5)})`); + } + if (typeof apexConfig[key] === 'object') { + apexConfig[key] = evalApexConfig(apexConfig[key]); + } + }); + return apexConfig; +}