ApexCharts card - A highly customizable graph card

Hi @RomRider and thanks for card and support!
It is working fine.

I have a question - is it possible to change the datasource “on the fly”?
I have found (in ApexCharts docu) the “customIcons” in toolbar with the possible mapping to a function, but not sure how it could work here.
I want to click anything and change the URL (and reload the chart) in this code snippet:

    data_generator: |
      var data = [];
      url = new URL("http://homeassistant.local:8123/local/data.csv");

      function getValue(){
        var request = new XMLHttpRequest();
        request.open('GET',url,false);
...
       return data1;
      }
      return getValue();

How did you get so many points? I’m trying to do a stock price chart but I only get points every hour.

Hi, thanks for such a great card.
I am trying to graph the energy used every hour coming from some utility_meters, most days with good results, but one thay and another I get this graph:
image
At the change of day (hour 0) the chart calculates a negative ammount.
Here is the relevant config for the “grid vall” (green) meter:

type: custom:apexcharts-card
graph_span: 24h
span:
  start: hour
  offset: '-24h'
update_delay: 3s
update_interval: 1min
cache: true
header:
  show: true
  show_states: true
series:
  - entity: sensor.energy_current_hour
    name: solar sud
    color: blue
    fill_raw: 'null'
    group_by:
      duration: 1h
    type: area
    opacity: 0.1
    stroke_width: 1
    curve: stepline
  - entity: sensor.main_energy_day_vall
    name: grid vall
    color: rgb(76,161,55)
    fill_raw: last
    group_by:
      func: diff
      duration: 1h
      fill: last
    type: area
    opacity: 0.2
    stroke_width: 1
    curve: stepline

Any advice for solving this? (apart from limiting the y_axis to a min value of 0)?

Not sure what you mean with points, but the graph shows the power values (W) from my inverter.
The energy values (kWh) are calculated every hour.

I would like colors for certain y-values. I thought I could just use a fixed value sensor, like this:

type: custom:apexcharts-card
experimental:
  color_threshold: true
series:
  - entity: sensor.value_50
    type: area
    color_threshold:
      - value: -10
        color: blue
      - value: 0
        color: blue
      - value: 20
        color: green
      - value: 40
        color: orange

But this does not seem to work, the area color is always one solid color. I also tried to use transform: return 80, but this also does not work.
When I just change the sensor by an actual sensor, the coloring works. When I use transform on a sensor, it works when i do a ‘return x;’ but when I try ‘return x/2+50;’ the coloring does not work.

Any idea what is wrong here?

I have a chart with two series, (today & tomorrow) taken from a sensor that fetches prices from the web. There is a gap in the line chart when transitioning from today till tomorrow. Any suggestions on how to connect these two series without the gap? I’m guessing it is in the data_generator part but I’m not proficient enough to figure this out on my own.

The gap:

The series part of the card code:

series:
  - entity: sensor.nordpool_kwh_oslo_nok_3_10_025
    yaxis_id: first
    name: Pris i dag
    type: area
    curve: smooth
    extend_to_end: false
    float_precision: 3
    stroke_width: 2
    opacity: 0.09
    color: cyan
    show:
      in_header: false
      legend_value: false
    data_generator: |
      return entity.attributes.raw_today.map((p) => {
        return [new Date(p.start), p.value];
      });
  - entity: sensor.nordpool_kwh_oslo_nok_3_10_025
    yaxis_id: first
    name: Pris i morgen
    type: area
    curve: smooth
    extend_to_end: false
    float_precision: 3
    stroke_width: 2
    opacity: 0.09
    color: magenta
    show:
      in_header: false
      legend_value: false
    data_generator: |
      return entity.attributes.raw_tomorrow.map((p) => {
        return [new Date(p.start), p.value];
      });

The prices (long list), from the sensor:

raw_today: 
- start: '2022-01-27T00:00:00+01:00'
  end: '2022-01-27T01:00:00+01:00'
  value: 1.584
- start: '2022-01-27T01:00:00+01:00'
  end: '2022-01-27T02:00:00+01:00'
  value: 1.517
- start: '2022-01-27T02:00:00+01:00'
  end: '2022-01-27T03:00:00+01:00'
  value: 1.458
- start: '2022-01-27T03:00:00+01:00'
  end: '2022-01-27T04:00:00+01:00'
  value: 1.44
- start: '2022-01-27T04:00:00+01:00'
  end: '2022-01-27T05:00:00+01:00'
  value: 1.442
- start: '2022-01-27T05:00:00+01:00'
  end: '2022-01-27T06:00:00+01:00'
  value: 1.473
- start: '2022-01-27T06:00:00+01:00'
  end: '2022-01-27T07:00:00+01:00'
  value: 1.536
- start: '2022-01-27T07:00:00+01:00'
  end: '2022-01-27T08:00:00+01:00'
  value: 1.607
- start: '2022-01-27T08:00:00+01:00'
  end: '2022-01-27T09:00:00+01:00'
  value: 1.68
- start: '2022-01-27T09:00:00+01:00'
  end: '2022-01-27T10:00:00+01:00'
  value: 1.667
- start: '2022-01-27T10:00:00+01:00'
  end: '2022-01-27T11:00:00+01:00'
  value: 1.666
- start: '2022-01-27T11:00:00+01:00'
  end: '2022-01-27T12:00:00+01:00'
  value: 1.654
- start: '2022-01-27T12:00:00+01:00'
  end: '2022-01-27T13:00:00+01:00'
  value: 1.634
- start: '2022-01-27T13:00:00+01:00'
  end: '2022-01-27T14:00:00+01:00'
  value: 1.65
- start: '2022-01-27T14:00:00+01:00'
  end: '2022-01-27T15:00:00+01:00'
  value: 1.666
- start: '2022-01-27T15:00:00+01:00'
  end: '2022-01-27T16:00:00+01:00'
  value: 1.666
- start: '2022-01-27T16:00:00+01:00'
  end: '2022-01-27T17:00:00+01:00'
  value: 1.672
- start: '2022-01-27T17:00:00+01:00'
  end: '2022-01-27T18:00:00+01:00'
  value: 1.661
- start: '2022-01-27T18:00:00+01:00'
  end: '2022-01-27T19:00:00+01:00'
  value: 1.61
- start: '2022-01-27T19:00:00+01:00'
  end: '2022-01-27T20:00:00+01:00'
  value: 1.561
- start: '2022-01-27T20:00:00+01:00'
  end: '2022-01-27T21:00:00+01:00'
  value: 1.556
- start: '2022-01-27T21:00:00+01:00'
  end: '2022-01-27T22:00:00+01:00'
  value: 1.578
- start: '2022-01-27T22:00:00+01:00'
  end: '2022-01-27T23:00:00+01:00'
  value: 1.545
- start: '2022-01-27T23:00:00+01:00'
  end: '2022-01-28T00:00:00+01:00'
  value: 1.524

raw_tomorrow: 
- start: '2022-01-28T00:00:00+01:00'
  end: '2022-01-28T01:00:00+01:00'
  value: 1.524
- start: '2022-01-28T01:00:00+01:00'
  end: '2022-01-28T02:00:00+01:00'
  value: 1.507
- start: '2022-01-28T02:00:00+01:00'
  end: '2022-01-28T03:00:00+01:00'
  value: 1.507
- start: '2022-01-28T03:00:00+01:00'
  end: '2022-01-28T04:00:00+01:00'
  value: 1.514
- start: '2022-01-28T04:00:00+01:00'
  end: '2022-01-28T05:00:00+01:00'
  value: 1.52
- start: '2022-01-28T05:00:00+01:00'
  end: '2022-01-28T06:00:00+01:00'
  value: 1.605
- start: '2022-01-28T06:00:00+01:00'
  end: '2022-01-28T07:00:00+01:00'
  value: 1.639
- start: '2022-01-28T07:00:00+01:00'
  end: '2022-01-28T08:00:00+01:00'
  value: 1.711
- start: '2022-01-28T08:00:00+01:00'
  end: '2022-01-28T09:00:00+01:00'
  value: 1.781
- start: '2022-01-28T09:00:00+01:00'
  end: '2022-01-28T10:00:00+01:00'
  value: 1.783
- start: '2022-01-28T10:00:00+01:00'
  end: '2022-01-28T11:00:00+01:00'
  value: 1.793
- start: '2022-01-28T11:00:00+01:00'
  end: '2022-01-28T12:00:00+01:00'
  value: 1.798
- start: '2022-01-28T12:00:00+01:00'
  end: '2022-01-28T13:00:00+01:00'
  value: 1.791
- start: '2022-01-28T13:00:00+01:00'
  end: '2022-01-28T14:00:00+01:00'
  value: 1.782
- start: '2022-01-28T14:00:00+01:00'
  end: '2022-01-28T15:00:00+01:00'
  value: 1.779
- start: '2022-01-28T15:00:00+01:00'
  end: '2022-01-28T16:00:00+01:00'
  value: 1.79
- start: '2022-01-28T16:00:00+01:00'
  end: '2022-01-28T17:00:00+01:00'
  value: 1.861
- start: '2022-01-28T17:00:00+01:00'
  end: '2022-01-28T18:00:00+01:00'
  value: 1.878
- start: '2022-01-28T18:00:00+01:00'
  end: '2022-01-28T19:00:00+01:00'
  value: 1.844
- start: '2022-01-28T19:00:00+01:00'
  end: '2022-01-28T20:00:00+01:00'
  value: 1.777
- start: '2022-01-28T20:00:00+01:00'
  end: '2022-01-28T21:00:00+01:00'
  value: 1.712
- start: '2022-01-28T21:00:00+01:00'
  end: '2022-01-28T22:00:00+01:00'
  value: 1.705
- start: '2022-01-28T22:00:00+01:00'
  end: '2022-01-28T23:00:00+01:00'
  value: 1.654
- start: '2022-01-28T23:00:00+01:00'
  end: '2022-01-29T00:00:00+01:00'
  value: 1.56

I love this!! However I had a question, for the radial sensor, how do I add my own icon? Im not familiar with the coding here, how did u obtain the data:image/svg…etc.

Hello everyone, please tell me how to rotate the characters?
rotate

- x: '${new Date(states[''sensor.sunset''].attributes.yesterday).getTime()}'
  label:
    text: 🌄
    borderWidth: 0
    style:
      background: '#0000'
      fontSize: '18px'

next doesn’t work for me :frowning:

      rotate: 90
      rotate: 90deg
      transform: rotate(90deg)

and how to highlight the vertical bar next to the symbol with a different color?

Really great project, I like the charts!
I am using this for the gas prices of my local filling station. As this is shut down during the night, there is no data. I see that there is the possibility to fill the empty data, but I would just like to exclude it, basically taking out 22.00-6.00. I see the start and end option, but that seems to only work for one continuous timeline (start each morning from 6.00), not if I display multiple days.
Any way to achieve that?
grafik

I like to make these mini icons. Is it possible to decrease the space reserved for the header? I can do so already a bit by setting floating: true, but with this option the “action” is no longer working. Is it for example possible to have the graph span the entire card, with still overlaying the actual value and title?

Capture

Code so far


type: custom:apexcharts-card
header:
  show: true
  show_states: true
  floating: true
experimental:
  color_threshold: true
all_series_config:
  stroke_width: 0
  opacity: 0.7
  type: area
series:
- entity: sensor.myenergi_my_home_power_grid
    name: Grid
    curve: smooth
    extend_to_end: false
    color_threshold:
      - value: -1
        color: '#1b8a5a'
      - value: 1
        color: '#ee3e32'
    group_by:
      func: avg
      duration: 15min
layout: minimal
graph_span: 24h
update_interval: 10 min
span:
  start: day
apex_config:
  chart:
    height: 110px
    width: 100px
style: |
  ha-card {font-size: 10px;}    

How can i plot a sensor value, but subtracting the first value in the graph?
The sensor is cumulative, and i want to show the daily increase.

Hi, what sensor have you used for your TV Consumption? have you a config for me? I use Philips TV integration. Thanks

I use the following in my sensors.yaml:

- platform: history_stats
  name: watched TV today
  entity_id: media_player.lg_fernseher
  state: "on"
  type: time
  start: "{{ now().replace(hour=0, minute=0, second=0) }}"
  end: "{{ now() }}"

It grows over the day and then starts fresh the next day.

3 Likes

Thank you very much

- platform: openexchangerates
  name: Euro Currency
  api_key: xxxx
  quote: EUR

- platform: template
  sensors:
    helium_wallet_value:
      value_template: "{{ ((states('sensor.helium_hnt_oracle_price') | float * states('sensor.helium_wallet_xxxxx') | float) * states('sensor.euro_currency') | float) | round(2) }}"
      unit_of_measurement: "EUR"

- platform: template
  sensors:
    helium_wallet_today_value:
      value_template: "{{ ((states('sensor.helium_hnt_oracle_price') | float * states('sensor.helium_wallet_today') | float) * states('sensor.euro_currency') | float) | round(2) }}"
      unit_of_measurement: "EUR"

is there no way to remove legends? I am making a power graph for devices in my home, and I don’t need legends when I can press them. I can only remove value, but not the legend it self which is a huge bummer

also, how do I get rid of so many decimals, it happens from time to time, about 20% of the time

code:

type: custom:apexcharts-card
update_interval: 1min
chart_type: donut
apex_config:
  plotOptions:
    pie:
      donut:
        background: transparent
        labels:
          show: true
          total:
            show: true
header:
  show: true
  title: Strømforbruk akkurat nå
  show_states: false
  colorize_states: true
series:
  - entity: sensor.power_bjorganveien_39
    name: Other
    show:
      legend_value: false
    transform: >-
      return parseFloat(x) -
      parseFloat(hass.states['sensor.varmepumpe_stikk_stue_electric_consumption_w'].state)
      -  parseFloat(hass.states['sensor.varmepumpe_kjellerstue_power'].state) -
      parseFloat(hass.states['sensor.kjoleskap_kjokken_power'].state) -
      parseFloat(hass.states['sensor.vvb_vaskerom_power'].state) - 
      parseFloat(hass.states['sensor.vaskemaskin_vaskerom_power'].state) -
      parseFloat(hass.states['sensor.tv_hifi_stue_power'].state) -
      parseFloat(hass.states['sensor.stekeovn_kjokken_power'].state) -
      parseFloat(hass.states['sensor.mikrobolgeovn_kjokken_power'].state) -
      parseFloat(hass.states['sensor.gulvvarme_bad_electric_consumed_w'].state)
      -
      parseFloat(hass.states['sensor.gulvvarme_matheo_electric_consumed_w'].state)
      -
      parseFloat(hass.states['sensor.gulvvarme_pabygg_electric_consumed_w'].state)
      -
      parseFloat(hass.states['sensor.gulvvarme_emma_electric_consumed_w'].state)
      -
      parseFloat(hass.states['sensor.gulvvarme_gang_electric_consumed_w'].state)
  - entity: sensor.varmepumpe_stikk_stue_electric_consumption_w
    show:
      legend_value: false
  - entity: sensor.varmepumpe_kjellerstue_power
    show:
      legend_value: false
  - entity: sensor.kjoleskap_kjokken_power
    show:
      legend_value: false
  - entity: sensor.vvb_vaskerom_power
    show:
      legend_value: false
  - entity: sensor.vaskemaskin_vaskerom_power
    show:
      legend_value: false
  - entity: sensor.tv_hifi_stue_power
    show:
      legend_value: false
  - entity: sensor.stekeovn_kjokken_power
    show:
      legend_value: false
  - entity: sensor.mikrobolgeovn_kjokken_power
    show:
      legend_value: false
  - entity: sensor.oppvaskmaskin_kjokken_power
    show:
      legend_value: false
  - entity: sensor.gulvvarme_bad_electric_consumed_w
    show:
      legend_value: false
  - entity: sensor.gulvvarme_matheo_electric_consumed_w
    show:
      legend_value: false
  - entity: sensor.gulvvarme_pabygg_electric_consumed_w
    show:
      legend_value: false
  - entity: sensor.gulvvarme_emma_electric_consumed_w
    show:
      legend_value: false
  - entity: sensor.gulvvarme_gang_electric_consumed_w
    show:
      legend_value: false

I guess float_precision: 0 should do it.

Hallo RomRider, thanks for this marvelous effort, I discovered this thread few weeks ago and I cant stop reading it. I need for my Lovelace dashboard st. like a combination of apex line chart and history graph… I have found some samples here at the forum and so far I succeded to implement it… as a sample this pic:

image

But the HA history graph itself doesn’t have the option for time span like you prepared in the apexchart integration… is it plz somehow possible to get it included also?
I have noticed in the apexcharts .js documentation there is a kind of graph called “Timeline chart - group series”

image

and I hope this graph might be used for this purpose(?)

The goal is to get in one graph both - the numeric values and also non-numeric values (such as DHW water tank states - like: charging, discharging, charged… etc. or service allerts, like “heatpump running”, “blocked” “waiting” … etc. to be able to track the temperatures and also the states back in time.

So far I have implemented dynamic “hours-to-show” option and I only succeeded to combine the custom minigraph and historygraph together as the best result. This of course doesnt have the span option, but looks a bit better than the previous sample of apex and history combined:

I also play a bit with the animation or blinking effect to visualize the current state a bit better.
It would be great to have the span option (instead of just dynamic “hours-to-show” like I have now) implemented and keep the look as much as this last sample graph.

(one more sample - switched to 48 hours, and mouse hover on the history graph to see the details…)

Is there plz any way how to go furhter?
Thank you indeed.
Willy

You can track https://github.com/RomRider/apexcharts-card/issues/109. I think it is a prerequisite for what you want to do.