ApexCharts card - A highly customizable graph card

Seems like the history API of home assistant is not reporting consecutive state change with the same value. I’ll need to investigate… Is it even stored in HA’s database?

I think I know the problem… In the API significant_change_only defaults to true… But it’s not documented :man_shrugging:

See here

I’ll fix it.

1 Like

I was still looking to see if the unchanged data is stored in de DB and your already 10 steps ahead hahaha

My yaml code of the sensor should make sure it’s stored in the DB even if it doesn’t change by using the force_update option.

  - platform: mqtt
    name: "energy_power"
    state_topic: "tele/energy_power/SENSOR"
    unit_of_measurement: "W"
    icon: mdi:home
    force_update: true

If i pull the history of this sensor in node red it give an entry per minute. Even if it doesn’t change.

3/21/2021, 12:44:22 AMnode: 344ba799.de60a8
msg.payload : Object
{ entity_id: "sensor.energy_power", state: "3", attributes: object, last_changed: "2021-03-20T23:27:45.223263+00:…", last_updated: "2021-03-20T23:27:45.223263+00:…" }
3/21/2021, 12:44:22 AMnode: 344ba799.de60a8
msg.payload : Object
{ entity_id: "sensor.energy_power", state: "3", attributes: object, last_changed: "2021-03-20T23:28:45.076861+00:…", last_updated: "2021-03-20T23:28:45.076861+00:…" }
3/21/2021, 12:44:22 AMnode: 344ba799.de60a8
msg.payload : Object
{ entity_id: "sensor.energy_power", state: "2.5", attributes: object, last_changed: "2021-03-20T23:29:45.201822+00:…", last_updated: "2021-03-20T23:29:45.201822+00:…" }
3/21/2021, 12:44:22 AMnode: 344ba799.de60a8
msg.payload : Object
{ entity_id: "sensor.energy_power", state: "2.5", attributes: object, last_changed: "2021-03-20T23:30:45.025889+00:…", last_updated: "2021-03-20T23:30:45.025889+00:…" }
3/21/2021, 12:44:23 AMnode: 344ba799.de60a8
msg.payload : Object
{ entity_id: "sensor.energy_power", state: "2.5", attributes: object, last_changed: "2021-03-20T23:31:45.151167+00:…", last_updated: "2021-03-20T23:31:45.151167+00:…" }
3/21/2021, 12:44:23 AMnode: 344ba799.de60a8
msg.payload : Object
{ entity_id: "sensor.energy_power", state: "2.5", attributes: object, last_changed: "2021-03-20T23:32:45.160869+00:…", last_updated: "2021-03-20T23:32:45.160869+00:…" }```

Hi there, i really like this chart! Would you mind sharing this with me?

Sure! It’s based off an Openweathermap weather entity which is configured as onecall-daily.

  - type: 'custom:apexcharts-card'
    graph_span: 7d12h
    span:
      start: day
      offset: +12h
    apex_config:
      dataLabels:
        enabled: false
      chart:
        height: 270%
      legend:
        position: 'top'
      stroke:
        colors: ['#ffa31a', '#03a8f4', 'none']
      fill:
        type: ['gradient', 'gradient', 'solid']
        gradient:
          type: 'vertical'
          shade: 'dark'
          inverseColors: true
          opacityFrom: 0.8
          opacityTo: 0.1
          stops: [20, 100]
        opacity: 0.85
      plotOptions:
        area:
          fillTo: 'origin'
        bar:
          columnWidth: '150%'
    series:
      - entity: weather.openweathermap
        type: area
        curve: smooth
        color: '#ffa31a'
        name: 'Température'
        extend_to_end: true
        fill_raw: last
        show:
          legend_value: false
        data_generator: |
          return entity.attributes.forecast.map((entry) => {
            return [new Date(entry.datetime), entry.temperature];
          });
      - entity: weather.openweathermap
        type: area
        curve: smooth
        name: 'Température min.'
        extend_to_end: true
        color: '#03a8f4'
        fill_raw: last
        show:
          legend_value: false
        data_generator: |
          return entity.attributes.forecast.map((entry) => {
            return [new Date(entry.datetime), entry.templow];
          });
      - entity: weather.openweathermap
        type: column
        color: '#0b0385'
        name: 'Précipitations'
        fill_raw: last
        show:
          legend_value: false
        data_generator: |
          return entity.attributes.forecast.map((entry) => {
            return [new Date(entry.datetime), entry.precipitation];
          });
    card_mod:
      style: |
        :host {
          left: 50%;
          top: 72.5%;
          width: 90% !important;
        }
        ha-card {
          background: none !important;
        }
2 Likes

Here you go:

  type: custom:apexcharts-card
  graph_span: 6d
  span:
    start: hour
    offset: '-36h'
  header:
    show: true
    title: Temperature Forecast
    show_states: true
  now:
    show: true
    label: now
  apex_config:
    legend:
      show: false
  series:
    - entity: weather.openweathermap
      name: Temperature
      unit: °C
      attribute: temperature
      fill_raw: last
      extend_to_end: false
      group_by:
        func: avg
        duration: 2h
    - entity: weather.openweathermap
      type: line
      extend_to_end: false
      unit: °C
      show:
        in_header: false
      data_generator: |
        const res = entity.attributes.forecast.map((entry) => {
          return [new Date(entry.datetime).getTime(), entry.temperature];
        });
        return [[new Date().getTime(), parseFloat(entity.attributes.temperature)], ...res]

:smiley: It should be fixed in the latest beta, please report back :slight_smile:

1 Like

@RomRider, you lost me, but “I’m here” :grin:
now it looks like this:
image

This is much better, but I wish I could understand how you build such syntax. Especially the “…res”
What on earth does that mean?

1 Like

That’s called the spread operator: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

@RomRider Updated to the latest dev release and working perfectly now. hourly totals are now spot on compared to the raw data in in my msql db.

Thanks for the quick fix :+1: :+1: :+1: :+1:

I spent embarassingly long trouble shooting the HACS installation method “Not Loading”. I should have known better that it would be the resources path via .yaml file.

Here’s what worked for me in case anyone else stumbles:

resources:
  - url: /hacsfiles/apexcharts-card/apexcharts-card.js
    type: module

Thanks @RomRider for these charts, I really missed these customizable charts. I have a quick question, for displaying my crypto wallets. I like to transform my values in each series, by subtracting the first value from the actual value. Something like this:

transform: "return x-first;"

Can you help me with the right formula?

That’s not possible but what is your use case?

I’m trying to find a clear way to display my different crypto wallets in one view. Since some of my wallets are bigger and others are smaller I would like to start each series at ‘0’ and show relative values, so difference between timestap 0 and timestamp x.

I want to make the heating curve filled 100% but without the line…only the filling will stay. how can i do that?

type: 'custom:apexcharts-card'
header:
  title: Bedroom
  show: true
  show_states: true
  colorize_states: true
update_interval: 10m
graph_span: 1d
apex_config:
  tooltip:
    enabled: true
  yaxis:
    - show: true
      decimalsInFloat: 0
      min: 18
      labels:
        style:
          colors: '#FFB62E'
          fontSize: 12px
          fontWeight: bold
      forceNiceScale: true
    - show: true
      opposite: true
      decimalsInFloat: 0
      min: 0
      max: 99
      labels:
        style:
          colors: '#FFB62E'
          fontSize: 12px
          fontWeight: bold
      forceNiceScale: true
    - show: false
      opposite: true
      decimalsInFloat: 0
      min: 18
      labels:
        style:
          colors: '#FFB62E'
          fontSize: 12px
          fontWeight: bold
      forceNiceScale: true
  xaxis:
    axisBorder:
      show: false
    labels:
      style:
        fontSize: 14px
  chart:
    height: 250px
  grid:
    show: false
  legend:
    show: false
    fontSize: 12px
    height: 40
  dataLabels:
    enabled: false
  stroke:
    width: 3
    curve: smooth
  # fill:
  #   type: gradient
  #   gradient:
  #     type: vertical
  #     shadeIntensity: 0.8
  #     inverseColors: false
  #     opacityFrom: 0.5
  #     opacityTo: 0
  #     stops:
  #       - [0, 50, 100]
series:
  - entity: sensor.bedroom_temperature
    name: Current
    type: line
    # opacity: 0
    fill_raw: last
    float_precision: 1
    group_by:
      duration: 10m
      func: avg
  - entity: sensor.bedroom_heating
    name: Heating
    type: area
    color: grey
    fill_raw: last
    float_precision: 0
    opacity: 0.2
    group_by:
      duration: 10m
      func: avg
  - entity: sensor.target_temp_bedroom
    name: Target
    type: line
    # opacity: 0
    fill_raw: last
    float_precision: 1
    group_by:
      duration: 10m
      func: avg

At the moment it looks like this
image

I want to make this look somewhat like this.
image

how to use different fill properties for different lines?

interesting observation: if i use secondary y aaxis limit max=100, it sets to 120, but with 99 it sets to 100!!!

In reference to Frank question there :
https://community.home-assistant.io/t/apexcharts-card-a-highly-customizable-graph-card/272877/296?u=formicro

  - type: 'custom:apexcharts-card'
    graph_span: 24h
    cache: true
    span:
      start: day
    chart_type: donut
    apex_config:
      plotOptions:
        pie:
          donut:
            total:
              show: true
              showAlways: true
              formatter: null

Is it possible to display a sensor value, right in the center of a donut ?
Thanks for suggestions, regards, Thomas.

Now, i have 2 elements with current value: legend and header. Header looks better, but him not have function hide series. I try hide header and up legend, but him looks bad. How i may add click function to header or make a legend view like header

The line can be removed by setting stroke_width=0

For example for a binary sensor:

  - entity: binary_sensor.night
    name: Night time
    curve: stepline
    opacity: 0.2
    stroke_width: 0
    show:
      in_header: false
    transform: 'return x === ''on'' ? 1 : 0;'
1 Like

Is there a mechanism to create an axis annotation at a timestamp contained in a sensor? From what I’ve read above Jinja templates are not supported.

In my case X axis annotations for sunrise and sunset, eg:

apex_config:
  annotations:
    xaxis:
      - x: states.sensor.sunrise
        label:
          text: Sunrise
1 Like

You can use config-template-card to build that for now :blush:

Thanks for the hint. Works great…

Card config
type: 'custom:config-template-card'
entities:
  - sensor.sunrise
  - sensor.sunset
  - sensor.zappi_generation
  - sensor.harvi
card:
  type: 'custom:apexcharts-card'
  header:
    show: true
    show_states: true
    colorize_states: true
    title: Solar generation
  span:
    start: day
  graph_span: 24h
  all_series_config:
    stroke_width: 2
    type: area
    extend_to_end: false
    float_precision: 0
  color_list:
    - yellow
    - yellow
    - green
    - grey
  series:
    - entity: sensor.zappi_generation
      name: Solar on house
      group_by:
        func: avg
        duration: 20min
    - entity: sensor.zappi_generation
      name: Solar on house
      offset: '-24h'
      type: line
      opacity: 0.2
      group_by:
        func: avg
        duration: 20min
      show:
        in_header: false
    - entity: sensor.harvi
      name: Solar on shed
      group_by:
        func: avg
        duration: 20min
  y_axis_precision: 0
  apex_config:
    annotations:
      xaxis:
        - x: '${new Date(states[''sensor.sunrise''].state).getTime()}'
          label:
            text: ☼
            borderWidth: 0
            style:
              background: '#0000'
        - x: '${new Date(states[''sensor.sunset''].state).getTime()}'
          label:
            text: ☾
            borderWidth: 0
            style:
              background: '#0000'
    yaxis:
      - seriesName: Solar on house
        decimalsInFloat: 0
      - seriesName: Solar on house
        show: false
      - seriesName: Solar on shed
        show: false
      - seriesName: Night time
        opposite: true
        show: false
    tooltip:
      x:
        format: 'ddd dd MMM - HH:mm'
    xaxis:
      tooltip:
        enabled: false
    legend:
      show: false
    grid:
      borderColor: '#7B7B7B'
    chart:
      foreColor: '#7B7B7B'
      zoom:
        type: x
        enabled: true
        autoScaleYaxis: true
      toolbar:
        show: true
        autoSelected: zoom
        tools:
          zoom: true
          zoomin: false
          zoomout: false
          pan: false
          reset: true
13 Likes