ApexCharts card - A highly customizable graph card

Just to put it here, if someone is having same kind of problems:

  • if combining multiple y series with into on timeline, do not use transform. Try to use only original data values. I could use value transformation in data_generator -block

Working chart

New code

type: custom:config-template-card
variables:
  LOWPOINT: states['sensor.nordpool_apexchart_y_min']
  MOVINGAVERAGE: states['sensor.nordpool_price_today_average_whole_day_longterm_mean']
entities:
  - ${MOVINGAVERAGE.entity_id}
card:
  type: custom:apexcharts-card
  graph_span: 13d
  span:
    start: day
    offset: '-7d'
  apex_config:
    xaxis:
      labels:
        datetimeFormatter:
          day: dd ddd
    chart:
      height: 300%
  yaxis:
    - id: tanaan
      decimals: 3
      apex_config:
        tickAmount: 4
    - id: power
      opposite: true
      decimals: 0
      min: 0
    - id: temperature
      opposite: true
      decimals: 0
  show:
    last_updated: true
  experimental:
    brush: true
    color_threshold: true
  brush:
    selection_span: 13d
    apex_config:
      xaxis:
        labels:
          datetimeFormatter:
            day: dd ddd
  header:
    title: Sähkön hinta, tuulivoima ja lämpötila
    show: true
    show_states: true
    colorize_states: true
  now:
    show: true
    label: Nyt
  series:
    - entity: sensor.fingrid_wind_power_generation_forecast_hourly
      yaxis_id: power
      name: Windpower gen forecast
      type: line
      curve: stepline
      stroke_width: 2
      color: grey
      data_generator: |
        return entity.attributes.events.event.map((d, index) => {
          return [new Date(d["start_time"]).getTime(), entity.attributes.events.event[index]["value"]*1];
        });
      show:
        header_color_threshold: true
        legend_value: false
        in_header: false
        name_in_header: false
        extremas: true
    - entity: weather.openweathermap
      yaxis_id: temperature
      name: Lämpötilaennuste
      curve: stepline
      stroke_width: 2
      color: purple
      data_generator: |
        return entity.attributes.forecast.map((entry) => {
              return [new Date(entry.datetime).getTime(), entry.temperature];
            });
      show:
        header_color_threshold: true
        legend_value: false
        in_header: false
        name_in_header: false
        extremas: true
    - entity: sensor.weather_combined_temperature
      yaxis_id: temperature
      name: Lämpötila
      curve: stepline
      stroke_width: 2
      extend_to: now
      color: purple
      show:
        header_color_threshold: true
        legend_value: false
        in_header: false
        name_in_header: false
        extremas: true
    - entity: sensor.nordpool_fi
      name: Tänään
      yaxis_id: tanaan
      show:
        in_brush: true
        in_chart: true
        extremas: true
        in_header: raw
        header_color_threshold: true
        legend_value: false
      type: column
      data_generator: |
        return entity.attributes.raw_today.map((start, index) => {
          return [new Date(start["start"]).getTime(), entity.attributes.raw_today[index]["value"]*0.01];
        });
      color_threshold:
        - value: ${MOVINGAVERAGE.state * 0.1}
          color: lightblue
        - value: ${MOVINGAVERAGE.state * 0.33}
          color: darkgreen
        - value: ${MOVINGAVERAGE.state * 0.75}
          color: goldenrod
        - value: ${MOVINGAVERAGE.state * 1.25}
          color: darkred
    - entity: sensor.nordpool_fi
      name: Huomenna
      yaxis_id: tanaan
      show:
        in_brush: true
        in_chart: true
        extremas: false
        in_header: false
        header_color_threshold: true
        legend_value: false
      type: column
      data_generator: |
        return entity.attributes.raw_tomorrow.map((start, index) => {
          return [new Date(start["start"]).getTime(), entity.attributes.raw_tomorrow[index]["value"]*0.01];
        });
      color_threshold:
        - value: ${MOVINGAVERAGE.state * 0.1}
          color: lightblue
        - value: ${MOVINGAVERAGE.state * 0.33}
          color: darkgreen
        - value: ${MOVINGAVERAGE.state * 0.75}
          color: goldenrod
        - value: ${MOVINGAVERAGE.state * 1.25}
          color: darkred
    - entity: sensor.nordpool_price_now_euro
      name: Price_euro
      yaxis_id: tanaan
      show:
        in_brush: true
        in_chart: true
        extremas: true
        in_header: false
        header_color_threshold: true
        legend_value: false
      type: column
      color_threshold:
        - value: ${MOVINGAVERAGE.state * 0.1}
          color: lightblue
        - value: ${MOVINGAVERAGE.state * 0.33}
          color: darkgreen
        - value: ${MOVINGAVERAGE.state * 0.75}
          color: goldenrod
        - value: ${MOVINGAVERAGE.state * 1.25}
          color: darkred
    - entity: sensor.nordpool_price_now_euro
      name: Price_euro
      yaxis_id: tanaan
      offset: '-7d'
      show:
        in_brush: true
        in_chart: true
        extremas: true
        in_header: false
        header_color_threshold: true
        legend_value: false
      type: column
      color_threshold:
        - value: ${MOVINGAVERAGE.state * 0.1}
          color: lightblue
        - value: ${MOVINGAVERAGE.state * 0.33}
          color: darkgreen
        - value: ${MOVINGAVERAGE.state * 0.75}
          color: goldenrod
        - value: ${MOVINGAVERAGE.state * 1.25}
          color: darkred

I love ApexCharts.
Sadly, the performance is horrible, at least on Firefox. Even with rather few data points, the fans of my laptop spin up quickly, when I open any page with such a card.

Has anyone been able to get “extend_to:” to work when using “data_generator:” ? i can’t get it to disappear no matter what I try

I have this working for some of my forecast graphs…extend_to: false works for me

How can I achieve having the y=0 aligned for the line charts?

Hi @jonasvath ,

I’m glad that my graph was useful to you!

Unfortunately I can’t make any useful suggestions seeing only an image: maybe I should see the code and how you sensors work…

But, if this can be useful to you, I’ve currently switched from that graph (apex chart) to another chart made with the following hacs integration: history explorer card.

I can paste here the code of my new graph, so that maybe you can try this different integration and configuration!

GIF

Wondershare Uniconverter 15_000001

How it works

I’ve created the following template sensor in yaml:

template:
  - sensor:
      - name: riscaldamento - app 9 - camera Andrea - grafico temperatura - sta riscaldando
        state: >
          {% if is_state_attr("climate.riscaldamento_app_9_camera_andrea_tado_homekit_termosifone_va3881777920","hvac_action","heating") -%}
            {{ states("sensor.temperatura_app_9_camera_andrea") }}
          {%- else -%}
            0
          {%- endif %}

The template sensor has the following values:

  • when tado is heating → the sensor has the same value of current temperature
  • when tado is not heating → the sensor has value 0

Then I’ve created the graph with the following code:

type: custom:history-explorer-card
cardName: Appartamento 9
graphs:
  - type: line
    title: Temperatura (arancione = sta riscaldando)
    entities:
      - entity: >-
          sensor.riscaldamento_app_9_camera_andrea_grafico_temperatura_sta_riscaldando
        name: sta riscaldando
        color: RGBA(255,161,80,0.5)
        fill: RGBA(255,161,80,0.5)
        width: 0
        process: |
          ( state > 0 ) ? state : "unavailable"
      - entity: sensor.temperatura_app_9_camera_andrea
        name: temperatura
        color: rgba(244, 209, 96, 1)
        width: 2
        fill: rgba(244, 209, 96, 0.2)
    options:
      showSamples: false
showCurrentValues: true
combineSameUnits: true
refresh:
  interval: 60
defaultTimeRange: 12h
defaultTimeOffset: 15m
header: hide
uiLayout:
  toolbar: bottom
  selector: hide
labelsVisible: false
labelAreaWidth: 35
tooltip:
  showDuration: true
showUnavailable: true
legendVisible: false
lineMode: curves
uiColors:
  buttons: rgba(0,0,0,0.05)


In the graph I’ve set two series:

  • a series showing current temperature (light yellow)
  • a serie showing the template sensor (darker yellow showing when Tado is heating) → with “process” option in the graph code I manipulate the data of this series so that: a) when the template sensor is > 0, in the graph I see the the serie in dark yellow; b) when the template sensor is = 0, the graph considers the series unavailable and nothing appears on the graph.
1 Like

I tried to follow the above receipt to display a partial donut, but I failed :sob:
What I get:
image
What I would like to get (a standard gauge):
image
Any advice is warmly welcomed :pray:
YAML:

- type: custom:apexcharts-card
  chart_type: donut
  apex_config:
    legend:
      show: false
    plotOptions:
      radialBar:
        offsetY: 0
        startAngle: -108
        endAngle: 108
        hollow:
          size: 65%
    dataLabels:
      name:
        show: false
      value:
        show: false
    track:
      strokeWidth: 80%
      margin: 0
    chart:
      height: 200
    grid:
      padding:
        left: 0
        right: 0
        bottom: 20
  header:
    show: true
    show_states: true
  experimental:
    color_threshold: true
  series:
    - entity: sensor.memory_use_percent
      color_threshold:
        - value: 0
          color: '#6AA84F'
        - value: 60
          color: '#3C78D8'
        - value: 85
          color: '#A61C00'

Change the chart_type to “radialBar” from “dounut”

Hi all,

any change someone can help me with the following:

I`m not very experienced with yaml code but like to create a pie chart from 1 single entity which changes

This entity is the operation mode from my ecodan heat pump
below is the yaml code:

case 0: return std::string("${stop}");
case 1: return std::string("${Warm water}");
case 2: return std::string("${heating}");
case 3: return std::string("${cooling}");
case 5: return std::string("${freeze_stat}");
case 6: return std::string("${legionella}");
default: return std::to_string(value);[/code}

I was tryiing to get a pie chart like below but no luck… (mine is in dutch)

type: custom:apexcharts-card
graph_span: 168h
experimental:
  color_threshold: true
header:
  show: true
  title: Fridge
  show_states: true
series:
  - entity: sensor.mitsubishi_werkings_mode
    show:
      extremas: true
    color_threshold:
      - value: 'Stop'
        color: grey
      - value: 'Verwarmen'
        color: orange
      - value: 'Ontdooien'
        color: green
      - value: 'Warm water'
        color: red
      - value: 'Legionella'
        color: yellow
      - value: 'Koelen'
        color: blue

thx in advance

ps:

this is the default as is

image

type: history-graph
entities:
  - sensor.mitsubishi_werkings_mode

Hi @andrea.magnani01,

I did the exact same thing like you with the apex chart.

But many thanks for your suggestion of the history explorer card, this works even better!

Have a great week! :slight_smile:

1 Like

I’m happy to do my little part helping somebody and contributing to the wonderful community of home assistant enthusiasts!
Have a great life! :smile:

2 Likes

Hello @andrea.magnani01 and @Kertz1954,

please excuse me if I have sneaked into this thread :wink:
This is my first post in this forum and I took my first steps in Home Assistant a few days ago.
I have been using ioBroker for a few years and now I want to switch. I have been looking for your solution Andrea for a long time. Thank you very much for that. I would like to use this card to visualize my oil burner starts with the temperature of my water buffer tank. I would like to use this card to visualize my oil burner starts with the temperature of my water buffer tank.

I have edited the configuration.yaml as described by you and added the following code:

template:
  - sensor:
      - name: heizungsdiagramm ## my sensor name
        state: "{{ states('sensor.node_1_input_8') | float }}" ## sensor outside temperature
        availability: "{{ states('sensor.node_1_output_8') | int}}" ## sensor oil burner status

Since I don’t need a target temperature, I have removed this section.
Here is my code from the card:

type: custom:apexcharts-card
graph_span: 12h
header:
  show: true
  title: Puffertemperatur
  show_states: true
  colorize_states: false
series:
  - entity: sensor.heizungsdiagramm
    name: Ölbrenner läuft
    stroke_width: 0
    type: area
    color: orange
    opacity: 0.5
    show:
      in_header: false
      legend_value: false
    group_by:
      func: avg
      duration: 5m
  - entity: sensor.node_1_input_8
    name: Puffertemperatur
    stroke_width: 3.5
    type: area
    color: '#4d908e'
    opacity: 0.08
    unit: °C
    show:
      extremas: true
      name_in_header: false
      in_header: true
    group_by:
      func: avg
      duration: 5m

My problem now is that the card shows that the burner is running even though the burner is not running.
grafik

Do you have any idea what I have done wrong?

Thank you very much.
Henri

I apologize, because after a restart it suddenly works.

Is there anyone out there that could point me to the right runes to change the title size and have it central?

type: custom:apexcharts-card
style: |
  ha-card {
    background-color: transparent;
    box-shadow: none;
    border: none;
chart_type: donut
header:
  show: true
  title: Radiators time on todays
  show_states: true
  colorize_states: true
apex_config:
  legend:
    show: false
  dataLabels:
    formatter: |
      EVAL:function(value) {
        return value.toFixed(1) + "%";
      }
  plotOptions:
    pie:
      donut:
        labels:
          show: true
          total:
            show: true
            label: Total
            formatter: |
              EVAL:function(w) {
                return w.globals.seriesTotals.reduce((a, b) => {return (a + b)} , 0).toFixed(2) + " hour"
                }
series:
  - entity: sensor.lounge_radiator_heating
    name: Lounge
    float_precision: 2
    color: '#2ECC71'
  - entity: sensor.kitchen_radiator_heating
    name: Kitchen
    float_precision: 1
    color: '#3498DB'
  - entity: sensor.study_radiator_heating
    name: Study
    float_precision: 1
    color: '#8E44AD'
  - entity: sensor.hallway_radiator_heating
    name: Hallway
    float_precision: 1
    color: '#E74C3C'
  - entity: sensor.charottes_radiator_heating
    name: Charlie
    float_precision: 1
    color: yellow
  - entity: sensor.master_bedroom_radiator_heating
    name: Master
    float_precision: 1
    color: cyan

many thanks

1 Like

Hi,

here is my version of changing title aligment, size and color:

type: custom:apexcharts-card
card_mod:
  style:
    .: |
      div#header__title {
        text-align: center;
        font-size: 14px;
        font-weight: bold;
        color: #ffffff !important;
      }
chart_type: donut
header:
  show: true
  title: Heizzeit pro Tag
  show_states: true
  colorize_states: true
apex_config:
...

Looks like this:

But could you a explain how you get the heating hours? My heating sensors have percent value between 0-100 to show how and how miuch heating is active and so I get not what I want.

Thanks, Steffen

2 Likes

Morning Stefan.

Will give that a go later today.

How I report the hours is a working progress, but may be enough for you to start with. I have a wiser system that has the attributes for when the TRV’s are heating and not heating.
To count the hours, I created several toggels using the helper, i.e Lounger Radiator. Then I used a simple automation to see when the the trv are heating and flip that toggle switch on

alias: Lounge radiator on
description: ""
trigger:
  - platform: device
    device_id: 4dd8d15d3a96f59cf25eafc396ffccce
    domain: wiser
    entity_id: climate.wiser_lounge
    type: started_heating
condition: []
action:
  - service: input_boolean.turn_on
    data: {}
    enabled: true
    target:
      entity_id:
        - input_boolean.lounge_radiator
mode: single

Another automation to flip it off when not heating. This is the bit I don’t like, I know there is another way I can do this in configuration template, just not managed to get it working properly by exposing the right attribute from the climate.wiser_lounge entity yet.
Anyway, I then counted how long that toggle was on, using a custom sensor.yaml file.

- platform: history_stats
  name: Lounge radiator heating
  entity_id: input_boolean.lounge_radiator
  state: "on"
  type: time
  start: "{{ now().replace(hour=0, minute=0, second=0) }}"
  end: "{{ now() }}"

The sensor.yaml file is included in the configuration.yaml

# Loads default set of integrations. Do not remove.
default_config:

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
sensor: !include sensors.yaml

Last step, reference the “Lounge radiator heating” made in the sensor.yaml into apex series

I’m not sure how familiar you are with yaml, personally I have never touched this and a complete beginner, however, I include all the steps here in case somebody like me learns from this

I have sperate counting for the actual boiler on time, as you well know the amount of time the radiators are on, does not actually reflect the time the boiler is fired up, I’m looking for a smarter way to incorporate that statistic with the radiator on into the graphs

- platform: history_stats
  name: Heating on Today
  entity_id: sensor.wiser_heating
  state: "On"
  type: time
  start: "{{ now().replace(hour=0, minute=0, second=0) }}"
  end: "{{ now() }}"

It worked, I had come across that code before, however, because the view did not dynamically change in the viewer, I assumed it did not work, but you have to save it and refresh for some reason.

Cheers bud

Complete code for anyone looking back at this for my solution.

type: custom:apexcharts-card
style: |
  div#header__title {
    text-align: center;
    font-size: 20px;
    font-weight: bold;
  }
  ha-card {
    background-color: transparent;
    box-shadow: none;
    border: none;
    font-size: 20px;
  }
chart_type: donut
header:
  title: Radiators time on today
  show: true
  show_states: true
  colorize_states: true
apex_config:
  style:
    fontSize: 20px
  legend:
    show: false
  dataLabels:
    formatter: |
      EVAL:function(value) {
        return value.toFixed(1) + "%";
      }
  plotOptions:
    pie:
      donut:
        labels:
          show: true
          total:
            show: true
            label: Total
            formatter: |
              EVAL:function(w) {
                return w.globals.seriesTotals.reduce((a, b) => {return (a + b)} , 0).toFixed(2) + " hour"
                }
series:
  - entity: sensor.lounge_radiator_heating
    name: Lounge
    float_precision: 2
    color: '#2ECC71'
  - entity: sensor.kitchen_radiator_heating
    name: Kitchen
    float_precision: 1
    color: '#3498DB'
  - entity: sensor.study_radiator_heating
    name: Study
    float_precision: 1
    color: '#8E44AD'
  - entity: sensor.hallway_radiator_heating
    name: Hallway
    float_precision: 1
    color: '#E74C3C'
  - entity: sensor.charottes_radiator_heating
    name: Charlie
    float_precision: 1
    color: yellow
  - entity: sensor.master_bedroom_radiator_heating
    name: Master
    float_precision: 1
    color: cyan

Thanks, my version is working now:

image

Only if I hoover and the Total in the middel change to the part the data is not use the format:

image

Do you have a idea to get there the hours like the labels on the top?

Steffen

Hello all,

Although I have been reading the documentation I can’t solve this issue. Need a bit help.
My goal is to show in an ApexChart columns of the attribute of an entity.
With some helpers I created new entities of the attribute from an existing entity

I used this code:
type: custom:apexcharts-card
header:
show: true
title: Helper
show_states: true
colorize_states: true
series:

  • entity: sensor.winddelen_totaal_helper_day1
    type: column
    stroke_width: 8
    name: ma
  • entity: sensor.winddelen_totaal_heperday2
    type: column
    stroke_width: 8
    name: di
  • entity: sensor.winddelen_helper_day3
    type: column
    stroke_width: 8
    name: wo
  • entity: sensor.winddelen_totaal_day4
    type: column
    stroke_width: 8
    name: do
  • entity: sensor.winddelen_totaal_deel5
    type: column
    stroke_width: 8
    name: vrij

The problem is that the columns don’t line up correctly:

Schermafbeelding 2023-12-29 om 20.53.40

I think I’m missing some point.

I would like to add an annotation (a horizontal line to my chart) which represents a HA sensor value (sensor.48_hour_anerage_electricity_profit_cost) - I would like this to be an annotation so it can be labeled.

If I use a fixed value this works… how do I use a HA sensor value?

type: custom:apexcharts-card
header:
  show: true
  show_states: true
  colorize_states: true
  title: 30 min Average Elec Profit / Cost
experimental:
  color_threshold: true
show:
  last_updated: true
series:
  - entity: sensor.30_min_anerage_electricity_profit_cost
    yaxis_id: elec_cost
    curve: stepline
    float_precision: 2
    show:
      extremas: true
      header_color_threshold: true
    color_threshold:
      - value: 0
        color: green
      - value: 0
        color: red
now:
  show: false
  color: red
  label: Now
update_interval: 30s
graph_span: 48h
cache: true
apex_config:
  annotations:
    yaxis:
      - 'y': 0.5
        borderColor: '#00E396'
        borderWidth: 4
        label:
          text: mean
  stroke:
    show: true
    width: 2
  chart:
    zoom:
      enabled: true
    toolbar:
      show: true
      tools:
        zoom: true
        zoomin: true
        zoomout: true
        pan: true
        reset: true
yaxis:
  - id: elec_cost
    show: true
    opposite: false
    apex_config:
      forceNiceScale: true
      labels:
        style:
          colors: '#ff0000'
      tickAmount: 8

The above code works - the problem is if I try and do something like this (which I know is incorrect - how do I use this sensor value for 'y': )

apex_config:
  annotations:
    yaxis:
      - 'y': sensor.48_hour_anerage_electricity_profit_cost
        borderColor: '#00E396'
        borderWidth: 4
        label:
          text: mean