ApexCharts card - A highly customizable graph card

I have the same issue using different data on different cards. This one is for generator (gas) input.
HA Web View:

HA Companion App View:

Code:

span:
  start: day
  offset: "-29d"
header:
  show: true
  show_states: true
  colorize_states: true
apex_config:
  yaxis:
    forceNiceScale: true
  legend:
    show: false
  chart:
    zoom:
      enabled: true
      type: x
      autoScaleYaxis: false
    toolbar:
      show: true
      tools:
        zoom: true
        zoomin: true
        zoomout: true
        pan: true
        reset: true
series:
  - entity: sensor.ac300_ac_generation_daily
    type: column
    name: Daily Generator Power Generated
    group_by:
      func: max
      duration: 1d

The data (sensor.ac300_ac_generation_daily) is coming from a utility helper, but I’m not sure that matters.

I continue to suspect something fishy, what is your purge period? if it is 11 days then both charts should not show data older than 23 april. Are you 100% sure that you are not using statistics for one of them?

No, I’m not 100% sure about anything when it comes to HA lol. A lot of this is still way over my head.

The original sensors come from the Bluetti AC300 via MQTT. This is a cumulative total counter. I use the Utility Helper to break it down into daily/monthly/yearly totals.

Here are the Utility Meter settings for the first post using the solar input breaking it down into daily stats:



Oh, I just looked at a longer data period for that utility helper of over a month. It does appear that the data is a mix of a mix of “History” (light blue) and “Long term statistics” (dark blue). I have no idea how to make it all show up in the graphs. I appreciate the hand-holding.

Thank you for pointing me in the right direction!! I believe I got it fixed by adding

statistics:
      type: state
      period: day
      align: end

to the entities in the chart. Strange that the companion app shows it all without this setting enabled

It should not, I remain confused :slight_smile:

Right, under the hood the companion app is just a wrapper around the website view, correct?

RomRider’s ApexCharts is 10 months behind.
I have a bug that was fixed upstream a while ago. Am I able to update this somehow?

Only if you create your own fork of the card and install that. I managed to create my own version a while ago and I found it to be not that straight forward if you are not experienced (as it was for me).
I checked a few existing forks and the one below updated recently, so maybe you can ask the owner to apply the apexcharts update (maybe even to 4.7.0?)

Making a working application or a fork that is used by others brings additional work (I have a few forks) which is I guess (part of) the reason that Romrider seems to have stepped out…someone should take over, but who ?

gramistella/apexcharts-card: :chart_with_upwards_trend: A Lovelace card to display advanced graphs and charts based on ApexChartsJS for Home Assistant

What could be wrong here? x-axis values not showing correctly.

        - type: custom:apexcharts-card
          cache: true
          stacked: true
          experimental:
            color_threshold: true
          apex_config:
            xaxis:
              type: datetime
              labels:
                datetimeFormatter:
                  day: ddd
          graph_span: 7d
          span:
            end: day
          show:
            last_updated: true
          header:
            show: true
            title: HVAC
            show_states: true
            colorize_states: true
          yaxis:
            - id: left
              min: 0
              max: 24
              decimals: 0
              apex_config:
                forceNiceScale: true
                tickAmount: 5
            - id: right
              opposite: true
              min: auto
              max: auto
              decimals: 1
              apex_config:
                forceNiceScale: false
                tickAmount: 5
          series:
            - entity: sensor.hvac_cooling_daily
              transform: return parseFloat(x).toFixed(1)
              yaxis_id: left
              stack_group: fan
              float_precision: 0
              show:
                header_color_threshold: true
                extremas: false
                as_duration: hour
                legend_value: false
              type: column
              name: Cooling
              group_by:
                func: max
                fill: last
                duration: 1d
            - entity: sensor.hvac_fan_on_daily
              transform: return parseFloat(x).toFixed(1)
              yaxis_id: left
              stack_group: fan
              float_precision: 0
              show:
                header_color_threshold: true
                extremas: false
                as_duration: hour
                legend_value: false
              type: column
              name: Fan On
              group_by:
                func: max
                fill: last
                duration: 1d
            - entity: sensor.outside_sensor_air_temperature
              yaxis_id: right
              unit: °F
              show:
                header_color_threshold: true
                extremas: true
                legend_value: false
              type: line
              opacity: 1
              curve: smooth
              stroke_width: 1
              name: Outside Avg
              fill_raw: last
              group_by:
                func: avg
                fill: last
                duration: 1d

got it:

            xaxis:
              type: datetime
              labels:
                datetimeFormatter:
                  day: ddd
                  month: ddd

I’m, tearing my now non-existent hair out trying to get to grips with creating a date range in my data generator.

I want to create a chart, a bit like the solar chart on the energy screen, that shows 24 hours for today which I will display multiple data sets on. None of those sets have any timestamps, I only have an a array of 24 values to plot at hourly intervals.

I have created two sensors…one that creates a timestamp as a string in the format 2025-05-08T00:00:00.000000+01:00 and another that takes that value and generates a timestamp from it which results in 1746658800000.

All good so far…in the apexchart config I have the following…

  - entity: sensor.algorithm
    type: column
    data_generator: |
      let stamp = hass.states['sensor.today_time_midnight_timestamp'].state;

      const now = new Date(stamp);
      const data = [];
      for(let i = 0; i < 24; i++) {
        data.push([now.getTime() + (i * 1000 * 60 * 60), hass.states['sensor.algorithm'].attributes.data.distribution[i] ]);
      }
      return data;

But instead of spreading the data out one per hour, I just get one column for the first hour.

Now the weird part is, if I replace the stamp with either a string or unix timestamp, everything renders correctly.

So the following works properly…just hard coded the stamp value!

  - entity: sensor.algorithm
    type: column
    data_generator: |
      let stamp = 1746658800000;

      const now = new Date(stamp);
      const data = [];
      for(let i = 0; i < 24; i++) {
        data.push([now.getTime() + (i * 1000 * 60 * 60), hass.states['sensor.algorithm'].attributes.data.distribution[i] ]);
      }
      return data;

So what am I doing wrong here…the sensor has the right value, in fact I output it in place of the data for the columns to prove it was there.

I think I must be getting back a value that is not the unix timestamp, but if not…why? It displays fine in the template editor.

This is the last piece of my puzzle and it’s got me beat right now.

Could anyone provide an example of how to define a gradient as an array? I’m trying to plot an area with a gradient and a line on top of it with no gradient.

Is there an other possibility to set the time to show dynamically? as mentioned GitHub - RomRider/apexcharts-card: 📈 A Lovelace card to display advanced graphs and charts based on ApexChartsJS for Home Assistant it is not possible to add a variable in the graph_span section:

CODE

`square: false
type: grid
cards:

  • features:
    • type: custom:service-call
      entries:
      • type: selector
        entity_id: input_select.showtime
        options:
        • entity_id: input_select.showtime
          option: 12h
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 12h
          target:
          entity_id: input_select.showtime
          label: 12h
          type: button
        • entity_id: input_select.showtime
          option: 1d
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 1d
          target:
          entity_id: input_select.showtime
          label: 1d
          type: button
        • entity_id: input_select.showtime
          option: 2d
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 2d
          target:
          entity_id: input_select.showtime
          label: 2d
          type: button
        • entity_id: input_select.showtime
          option: 3d
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 3d
          target:
          entity_id: input_select.showtime
          label: 3d
          type: button
        • entity_id: input_select.showtime
          option: 1w
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 1w
          target:
          entity_id: input_select.showtime
          label: 1w
          type: button
        • entity_id: input_select.showtime
          option: 2w
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 2w
          target:
          entity_id: input_select.showtime
          label: 2w
          type: button
        • entity_id: input_select.showtime
          option: 1m
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 1m
          target:
          entity_id: input_select.showtime
          label: 1m
          type: button
        • entity_id: input_select.showtime
          option: 2m
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 2m
          target:
          entity_id: input_select.showtime
          label: 2m
          type: button
        • entity_id: input_select.showtime
          option: 3m
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 3m
          target:
          entity_id: input_select.showtime
          label: 3m
          type: button
        • entity_id: input_select.showtime
          option: 6m
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 6m
          target:
          entity_id: input_select.showtime
          label: 6m
          type: button
        • entity_id: input_select.showtime
          option: 1j
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 1j
          target:
          entity_id: input_select.showtime
          label: 1j
          type: button
        • entity_id: input_select.showtime
          option: 2j
          tap_action:
          action: perform-action
          perform_action: input_select.select_option
          data:
          option: 2j
          target:
          entity_id: input_select.showtime
          label: 2j
          type: button
          autofill_entity_id: true
          haptics: true
          styles: “”
          type: tile
          entity: input_select.showtime
          features_position: bottom
          vertical: false
          hide_state: true
          show_entity_picture: false
          color: rgba(158,158,158,255)
          grid_options:
          columns: full
          rows: none
          card_mod:
          style: |
          ha-card .content {
          display: none !important;
          }
          ha-card {
          padding-top: 10px !important;
          height: 62px !important;
          }
  • type: custom:apexcharts-card
    update_delay: 10000ms
    graph_span: “{{ states(‘input_select.showtime’) }}”
    span:
    end: minute
    header:
    show: true
    title: Aussentemperatur
    show_states: true
    colorize_states: true
    series:
    • entity: sensor.hmip_swo_pr_123_aussen_temperatur
      unit: °C
      name: Aussentemperatur
      stroke_width: 1.5
      color: “#4b66ae
      curve: straight
      statistics:
      period: 5minute
      show:
      extremas: true
    • entity: sensor.temperature_feels_like
      unit: °C
      name: gefühlte Temperatur
      stroke_width: 1.5
      color: “#efbc3d
      curve: straight
      statistics:
      period: 5minute
      yaxis:
    • decimals: 1
      show:
      last_updated: true
      apex_config:
      yaxis:
      forceNiceScale: true
      chart:
      height: 300
      columns: 1
      grid_options:
      columns: full`

Newbie here: how can I show only the last X hours of a graph, but keep the possibility to zoom out? If I use
graph_span: 8h
I am seeing last 8 hours in my graph, I can zoom in but I cannot zoom out.
What else should I edit?

Yours seems to be the one with apexcharts 4.7.0.

Do you have any issue with your fork, or can we use it as replacement of RomRider’s?

Also: why did you replace actions/[email protected] with actions/cache@v4 ? isn’t it a step back?

I am only toying around and in no (!) way (…I want to be absolutely clear…) provide any guarantee for support or even keep it alive
You can try if the one I have works, there is no risk in that.

EDIT: @kouny I made a 470 specific release without all the c…p it had before, have a look

1 Like

hi guys,

I am having trouble to display the daily energy consumption with apexchart. The apexchart would just not load when i insert the card’s YAML and i would need to reboot HA. Even if it loads, i am not seeing the bar chart in daily aggregation. It looks more like a daily increasing line. May i know what is wrong with my code below?

Thanks experts.

configuration.yaml

utility_meter:
    utility_meter_energy_daily_aircond:
        source: sensor.aircond_today_s_consumption
        cycle: daily

the attributes of the utility_meter_energy_daily_aircond

state_class: total_increasing
status: collecting
last_period: 2.089
last_valid_state: 9.169
last_reset: 2025-05-13T16:00:00.001833+00:00
next_reset: 2025-05-15T00:00:00+08:00
unit_of_measurement: kWh
device_class: energy

my apexchart card:

type: custom:config-template-card
entities:
  - sensor.utility_meter_energy_daily_aircond
variables:
  cust_span: >-
    parseInt(states['input_number.utility_bill_energy_curr_cycle_days'].state)+"d"
card:
  type: custom:apexcharts-card
  header:
    show: true
    title: Current month usage
    show_states: false
  graph_span: ${cust_span} #test 7d
  span:
    start: day
  series:
    - entity: sensor.utility_meter_energy_daily_aircond
      type: column
      group_by: 
        duration: 1d
      type: column
      show:
        in_header: false
        extremas: true

nevermind i have solved it myself.

the entities sensor.utility_meter_energy_daily_aircond under the custom:config-template-card is causing the whole card to be re-rendered every seconds and result in high cpu usage. so i have changed it to the below:

type: custom:config-template-card
entities:
  - input_number.utility_bill_energy_curr_cycle_days
variables:
  cust_span: >-
    parseInt(states['input_number.utility_bill_energy_curr_cycle_days'].state)+"d"
  cust_offset: >-
    -(parseInt(states['input_number.utility_bill_energy_curr_cycle_days'].state)-1)+"d"
card:
  type: custom:apexcharts-card
  header:
    show: true
    title: Current month usage
    show_states: true
    colorize_states: false
  graph_span: ${cust_span}
  span:
    start: day
    offset: ${cust_offset}
  series:
    - entity: sensor.utility_meter_energy_curr_bill_cycle_aircond
      show:
        in_chart: false
        name_in_header: false
      float_precision: 3
    - entity: sensor.aircond_today_s_consumption
      type: column
      group_by:
        func: max
        duration: 1d
      show:
        in_header: false
        extremas: true
      float_precision: 3

Are you allowed to use variable in the xaxis -x line of code? The variable is simply a Unix timestamp that should work in the graph. If I cut and paste the timestamp directly into x: e.g. - x: 1747335600000 the annotation appears in graph. But I can’t seem to call it as a variable anyway I format it. Even if I put the sensor directly into the x: it doesn’t do anything. Any help is appreciated.

type: custom:config-template-card
template: true
entities:
  - sensor.sunset_timestamp_ms
  - sensor.patio_weather_sensor_temperature
variables:
  - SUNSET: states['sensor.sunset_timestamp_ms'].state
  - MOONSET: "{{ states('sensor.sunset_timestamp_ms') }}"
card:
  type: custom:apexcharts-card
  graph_span: 24h
  span:
    start: day
  header:
    show: true
    title: "Sunset (ms): $ [[MOONSET]]"
  series:
    - entity: sensor.patio_weather_sensor_temperature
      name: Outside Temp
      type: line
  apex_config:
    annotations:
      xaxis:
        - x: [[SUNSET]]
          borderColor: "#FF4500"
          strokeDashArray: 4
          label:
            text: Sunset
            orientation: vertical
            position: top
            style:
              color: "#FF4500"