ApexCharts card - A highly customizable graph card

Is there a way to specify the name of the entities via a template? I have already tried many variants, but without success. :man_shrugging:

1 Like

Final result! I’m really happy!

Wondershare UniConverter 13_000008

If somebody wants to replicate:

Prerequisites:

  • apex.chart card (graph)
  • config-template card (change hours)
  • mushroom card (layout of hour picker)
  • template sensor (creating the darker heating area)

Full apex chart code here:

type: vertical-stack
cards:
  - type: custom:mushroom-chips-card
    chips:
      - type: template
        double_tap_action:
          action: none
        icon: mdi:minus
        tap_action:
          action: call-service
          service: counter.decrement
          data: {}
          target:
            entity_id: counter.grafici_temperatura_ore
        hold_action:
          action: call-service
          service: counter.reset
          data: {}
          target: {}
      - type: template
        icon: mdi:chart-box-outline
        content: >-
          {{ states('counter.grafici_temperatura_ore') }}

          {% if states('counter.grafici_temperatura_ore') | int == 1 %} ora nei
          grafici
            {% else %} ore nei grafici
            {% endif %}
        tap_action:
          action: more-info
        entity: counter.grafici_temperatura_ore
      - type: template
        icon: mdi:plus
        content: ''
        tap_action:
          action: call-service
          service: counter.increment
          data: {}
          target:
            entity_id: counter.grafici_temperatura_ore
        double_tap_action:
          action: none
        hold_action:
          action: call-service
          service: counter.increment
          data: {}
          target:
            entity_id: counter.grafici_temperatura_ore
    alignment: center
  - type: custom:config-template-card
    entities:
      - counter.grafici_temperatura_ore
    card:
      type: custom:apexcharts-card
      update_interval: 1m
      graph_span: ${{states['counter.grafici_temperatura_ore'].state+'h'}}
      header:
        show: true
        title: Temperatura bagno
        show_states: true
        colorize_states: false
      series:
        - entity: sensor.grafico_riscaldamento_bagno_sta_riscaldando
          name: Sta riscaldando
          stroke_width: 0
          type: column
          color: '#F5B041'
          opacity: 0.3
          show:
            in_header: false
            legend_value: false
          group_by:
            func: avg
            duration: 2m
        - entity: sensor.tado_riscaldamento_bagno_temperature
          name: Temp attuale
          stroke_width: 3
          type: area
          color: '#f8e07d'
          opacity: 0.25
          unit: °C
          show:
            extremas: true
            name_in_header: false
            in_header: true
          group_by:
            func: avg
            duration: 2m
        - entity: climate.tado_riscaldamento_bagno
          attribute: temperature
          name: Temp desiderata
          stroke_width: 1.5
          type: line
          color: '#CC3333'
          opacity: 1
          unit: °C
          show:
            extremas: false
            in_header: false
          group_by:
            func: avg
            duration: 2m
  - type: custom:config-template-card
    entities:
      - counter.grafici_temperatura_ore
    card:
      type: custom:apexcharts-card
      update_interval: 1m
      graph_span: ${{states['counter.grafici_temperatura_ore'].state+'h'}}
      header:
        show: true
        title: Umidità bagno
        show_states: true
        colorize_states: false
      series:
        - entity: sensor.tado_riscaldamento_bagno_humidity
          name: Umidità
          stroke_width: 3
          type: area
          color: '#7AB7FF'
          opacity: 0.15
          show:
            extremas: true
            name_in_header: false
            in_header: true

How I’ve created the darker “heating area” here:

In order to achieve that result, I’ve created a new template sensor in configuration.yaml that

  • when it’s heating → gives me current temperature
  • when it’s not heating → is empty or null (:warning: when it’s not heating I don’t want a 0 value, since this will interfere with y-axis min value in my chart)

So I’ve created in my configuration.yaml the following sensor:

template:
  - sensor:
      - name: Grafico riscaldamento soggiorno - sta riscaldando ## In English it's heating
        state: "{{ states('sensor.tado_riscaldamento_bagno_temperature') | float }}" ## the value of the sensor is equal to current temperature
        availability: "{{ states('sensor.tado_riscaldamento_bagno_heating') | int}}" ## when it's not heating, availability is 0, so the value of the sensor is null

Pay attention to “availability”:

  • when heating is 0 → availability is false, so the value of the sensor is null
  • when it’s heating (heating is not 0) → availability is true and the value of the sensor is current temperature

Finally I’ve added the template sensor to my apex chart as a third orange series.

Special thanks
Special thanks to @Kertz1954 for his precious help during the process!

3 Likes

Hello! Don’t share the code?

@Fanan Did you ever solve this? Want to do the same. I have a sensor with the average price.

Is anyone showing (long term) statistic sensors in Apex?

It works good but for some reason, the date on the tooltip is one day behind. Below it says January 12 when it’s actually data from January 13 that is shown. The data for the last bar in the chart is also for the 13th.

Any ideas?

    statistics:
      type: sum
      period: day
      align: middle
    group_by:
      func: diff
      duration: 1d
      fill: last
      start_with_last: true

First of all thanks for this amazing card. It’s absolutely fabulous.
Does anyone know how to change the decimal number notification for the y-axis label from decimal point to decimal comma (5,7 instead of 5.7)?

It’s not in your localization settings. I tried changing date formats to Danish, dit not work either. Simple fix is to remove decimals

Is it possible to cut a line?
I have a value that is only valid for three hours a day.
image
The red line is all the way through, I’d like it to only be displayed between 17 and 20h. I’ve tried this to no avail:


      let pr =[entity.attributes.gasday,entity.attributes.gasday,entity.attributes.gasday];
      console.log(pr); 
      return [...entity.attributes.gasday].reverse().map((entry)
      => {
        const lNow = now;
        console.log(entry);  
        now -= 30 * 60 * 1000;
        return [lNow, entry];
      }).reverse();

Btw thanks to Romrider, I have 10k+ views of my spot price prognosis per day, and it’s Apexchart-card that is the business end of visuals.

Henrik

Changing the format may be possible by following this Formatting Axes Labels – ApexCharts.js

Does anybody know how to use a sensor value to set a horizontal line in the chart?

This doesn’t work:

 apex_config:
   annotations:
     yaxis:
       - 'y': hass.states['sensor.mysensor'].state

Yes I solved it.
I created a sensor (in my sensors.yaml):

- platform: template
  sensors:
    medelpris_el_kr:
      friendly_name: Medelpris på el idag
      entity_id: 
        - sensor.nordpool_kwh_se3_sek_3_095_025
      value_template: '{{ states.sensor.nordpool_kwh_se3_sek_3_095_025.attributes.mean }}'

Then I added this to the apexchart:

  - entity: sensor.medelpris_el_kr
    type: line
    transform: return x * 100
    group_by:
      func: avg
      duration: 24h

Hopefully that helps.
/Fanan

Here’s two snippets of code that will work for you. Your choice which one you choose.

yaxis:
  - id: electric
    decimals: 3
    apex_config:
      title:
        text: Electric kWh
        style:
          fontSize: 16px
      forceNiceScale: 'no'
      labels:
        show: true
        formatter: |
          EVAL:function(value) {
            let text = parseFloat(value).toFixed(3);
            let result = text.replace(".", ",");
            return result;
          }
        style:
          colors: '#ffffff'
          fontSize: 14px
series:

or

apex_config:
  yaxis:
    show: true
    labels:
      show: true
      formatter: |
        EVAL:function(value) {
          let text = parseFloat(value).toFixed(3);
          let result = text.replace(".", ",");
          return result;
        }
      style:
        colors: '#ffffff'
        fontSize: 16px

apex chart

1 Like

Many thanks for the support! Working great.

Thanks for your post. This is something I would like to have to! Unfortunally the code for the config.yaml doesn’t work:

template:
  - sensor:
      - name: Grafico riscaldamento soggiorno - sta riscaldando ## In English it's heating
        state: "{{ states('sensor.tado_riscaldamento_bagno_temperature') | float }}" ## the value of the sensor is equal to current temperature
        availability: "{{ states('sensor.tado_riscaldamento_bagno_heating') | int}}" ## when it's not heating, availability is 0, so the value of the sensor is null

I have the 2022.1.1 version of HA. Most yaml code is written as this in my HA:

  - platform: template
    sensors:
      energy_gas_en_elektriciteit_maandelijks_eur:
        friendly_name: 'Totale netto maand kosten energie'
        value_template: "{{ (states('sensor.gas_maandelijks_eur')|float + states('sensor.energy_import_total_maandelijks_eur')|float)|round(2) }}"
        unit_of_measurement: "€"

How can I get this to work?

Hi! I’ll try to help you, if I can (even though I’m not an expert in template sensors).

I suggest you to proceed step by step

1) Check in developer tools the result of your value

{{ ( states('sensor.gas_maandelijks_eur') | float + states('sensor.energy_import_total_maandelijks_eur') | float) | round(2) }}

If you obtain the right value, go on.

2) Create a really simple template sensor in configuration.yaml

template:
  - sensor:
      - name: Totale netto maand kosten energie
        state: "{{ ( states('sensor.gas_maandelijks_eur') | float + states('sensor.energy_import_total_maandelijks_eur') | float) | round(2) }}"

Restart home assistant and check if you see your template sensor (go to entities and search for “Totale netto maand kosten energie”)

3) Play with availability, units, etc

Then you can come back to configuration.yaml and add more complexity to your sensor (unit of measurement, availability, etc)

Maybe this approach could help you creating your template sensor. Otherwise I suggest you to search videos / post about creating a template sensor!

1 Like

Are there any examples on how to modify the header?

This is with a floating header:
2023-01-15 17_04_49-Fire Tablet – Home Assistant

I would like to put the header in the middle of the card.

@Rubbervdh When you have created your template sensor, if you want to play with availability, keep in mind that:

  • when availability is 0 (int) → the sensors is not available in home assistant and its value in the chart is null
  • when availability is different from 0 → the sensor is available in home assistant and its value is the value you have assigned to it in configuration.yaml

So if you want that your sensor is unavailable when {{ states(‘sensor.my_sensor’) }} is 0, you should write something like this:

template:
  - sensor:
      - name: Totale netto maand kosten energie
        state: "{{ ( states('sensor.gas_maandelijks_eur') | float + states('sensor.energy_import_total_maandelijks_eur') | float) | round(2) }}"
        availability: "{{ states('sensor.my_sensor') | int }}"

Short answer No. As per the HA Apex Chart documentation, Positioning will be supported later. Note, the HEADER is an HA option and is not part of the official Apex Chart system.
However, you could make use of the legend option within the apex_config.
Much neater and takes up less vertical space (depending on fontsize), plus an optional title if so inclined. See https://apexcharts.com/docs/options/legend/ for all options and much more.

Code snipped to get you started.

apex_config:
  chart:
    height: 250
  legend:
    show: true
    showForSingleSeries: true
    position: top
    horizontalAlign: center
    fontSize: 30px
    offsetX: 0
    offsetY: 0
    labels:
      useSeriesColors: true
    onItemClick:
      toggleDataSeries: false
    onItemHover:
      highlightDataSeries: false

legend

1 Like

Thanks for the response. I see that you’re way of writing in the config.yaml is different from mine. I have my sensors this way:

sensor:
  - platform: systemmonitor
    resources:
      - type: processor_use
      - type: processor_temperature
      - type: memory_free
      - type: disk_use_percent
        arg: /
      - type: disk_use
      - type: disk_free
      - type: throughput_network_in
        arg: enp0s3
      - type: throughput_network_out
        arg: enp0s3
# Temperatur-Attribut Buitentemp volgens HA zelf
  - platform: template
    sensors:
      norwegian_temperature:
        friendly_name: "met.no Tempratuur Buiten"
        unit_of_measurement: '°C'
        value_template: "{{ state_attr('weather.huis', 'temperature') }}"
    
# Temperatur-Attribut Windkracht volgens HA zelf
  - platform: template
    sensors:
      norwegian_temperature:
        friendly_name: "met.no Windkracht Buiten"
        unit_of_measurement: 'km/h'
        value_template: "{{ state_attr('weather.huis', 'wind_speed') }}"

#WK gemiddelde beide sensors
  - platform: min_max
    name: avg_wk_xiaomi_sonoff
    type: mean
    entity_ids:
      - sensor.sonoff_woonkamer_sensor_temperature
      - sensor.woonkamer_temperature
#WK gemiddelde beide sensors 24h
  - platform: statistics
    name: WK avg Sonoff en Xiaomi 24h
    entity_id: sensor.avg_wk_xiaomi_sonoff
    state_characteristic: mean
    max_age:
      hours: 24

# Gemiddelde WK temp Sonoff 24h
  - platform: statistics
    name: WK Sonoff avg 24h
    entity_id: sensor.sonoff_woonkamer_sensor_temperature
    state_characteristic: mean
    max_age:
      hours: 24
# Gemiddelde WK temp Xiaomi 24h
  - platform: statistics
    name: WK Xiaomi avg 24h
    entity_id: sensor.woonkamer_temperature
    state_characteristic: mean
    max_age:
      hours: 24

#Buiten gemiddelde beide sensors zonder tijd
  - platform: min_max
    name: avg_bu_sonoff_sonoff2
    type: mean
    entity_ids:
      - sensor.sonoff_buiten_sensor_temperature
      - sensor.sonoff_buiten_sensor_2_temperature
      
#Buiten gemiddelde beide sensors 24h
  - platform: statistics
    name: BU avg Sonoff hok en huis 24h
    entity_id: sensor.avg_bu_sonoff_sonoff2
    state_characteristic: mean
    max_age:
      hours: 24

# Gemiddelde Buiten temp Sonoff naast huis 24h
  - platform: statistics
    name: BU Sonoff naast huis avg 24h
    entity_id: sensor.sonoff_buiten_sensor_2_temperature
    state_characteristic: mean
    max_age:
      hours: 24

So in short: I start with the tag Sensor:

And under that tag i define my sensors and their platform, like template.

I see that you start with Template. Is that te platform or is that a different way of writing? I am getting errors when I trie it that way

Sorry, on the phone here, but if you look at the template documentation, your way is now considered “legacy”, meaning that it’s still supported, but the new way with template on the top level is the recommended way going forward.

“Legacy binary sensor configuration format
This format still works but is no longer recommended. Use modern configuration.”

I actually just discovered this myself and I would recommend reading the documentation and related discussion well before converting to the new one.
E.g. friendly name is now not longer needed. It now takes advantage of unique_id instead.