ApexCharts card - A highly customizable graph card

hello, I have the following code:

type: 'custom:apexcharts-card'
graph_span: 3d
header:
  show: true
  title: Balance Last Three Days
  show_states: true
  colorize_states: true
series:
  - entity: sensor.nh_nicehash_totalbalance_usd
    fill_raw: last
    color: red
  - entity: sensor.nh_nicehash_totalbalance
    fill_raw: last
    color: blue
apex_config:
  yaxis:
    - title:
        text: USD
      opposite: true
      decimalsInFloat: 0
      min: 55
    - title:
        text: BTC
      labels:
        show: true
      decimalsInFloat: 5
      min: 0.001

Is it possible to make min values to be dynamically calculated as min value of the entity being displayed?

I have a chart showing the last 30 days of electricity cost + usage. It would be nice to have an X axis annotation at each Monday, but I can’t see a way to nicely automate that. An alternative would be to have a binary sensor that turns on each Monday, and off for other days of the week, and use that as a chart series on a secondary Y axis. Anybody got something like this working?

To answer my own question, I ended up creating a series in the chart using data_generator…

config
  • entity: sensor.octopus_electricity_agile_cost_30days
    fill_raw: zero
    type: area
    color: grey
    curve: stepline
    name: Start of week
    extend_to_end: true
    opacity: 0.2
    stroke_width: 1
    data_generator: >
    let res = [];
    var startOfWeek = new Date();
    startOfWeek.setHours(0,0,0,0);
    startOfWeek.setDate(startOfWeek.getDate() - (startOfWeek.getDay() + 6) % 7);
    var startOfWeekTime = startOfWeek.getTime();
    var day = 2460601000;
    res.push([startOfWeekTime, 1]);
    res.push([startOfWeekTime- (8
    day), 0]);
    res.push([startOfWeekTime-(14day), 1]);
    res.push([startOfWeekTime-(22
    day), 0]);
    res.push([startOfWeekTime-(28day), 1]);
    res.push([startOfWeekTime-(36
    day), 0]);
    return res.sort((a, b) => {return a[0] - b[0] });

3 Likes

Is it possible to transform both value 50 and 51 to booleans according to transform: 'return x == ''50'' ? 1 : 0;'?

How would one “transform” data_genetatored values?

  - entity: weather.openweathermap
    name: Precipitation
    type: column
    group_by:
      func: avg
      duration: 1h
    show:
      datalabels: false
      in_header: false
    data_generator: |
      return entity.attributes.forecast.map((entry) => {
        return [new Date(entry.datetime).getTime(), entry.precipitation];
      });

I’ve tried adding the transform option but it gets ignored, I feel I need to add it in the data genetor somewhere but not very good with javascript or whatever it is.

Essentially, I’d like the precipitation value for the forecasted data to be multiplied by 4.

Hi everyone,

First of all, thank you for this amazing card!
I am trying to have only two y-axis for four series. Any clue how to do that?

image

type: 'custom:apexcharts-card'
graph_span: 10d
hours_12: false
y_axis_precision: 0
all_series_config:
  stroke_width: 3
  show:
    legend_value: false
header:
  show: true
  title: Conso. quotidienne
  show_states: true
  colorize_states: true
  standard_format: true


apex_config:
  yaxis:
    - show: true
      decimalsInFloat: 0
      forceNiceScale: true
    - show: true
      decimalsInFloat: 0
      forceNiceScale: true

    - show: true
      opposite: true
      decimalsInFloat: 0
      forceNiceScale: true
    - show: true
      opposite: true
      decimalsInFloat: 0
      forceNiceScale: true

series:
  - entity: sensor.gazpar_energy_price
    name: Gaz
    type: column
    group_by:
      func: max
      duration: 1d
  - entity: sensor.myenedis_cost_yesterday_pdl
    name: Électricité
    type: column
    group_by:
      func: max
      duration: 1d
  - entity: sensor.outside_temperature
    name: T° ext. maximale
    show:
      in_header: false
      offset_in_name: false
    offset: '-1d'
    group_by:
      func: max
      duration: 1d
  - entity: sensor.outside_temperature
    name: T° ext. minimale
    show:
      in_header: false
      offset_in_name: false
    offset: '-1d'
    group_by:
      func: min
      duration: 1d

Can extremas be tweaked to only show maximum and not minimum?

You can switch show: true to show: false on the two y-axis entries you don’t want to appear. Although I would recommend setting some max/min values so they align with the visible axis values to avoid confusion.

1 Like

I love it, thank you @Kinetic21
image

2 Likes

When I combine two sensors in one diagram (with two y-axis) the automatic scaling changes it’s behavior in a manner, that only the max value seems to work and the min value is always zero.
Both diagrams show the same sensor in red, left combined with another sensor. Both no max or min.

Is there a way to have the y-axis scaling automic for max and min?

type: 'custom:apexcharts-card'
graph_span: 24h
header:
  show: true
  title: Außen
  show_states: true
  colorize_states: true
series:
  - entity: sensor.xiaomiaqara_1_temperature
    name: Temperatur
    color: '#ff444f'
  - entity: sensor.xiaomiaqara_1_humidity
    name: Feuchte
    color: '#00b4fb'
all_series_config:
  type: area
  curve: smooth
  show:
    extremas: true
  group_by:
    func: avg
    duration: 5m
apex_config:
  stroke:
    width: 2
  yaxis:
    - decimalsInFloat: 0
    - decimalsInFloat: 0
      opposite: true
  fill:
    type:
      - gradient
    gradient:
      type: vertical
      opacityFrom: 0.7
      opacityTo: 0.3
  tooltip:
    x:
      format: 'HH:mm'

Is it possible :

  • to show the numbers of every month
  • completely occupy the x-axis

Why does a duration of 31 days cause a column overflow?

type: 'custom:apexcharts-card'
graph_span: 365d
update_interval: 1hour
cache: true
span:
  end: month
header:
  show: false
apex_config:
  xaxis:
    labels:
      format: MM
      show: true
      showAlways: true
  yaxis:
    forceNiceScale: false
    decimalsInFloat: 0
  chart:
    type: area
    height: 300
  stroke:
    show: true
    width: 1
  legend:
    show: true
  dataLabels:
    enabled: false
    distributed: true
  fill:
    type: gradient
    gradient:
      shadeIntensity: 0.1
      opacityFrom: 0.25
      opacityTo: 1
      inverseColors: true
      stops:
        - 0
        - 90
        - 100
series:
  - color: 'rgb(20,129,238)'
    entity: sensor.conso_eau_mois
    type: column
    name: Eau
    float_precision: 2
    group_by:
      func: max
      duration: 30d

** EDIT** Nevermind, there was a spacing issue… seems to work now. Thanks for the example!!!

Hi Mark thanks for putting this up on github, I looked at it and am working on doing the same thing in nodered since I already have this up and there is an influxdb node. I just wanted to see if I am formatting the sensor the same as you for your data_generator function. Is the below correct?

Hi everyone, i would like to import data with the data generator function

I recently switch to a french energy provider which provides API to get the lowest price of the day.
I managed to get the prices in either pyscript and nodered for comparaison purpose (pyscript will disapear as soon as i will be sure that everything is ok).
Data are stored in attributes under the dictionnary template {‘time’:value}.
1e02acc7ebe7e1ffca87df6e23af719060e1a67e
Between NodeRed & Pyscript, no probs, they both have the same chart and the base time is in accordance with the official app.
I used one of the script if found in this topic:

type: 'custom:apexcharts-card'
header:
  show: true
  title: Barry Electricité NODERED (€/kWh)
  show_states: false
  colorize_states: true
y_axis_precision: 4
span:
  start: day
  offset: '-1day'
graph_span: 72hours
all_series_config:
  stroke_width: 2
  extend_to_end: false
  curve: stepline
now:
  show: true
  label: now
  color: red
series:
  - entity: sensor.general_prices
    unit: €/kWh
    float_precision: 5
    data_generator: |
      let res = [];
      for (const [key, value] of Object.entries(entity.attributes.values)) {
        res.push([new Date(key).getTime(), value]);
      }
      return res.sort((a, b) => { return a[0] - b[0] })

I decided to process a moving average on NodeRed; no probs here, when i do the maths manually, i get the good time and the good average with the same data template

But when i’m using the same function used to plot the general prices, I now have a 2hr offset…

d243eac59fd293153f8c15fabbbe661ca7b18f33
d97ed78db5433d9fd5da84bee62eae1568c81a07

We can see there that between the lowest price in attributes and the lowest price in the graph, i have a 2hr offset.

Any idea where it could come from ?

Thanks

Did anyone manage to get it working with two y-axes? I have three series I want to plot, so I put the one I want on the right y-axis first and then the other two since everything after the first is supposed to end up on the second axis.

This doesn’t work for me, the two series on the same axis are offset for some reason, one of them not really matching the scale of any axis:

I want the white line to be on the left y-axis together with the orange one, but it appears to be on neither the left or right y-axis.

Is this a bug or am I doing something wrong?

has anyone seen this happening upon loading history:

Error: Invalid value for <svg> attribute height="NaN"

maybe its a latency issue of HA getting to the DB too slowly, but still there’s many errors there in just the flash of an eye…
and another one after clicking restart HA:

Yeah it’s a known issue but there is no fix and it’s safe to ignore it

1 Like

What an awesome card - I wonder what took me so long to discover it…

One question concerning the header: it seems to be very close to the top end of the card.

image

type: 'custom:apexcharts-card'
chart_type: radialBar
header:
  show: true
  show_states: true
  floating: true
  title: Used Space
all_series_config:
  show:
    name_in_header: false
series:
  - entity: sensor.ds_volume_1_volume_used
  - entity: sensor.ds_volume_1_used_space
    show:
      in_chart: false
apex_config:
  legend:
    show: false
  plotOptions:
    radialBar:
      hollow:
        size: 70%
      dataLabels:
        show: false
  stroke:
    lineCap: butt

I noticed that the #header comes with a padding of only 8px while I see most cards coming with 16px. Of course, I could use card_mod to adjust this, but I was wondering if I miss something?

bonjour, j’utilise votre code pour analyser des senseurs dans mon jardin, seulement je crois que je n’ai pas la dernière version que vous utilisez car je n’ai toujours pas la barre “now” au bon endroit!
auriez-vous la gentillesse de m’aider avec votre code le plus récent, c’est de cette façon que j’apprends, en regardant le code des autres.

merci!

Is there a way to start the chart dynamic at the first day of a month?

graph_span: 14d

Hi all,

I am trying to display solar monthly production history data which is in an influx DB.
All I get it the average amount for the total months as below which I have data for Jan to April 2021.

image

type: 'custom:apexcharts-card'
header:
  show: true
  title: Solar Monthly Production
  show_states: false
  colorize_states: true
apex_config:
  chart:
    type: line
    height: 270
  yaxis:
    min: 0
    max: 800
  stroke:
    show: true
    width: 1
  legend:
    show: true
graph_span: 12 month
span:
  end: month
series:
  - entity: sensor.solar_monthly_influx
    type: column
    name: Monthly Production
    color: green
    show:
      datalabels: true
update_interval: 1d

The data is in influxDB. It is added the last day of the month

root@pi4HA:~# influx -database 'sensors'                                        Connected to http://localhost:8086 version 1.8.5
InfluxDB shell version: 1.8.5
> SELECT "value" FROM "solar" WHERE "entity_id"='month'
name: solar
time                value
----                -----
1612085400000000000 588.8
1614504600000000000 596.5
1617183000000000000 736.7
1619775000000000000 572.9
>

and using a curl query

root@pi4HA:~# curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=sensors" --data-urlencode "q=SELECT \"value\" FROM \"solar\" WHERE \"entity_id\"='month'"
{
    "results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "solar",
                    "columns": [
                        "time",
                        "value"
                    ],
                    "values": [
                        [
                            "2021-01-31T09:30:00Z",
                            588.8
                        ],
                        [
                            "2021-02-28T09:30:00Z",
                            596.5
                        ],
                        [
                            "2021-03-31T09:30:00Z",
                            736.7
                        ],
                        [
                            "2021-04-30T09:30:00Z",
                            572.9
                        ]
                    ]
                }
            ]
        }
    ]
}

and here is my configuration.yaml

  - platform: influxdb
    host: 127.0.0.1
    queries:
      - name: solar_monthly_influx
        database: sensors
        measurement: solar
        field: "value"
        unit_of_measurement: kWh
        where: '"entity_id" = ''month'''   

Is it the data in influx that is the problem, the way I am accessing the data / sensor setup in HASS, or the card config ?

Thanks for any help.