ApexCharts card - A highly customizable graph card

how do I set the time period? e.g in grafana you can easily choose the time period, I couldn’t find any mention of it in the apex-chart documnetion.

I’m having this issue:

imagen

It’s sunday (dom) and bar is not where it should be (or maybe is the lavel the one wrong). Another thing is why xaxis don’t take the whole available width.

Card config:

type: custom:apexcharts-card
header:
  show: true
  title: Consumo Energía Semanal
  show_states: true
  colorize_states: true
apex_config:
  chart:
    height: 200px
  yaxis:
    min: 0
    tickAmount: 4
  xaxis:
    type: datetime
    labels:
      datetimeFormatter:
        day: ddd
graph_span: 1week
span:
  start: week
series:
  - entity: sensor.energy_daily
    name: Hoy
    type: column
    float_precision: 2
    group_by:
      func: max
      duration: 1d
  - entity: sensor.energy_weekly
    name: Total semana
    float_precision: 2
    show:
      in_chart: false

Edit:
Also values not calculated correctly.
I’m displaying a utility meter in bar chart with group_by day and func max. Trying with last instead of max, but it gives worse results
imagen
imagen

Card config:
type: custom:apexcharts-card
header:
  show: true
  title: Consumo Energía Semanal
  show_states: true
  colorize_states: true
apex_config:
  chart:
    height: 200px
  xaxis:
    labels:
      format: ddd
      hideOverlappingLabels: false
graph_span: 1week
series:
  - entity: sensor.energy_daily
    name: Hoy
    type: column
    float_precision: 2
    group_by:
      func: max
      duration: 1d

Hi! I love this graph card, there is only one thing that I am not able to do:

I have a column chart with only one series. I’ve defined a color_threshold and also, defined the colorized_states: true option.

Is there any chance to show the state with the same color than the current value of the serie defined in color_threshold?

For example: if the curren column is red, show the title in red.
Or at least being able to define a javascript function to calculate the color of the title?

Thanks!

Hi Enrico,
im italian too.
I am struggling with apex chert, i would like to have a graph (not bargraph but curve) showing solar production, consumed and sold energy.
Do you have some suggestions or yaml to share?
Thanks!!!

So… I’ve figured out enough about data_generator to solve my problem. Thanks again to @RomRider for the card. For those other newbies interested, I found two ways to set the state of a sensor to test / build from the basic data_generator examples (the weather.home & tides)

  • Use the Developer Tools > States tab to manually set the state & attributes of a sensor
  • Use the ‘Set State’ python script

It is a hack, but by using the python script in an automation that runs on startup, I’m able to load my rolled up monthly history of a few key variables into HA, so I can chart it along with the live 7 day data in my HA database. Here is a picture of some of the graphs produced.

looking for some guidance, creating my 2nd effort today to plot 2 y-axis’s without success so far…
first I trired mini-graph-card, but because I couldn’t get the secondary y-axis to be set correctly, here’s my first go at it using the apexcharts:

  - type: custom:apexcharts-card
    apex_config:
      yaxis:
        - id: sun
          show: true
          title: Sun
          min: 0
          max: 6000
        - id: cloud
          show: false
          title: Cloud
          min: 0
          max: 100
    span:
      start: day
    header:
      show: true
      title: Sun - Cloud
    series:
      - yaxis_id: sun
        entity: sensor.zp_actuele_opbrengst
        type: area
        fill_raw: last
        extend_to_end: false
        color: gold
        name: Sun
      - yaxis_id: cloud
        entity: sensor.weatherbit_cloud_coverage
        type: line
#        fill_raw: last
#        extend_to_end: false
        color: grey
        name: Cloud

won’t show me my clouds, or even the scale for that matter:

deselecting the Sun renders an empty graph (though the legend shows the clouds to be indentified correctly:

please have a look where I am troubling myself? thanks!

edit
duh, of course I have to set it to show: true… and opposite: true

still seems off … while I cant get rid of the decimals, using

    apex_config:
      decimalsInFloat: 0

on either y axis’s or generic

update
solved too:

    apex_config:
      yaxis:
        - id: sun
          show: true
#          title: Sun
          min: 0
          max: 6000
          decimalsInFloat: 0
        - id: cloud
          opposite: true
          show: true
#          title: Cloud
          min: 0
          max: 100
          decimalsInFloat: 0

noob…

It’s possible to have the forecast for the rain ? with weather.openweathermap ??

Can you show your code please thanks

Hello Every Body
First thanks for this !!! I would like to show in a donut the energy use yesterday or for the last month i try this code but in the value in receive le last value of yesterday (exemple 411 kwh) not the value for only yesterday (exemple 12 kWh)

type: custom:apexcharts-card
graph_span: 24h
cache: true
span:
  start: day
apex_config:
  chart:
    height: 400px
  plotOptions:
    pie:
      donut:
        total:
          show: true
          showAlways: true
header:
  show: true
  title: Utilisatation Du Réseau
chart_type: donut
series:
  - entity: sensor.bureau_conso
    offset: '-1d'
  - entity: sensor.chaud_conso
    offset: '-1d'
  - entity: sensor.lavev_conso
    offset: '-1d'
  - entity: sensor.mal_conso
    offset: '-1d'
  - entity: sensor.nas_conso
    offset: '-1d'
  - entity: sensor.sdj_conso
    offset: '-1d'
  - entity: sensor.tv_conso
    offset: '-1d'
1 Like

What a great solution for HA!

I’m measuring the amount of rail, and my intention was to ensure that it was from “0.0 to 23.59”, but it seems to be a bit different

Can anyone help me find a way for ensuring that my graph’s is one full day?

Is there a way with ApexCharts to shade under a curve for portions only when my air conditioning is on? The stock history graph card can do this (as seen in picture). Thanks.Capture

1 Like

Would love if you can share your code for this? Have just started monitoring daily solar costs and savings but would love to be able to graph historical costs and consumption like you have :slight_smile:

Hi! I’ve discovered an issue where the tooltip is cut off. I’m wondering if this is some sort of a freak occasion, as it seems quite a big flaw in the card. Or are my charts and cards just too small and the tooltip fits into the card for everybody else?

I tried debugging it and trying to understand the box model and overflows involved, and found out that the <ha-card> element has overflow: hidden defined on it.

I’ve made a pull request and hopefully, it’ll get fixed soon, unless I misunderstood something and am just using it wrong.

1 Like

On an unrelated topic: is it possible to have dynamic values in the configuration? E,g, I would like to hide numbers in the header if the value is 0, but this doesn’t get parsed:

  - entity: sensor.rtorrent_down_speed
    show:
      in_header: '{{ float(states.sensor.rtorrent_down_speed.state) > 0 }}'

Hi,
Don’t know if you managed it, I’ve been struggling with the same question. Here is the part of the code that gets rid of the borders on the side and the bottom:

apex_config:
  grid:
    margin:
      left: 0
      right: 0
  chart:
    offsetY: 15
    parentHeightOffset: 0

Ok, so I’ve set myself a lofty goal here, but I’m reaching some limitations that I’ve been unable to get around these past few days. Any insight would be greatly appreciated.

What I want to achieve: a weather chart mapping past temperatures, temperature forecast, past precipitation (rain + snow) and precipitation forecast. I would like to show the past 7 days, temperatures are areas (same color for past and future) and precipitation are columns (stacked for rain + snow) placed on the relevant day’s tick. The card itself is placed on a picture-elements card, should take up about the whole width and about 40% of the height of said picture-elements card.

The following are my current hurdles:

  1. There’s an overlap in data. My forecast data provided via data-generator includes the present day. Currently using OWM with onecall daily API. That leads me to have two columns on the same day as well as an area overlap for temperatures. Overlap in temperatures:
    overlap
    I’m no JS wiz, but I’m guessing I’d need to fiddle with the data-generator code to avoid these overlaps?

  2. If I don’t set the columns to a ridiculous width (e.g. 600%) via apex-config, they are way to thin to my taste. However, setting the columns this wide messes with their placement with regard to the x-axis ticks and displaces the background behind the “now” flag. Even is the case when column width is set to 100%.
    now
    How do I get the columns wider without messing up the entire layout? And I’d like the column to be set either in centered between ticks - noon - or on the ticks - midnight. Currently, they’re in between but not centered.

  3. Somehow, the tooltips for the forecast precipitation show up in the past. See:


    Any Idea why that is? My data-generator code perhaps?

It’s still a work in progress, here’s the code for the card:

  - type: 'custom:apexcharts-card'
    graph_span: 14d
    span:
      start: day
      offset: -7d
    now:
      show: true
      label: 'Présent'
    yaxis:
      - id: temp
        show: true
        apex_config:
          forceNiceScale: true
          tickAmount: 5
          decimalsInFloat: 0
      - id: rain
        show: true
        opposite: true
        apex_config:
          forceNiceScale: true
          tickAmount: 5
          decimalsInFloat: 0
    apex_config:
      dataLabels:
        enabled: false
      chart:
        width: '100%'
        height: 100%
      legend:
        position: top
      grid:
        show: false
        padding:
          left: 0
          right: 0
      stroke:
        colors: ['#ffa31a', '#03a8f4', 'none']
      fill:
        type: ['gradient', 'gradient', 'solid', 'solid', 'solid']
        gradient:
          type: 'vertical'
          shadeIntensity: 0.5
          inverseColors: false
          opacityFrom: 1
          opacityTo: 0.3
          stops:
            - 0
        opacity: 0.65
      plotOptions:
        area:
          fillTo: origin
        bar:
          columnWidth: 100%
          stacked: true
      xaxis:
        axisBorder:
          show: false
        axisTicks:
          show: false
        tooltip:
          enabled: false
        tickPlacement: 'on'
    series:
      - entity: weather.openweathermap
        type: area
        name: 'Température'
        unit: °C
        attribute: temperature
        stroke_width: 0
        yaxis_id: temp
        color: '#ffa31a'
        fill_raw: last
        show:
          legend_value: false     
        group_by:
          func: avg
          duration: 2h 
        extend_to_end: false  
      - entity: weather.openweathermap
        type: area
        stroke_width: 0
        yaxis_id: temp
        color: '#ffa31a'
        name: 'Température'
        unit: °C
        extend_to_end: false
        fill_raw: last
        show:
          legend_value: false
        data_generator: |
          return entity.attributes.forecast.map((entry) => {
            return [new Date(entry.datetime).getTime(), entry.temperature];
          });
      - entity: sensor.openweathermap_rain
        type: column
        yaxis_id: rain
        name: 'Précipitations'
        unit: mm
        color: '#0b0385'
        fill_raw: last
        show:
          legend_value: false     
        group_by:
          func: sum
          duration: 1d
      - entity: sensor.openweathermap_snow
        type: column
        yaxis_id: rain
        name: 'Neige'
        unit: mm
        color: '#0b0385'
        fill_raw: last
        show:
          legend_value: false     
        group_by:
          func: sum
          duration: 1d
      - entity: weather.openweathermap
        type: column
        yaxis_id: rain
        color: '#0b0385'
        name: 'Précipitations'
        unit: mm
        extend_to_end: false
        fill_raw: last
        show:
          legend_value: false
        data_generator: |
          return entity.attributes.forecast.map((entry) => {
            return [new Date(entry.datetime).setHours(0, 0, 0, 0), entry.precipitation];
          });
    card_mod:
      style: |
        :host {
          left: 50%;
          top: 75%;
          width: 90%;
          height: 40%;
        }
        ha-card {
          background: none !important;
          height: 100%;
        }
        .wrapper.with-header {
          height: 100%;
        }

I am trying to track the number of times the garage door has been opened in a day.

This is the screenshot of the history of the entity.
image

The last value for Aug 3 and 4 is 7 and 3 respectively.

I am trying to plot the last value of the entity for a day in a chart.

type: custom:apexcharts-card
header:
  show: true
  show_states: true
yaxis:
  - min: ~2
    apex_config:
      decimalsInFloat: 0
      forceNiceScale: true
apex_config:
  chart:
    height: 200px
graph_span: 7d
color_list:
  - tomato
series:
  - entity: sensor.garage_door_daily_count
    type: column
    group_by:
      func: last
      duration: 1d

The chart appears as below, where the value is 3 for both the days.

image

If I change the group_by function to max, the chart appears as below. The values seem to be flipped around for the 2 dates.

image

Any help with getting the chart to show the right values on the right days?

1 Like

Hi,

I wonder if anyone can help. I have an entity with a bunch of attributes that’s retrieved from my electricity providor. Its an array which contains my consumption every half hour. Example output is below from the attribute.

Is there any way I can graph this using ApexCharts? I have tried and can’t work out what I would need to do, can I use both the consumption as the y axis and the interval start/end as the x axis?

Thank you in advance!

Craig

Results

  • consumption: 0.097 interval_start: ‘2021-08-04T00:00:00+01:00’ interval_end: ‘2021-08-04T00:30:00+01:00’ - consumption: 0.08 interval_start: ‘2021-08-03T23:30:00+01:00’ interval_end: ‘2021-08-04T00:00:00+01:00’ - consumption: 0.139 interval_start: ‘2021-08-03T23:00:00+01:00’ interval_end: ‘2021-08-03T23:30:00+01:00’ - consumption: 0.176 interval_start: ‘2021-08-03T22:30:00+01:00’ interval_end: ‘2021-08-03T23:00:00+01:00’ - consumption: 0.167

I have a goal of displaying external data so that I don’t need to include my weather data into homeassistant (and can have a long term graph) and today we succeeded in doing so with a custom web server. But I do get interesting results displayed.

image
image

Using (almost) the same data via mqtt sensor works like it should
image

This is the complete code of the data generator card:

type: custom:apexcharts-card
graph_span: 1d
hours_12: false
header:
  show: true
  title: Innentemperatur
  show_states: true
  colorize_states: true
  standard_format: false
now:
  show: true
all_series_config:
  type: area
  stroke_width: 2
  opacity: 0.5
  unit: °C
  show:
    legend_value: false
series:
  - entity: sensor.time
    name: Wohnzimmer
    data_generator: |
      function makeRequest(method, url) {
          return new Promise(function (resolve, reject) {
              let xhr = new XMLHttpRequest();
              xhr.open(method, url);
              xhr.onload = function () {
                  if (this.status >= 200 && this.status < 300) {
                      resolve(xhr.response);
                  } else {
                      reject({
                          status: this.status,
                          statusText: xhr.statusText
                      });
                  }
              };
              xhr.onerror = function () {
                  reject({
                      status: this.status,
                      statusText: xhr.statusText
                  });
              };
              xhr.send();
          });
      }
      const request = async () => {
        var http = new XMLHttpRequest();
        var response = await makeRequest('GET', 'https://kuroi1992.dyndns.pro/test?type=temperature&location=inside&name=wohnzimmer&time=24h');
        console.debug(response);
        var json = JSON.parse(response);
        console.debug(json);
        return json.map(x => {
              return [x['time'], x['value']];
          });
      } 
      return request();
  - entity: sensor.time
    name: Schlafzimmer
    data_generator: |
      function makeRequest(method, url) {
          return new Promise(function (resolve, reject) {
              let xhr = new XMLHttpRequest();
              xhr.open(method, url);
              xhr.onload = function () {
                  if (this.status >= 200 && this.status < 300) {
                      resolve(xhr.response);
                  } else {
                      reject({
                          status: this.status,
                          statusText: xhr.statusText
                      });
                  }
              };
              xhr.onerror = function () {
                  reject({
                      status: this.status,
                      statusText: xhr.statusText
                  });
              };
              xhr.send();
          });
      }
      const request = async () => {
        var http = new XMLHttpRequest();
        var response = await makeRequest('GET', 'https://kuroi1992.dyndns.pro/test?type=temperature&location=inside&name=schlafzimmer&time=24h');
        console.debug(response);
        var json = JSON.parse(response);
        console.debug(json);
        return json.map(x => {
              return [x['time'], x['value']];
          });
      } 
      return request();
  - entity: sensor.time
    name: Keller
    data_generator: |
      function makeRequest(method, url) {
          return new Promise(function (resolve, reject) {
              let xhr = new XMLHttpRequest();
              xhr.open(method, url);
              xhr.onload = function () {
                  if (this.status >= 200 && this.status < 300) {
                      resolve(xhr.response);
                  } else {
                      reject({
                          status: this.status,
                          statusText: xhr.statusText
                      });
                  }
              };
              xhr.onerror = function () {
                  reject({
                      status: this.status,
                      statusText: xhr.statusText
                  });
              };
              xhr.send();
          });
      }
      const request = async () => {
        var http = new XMLHttpRequest();
        var response = await makeRequest('GET', 'https://kuroi1992.dyndns.pro/test?type=temperature&location=inside&name=keller&time=24h');
        console.debug(response);
        var json = JSON.parse(response);
        console.debug(json);
        return json.map(x => {
              return [x['time'], x['value']];
          });
      } 
      return request();
apex_config:
  markers:
    hover:
      size: 5

Before anyone suggests it, yes, the same problem happens even if I use the sensors corresponding to the temperature sensor, I just replaced them with sensor.time because in the long run I want to run completely via data generator and I needed to test if it works with any random sensor.

I have another graph using the same code and web backend with similar temperatures and on thet one it displays correctly so far.

image

The webserver used for testing is not online most of the time, so if anyone tries to test the example ot, it most likely won’t work.

Anyone got any idea how to force the curves to display correctly? I did try to manually set a minimum for the yaxis, but that only moved the yaxis, but still didn’t render the curves down to the axis.

1 Like

I just want to say that I absolutely love this card. I struggled a lot trying to get the mini-graph-card to do what I wanted and ended up only partially succeeding, while it only took about 30mins to get this working 100%. Between this and the custom button card, my dashboard is about 90% RomRider-powered :slight_smile: .