ApexCharts card - A highly customizable graph card

Yes, definitely line.

type: custom:apexcharts-card
chart_type: line
header:
  show: true
  show_states: true
  colorize_states: true
series:
  - entity: sensor.pooltemperature
  - entity: sensor.serverroomtemp

Thanks

Is there any way to group points by timestamp into days without reducing the number of points? Essentially I have multiple events occurring on the same day, but on my chart I’d like to show them all in line over the x-axis label for that day. Currently, they are offset from the label depending on the time these events occurred. In the graph below, both of the dots represent events that occurred on Jan. 21, but as you can see they are shifted left from the Jan 21 label depending on the time of day they were recorded:
image

If possible, I’d like to stack them vertically directly above each other and above the Jan 21 label.

Current config:

type: custom:apexcharts-card
chart_type: scatter
graph_span: 1 week
apex_config:
  dataLabels:
    enabled: true
  yaxis:
    min: 0
    max: 1440
    tickAmount: 6
    labels:
      formatter: |
        EVAL:function(value) {
          var suffix = '';
          var hour = Math.floor(value / 60);
          if (hour == 0) {
            return '';
          }
          if (hour > 12) {
            suffix = 'PM';
            hour -= 12;
          } else {
            suffix = 'AM';
          }
          return hour + suffix;
        }
header:
  show: true
  title: Poop Chart
  colorize_states: true
series:
  - entity: button.poop_button
    color: '#704000'
    group_by:
      func: raw
      duration: 1d
    transform: |
      var time = new Date(x);
      return time.getHours() * 60 + time.getMinutes();  

I’ve one question how can i add a value of a sensor to the yaxis?

Hi, did not know this (admitting to not have read all options)
Question with that… I would like to color the label depending on another value
e.g. I have ‘pairs’ with value and boolean in my sensor

value:
 - 1
 - 2
..
value_b
 - true
 - false
...

Can one use an EVAL to change the style (color) of the label based on the boolean?

Unfortunately there is no formatter option available for label colors. You can change the colors to some extent. I have used 3 in this example.

yaxis:
  - id: °c
    decimals: 3
    apex_config:
      title:
        text: Temperatures °c
        style:
          fontSize: 16px
      forceNiceScale: true
      labels:
        show: true
        formatter: |
          EVAL:function(value) {
            let text = parseFloat(value).toFixed(0);
            let result = text.replace(".", ",");
            return result;
          }
        style:
          colors:
            - '#FFFF00'
            - '#ffffff'
            - '#0000FF'
          fontSize: 14px
series:

3_colors

To use external and variable values in the Apexcharts card you must first install the HACS - Frontend “Config Template Card” card.
Use the example below my screenshot to make it the way you wish.
afbeelding

type: vertical-stack
cards:
  - type: custom:config-template-card
    entities: sensor.nordpool
    variables:
      average: states['sensor.nordpool'].attributes.average
    card:
      type: custom:apexcharts-card
      graph_span: 24h
      hours_12: false
      header:
        title: cent/kWh uurtarief vandaag
        show: true
      span:
        start: day
      now:
        show: true
        color: grey
        label: Nu
      apex_config:
        annotations:
          yaxis:
            - y: ${average}
              y2: 40
              strokeDashArray: 5
              borderColor: var(--primary-color)
              opacity: 0.5
              label:
                text: ${average}
      series:
        - entity: sensor.nordpool
          type: column
          data_generator: |
            return entity.attributes.raw_today.map((start, index) => {
              return [new Date(start["start"]).getTime(), entity.attributes.raw_today[index]["value"]];
            });

I ended up to program my own data_generator to correctly sum-up long term statistics. Would be great if HA core team or apex-chart team fixes the problem.

thanks here for inspiration

For anyone who may need this…here my code:

chart_type: donut
graph_span: 30d
update_interval: 1h
series:
  - entity: sensor.daily_energy_consumption
    name: House
    show:
      datalabels: percent
    data_generator: |
      var statistics = await hass.callWS({
          type: 'recorder/statistics_during_period',
          start_time: new Date(start).toISOString(),
          end_time: new Date(end).toISOString(),
          statistic_ids: [entity.entity_id],
          period: "hour",
      });

      var stats = statistics[entity.entity_id];

      var result = [];
      var len = stats.length;
      var hour, day;
      var tzoffset = new Date().getTimezoneOffset()*1000*60;
      var timeoffset = tzoffset - 1000*60; //timezone -1min
      var sum = 0;

      for (let i = 0; i < len; i++) {
        hour = new Date(stats[i].start).getHours();
        day = new Date(stats[i].start).getDate();
        if(parseFloat(hour) == 0){ //add last value to result
          sum += stats[i].max;
        }
      }

      if(hour !=0){ //add last reading of current day but avoid double
        sum += stats[len-1].max;
      }
      result.push([(new Date(stats[len-1].end).getTime()),sum]);

      return result;

1 Like

Thanks but not exactly what I am looking for. I would like to have ‘conditional’ coloring but it was already a long shot. With your solution I can at least color the ‘limit’ red :slight_smile:

issue seems to be with Chrome and Firefox. On Edge the graphs are displaying correctly

I’ve already got an entity which calculates the average value, how can i add the following sensor to your vertical stack. Because removing - ‘y’: ${average} and change to - ‘y’: ${sensor.nordpool_today_average} wont work.

Do not change anything in the Apexcharts card, but try it with this:

type: vertical-stack
cards:
  - type: custom:config-template-card
    entities: sensor.nordpool
    variables:
      average: states['sensor.nordpool_today_average']
    card:
      type: custom:apexcharts-card

If i add the line the apexchard is gone, when i remove state i see the following without the correct value at the moment
Screenshot at Jan 23 14-34-10

sensor.nordpool_today_average
Screenshot at Jan 23 14-35-50

This is silly…
Replace the variable “average:” “states[‘sensor.nordpool_today_average’]” and change it in eg. “48”
Now you should see a line on 48.0
If not, then you have to check if everything is properly copied from my example.

type: vertical-stack
cards:
  - type: custom:config-template-card
    entities: sensor.nordpool
    variables:
      average: 48 # change this
    card:
      type: custom:apexcharts-card
      [...]

does anyone know if its planned to implement
reverseData: true
horizontalBars: true
So that i can have hours top to bottom with data values going from left to right ?

1 Like

I’ve rebooted the nas and it works fine now, thanks!

I have 2 questions;
How do I configure the vertical gridlines.
And is it possible to get 2 entities in the same place (column).

See my post above with windmolens as a background. It has a brief grid section and also covers stacked columns. More info for all options can be found here

I could make horizontal bar (column), but I still can’t figure out the rests, like swapping Y and X entities.
Hopefully someone else knows.

apex_config:
  plotOptions:
    bar:
      horizontal: true
      columnWidth: 80%
  dataLabels:
    enabled: true
    textAnchor: middle
    dropShadow:
      enabled: true
    offsetY: -12
    style:
      fontSize: 12px```

Hello,
starting to use ApexCharts. Spend a lot time in the thread and with searching.
Can someone help we.
Can I increase the textsize of the current states:

image

Thank you :slight_smile:

How to use if then else in a formatter function? The below code works, but some of the data value might be not available / undefined, so the tooltip will display NaN.

I want to catch that NaN, and convert it to 0.

Anyone can help?

apex_config:
  tooltip:
    enabled: true
    'x':
      format: MMM dd
    'y':
      formatter: |
        EVAL:function(value) {
        let text = parseFloat(value).toFixed(3);
        let result = text.replace(".", ",")+" m3";
        return result;
        }

SOLVED the issue by adding fill: zero in the group_by:

series:
  - entity: sensor.helper_gas_consumption
    type: column
    float_precision: 3
    fill_raw: zero
    group_by:
      fill: zero
      func: last
      duration: 1d

Then catch the value in the datalabels formatter:

  dataLabels:
    enabled: true
    formatter: |
      EVAL:function(value) {
      if (value == 0) {
        return " ";
      }
      return value;
      }