ApexCharts card - A highly customizable graph card

I guess it should be possible with Data Generator feature, yet FWIW I haven’t found any good example and haven’t tried it yet myself.
The question has been raised numerous times in this board and I believe @jchh has made a feature request for that too: ApexCharts card - A highly customizable graph card - #1962 by jchh
Would be great feature indeed and save a lot of manual work creating needed math entities in HA.

How do I enable tooltip only for one serie?
I have tried to set the series-name, and index, but it wont work.

  apex_config:
    tooltip:
      enabledOnSeries:
        - 'name_of_my_serie'

Thanks!

For my energy graphs I wanted the option to step through days backward and forward.
I could not find an easy way in the Apex Charts, so I ended up implementing a solution including a input_number helper, custom:button-card and custom:config-template-card.

It looks like this:

By pressing < and > I can navigate through days.

The code is in this gist.
Maybe it inspires you.

If you know a better solution, let me know :slight_smile:

3 Likes

try extend_to: now under entity? (or false if you want the line to stop at the datapoint not “now”)

Is it possible to use a value for the “now” label? I tried using EVAL like for axis labels but no joy.

I want the current value of one of the series or a sensor state from HA using the hass.states array like below, it doesnt parse the code and uses the code as the label.

now:
  show: true
  label: |
    EVAL:function(value) {
      return parseFloat(hass.states['sensor.somesensor'].state).toFixed(2);}

Edit:

Try the hass.states['sensor.somesensor'] syntax above? should be valid JS inside the data generator

Yeah I found the hass object and duped it to the console and figured that out a bit after posten, so what you suggested work fine :slight_smile:
Isn’t there any method to get a sensor value or do we need to get it directly from the array?

Thanks for your reply but this doesn’t work for me. sensor.garaget is a temperature sensor returning 6.6.

  annotations:
    position: back
    yaxis:
      - 'y': sensor.garaget
        strokeDashArray: 5
        borderColor: '#f7a6af'
        borderWidth: 1

Nothing special, just a pie chart :slight_smile:

type: custom:apexcharts-card
chart_type: radialBar
header:
  title: ''
  show: true
  show_states: true
apex_config:
  plotOptions:
    radialBar:
      offsetY: 0
      startAngle: -130
      endAngle: 130
  legend:
    show: false
  chart:
    height: 200px
  stroke:
    lineCap: round
  fill:
    type: gradient
    gradient:
      type: vertical
      shadeIntensity: 0
      inverseColors: false
      opacityFrom: 0.9
      opacityTo: 0.7
      shade: dark
      stops:
        - 10
        - 100
series:
  - entity: sensor.current_l1_street
    name: Fas 1
    color: 2eb9ff
    show:
      in_header: false
    min: 0
    max: 20
  - entity: sensor.current_l2_street
    name: Fas 2
    color: 2db9dd
    show:
      in_header: false
    min: 0
    max: 20
  - entity: sensor.current_l3_street
    name: Fas 3
    color: 2cb9aa
    show:
      in_header: false
    min: 0
    max: 20
style: |
  ha-card {
     --ha-card-background: rgba(0, 0, 0, 0);
     box-shadow: none;
     margin: 0px 0px 0px 0px;
     font-size: 15px;
     font-family: 'Segoe UI Light";
     text-align: center
   }
   div#header__title {
     font-size: 20px;
     font-weight: 300;
     font-family: 'Segoe UI Light";
     font-color: #ff0000
   }

Did you manage to get the “now” label to display the value? I keep getting the full sensor name in the label instead of the actual value.

I think its possible by layering Config Template Card on top of apexcharts, but I settled on displaying the value in the legend, and only showing the one series in the legend by accident

apex_config:
  legend: #show up top, on top of graph, save space
    floating: true
    position: top
    customLegendItems: #didt set the title, but having only one entry seems to hide the other series.
      - Forbruk 

How do I use two y axis and have the y=0 on the same level for both series?

I guess I’m missing something here and if someone knows how to do it I would very much appreciate it :slight_smile:

This is how I would like it to be (but with two axis):

But this is how it turns out:

Edit:
Here is the code :slight_smile:

type: custom:apexcharts-card
header:
  title: ''
  show: false
  show_states: true
  colorize_states: false
graph_span: 24h
apex_config:
  tooltip:
    enabled: true
    x:
      format: hh:mm
  annotations:
    position: back
  yaxis:
    - id: Värmebehov
      forceNiceScale: true
      decimalsInFloat: 1
      opposite: false
      labels:
        style:
          fontSize: 10px
          fontFamily: Segoe UI Light
    - id: Kompressor
      max: 200
      forceNiceScale: true
      decimalsInFloat: 0
      opposite: true
      labels:
        style:
          fontSize: 10px
          fontFamily: Segoe UI Light
  xaxis:
    axisBorder:
      show: false
    labels:
      style:
        fontSize: 10px
        fontFamily: Segoe UI Light
    tooltip:
      enabled: false
  legend:
    show: false
  chart:
    height: 225
  grid:
    show: true
    borderColor: '#EDEDED'
    strokeDashArray: 4
    position: back
  dataLabels:
    enabled: false
  fill:
    type: gradient
    gradient:
      type: vertical
      shadeIntensity: 0
      inverseColors: false
      opacityFrom: 1
      opacityTo: 0.8
      stops:
        - 10
series:
  - entity: sensor.nibe_105703_43005
    name: Värmebehov
    yaxis_id: Värmebehov
    type: column
    color: fc7703
    fill_raw: last
    group_by:
      func: avg
      duration: 15min
    float_precision: 0
  - entity: sensor.nibe_105703_43136
    name: Kompressor
    yaxis_id: Kompressor
    type: column
    color: b0e4ff
    float_precision: 0
    fill_raw: last
    group_by:
      func: last
      duration: 15min

Sorry, I didn’t try that I used that sensor for calculating some values for the series data.

How can i change the graph so it will not start at 0 for both enttities? like the 2 right pica’s.

Hello.

Is it posible to set value in color_threshold with a input_number?

color_threshold:
  - value: 0
    color: green
  - value: 3
    color: orange
  - value: 4
    color: red
  - value: states.input_number.test
    color: darkred

This is not working

Hi there!
Hope someone can help me with this. I accidentally got a invalid state from a sensor, with a value 100 times greated than what it actually should read. This datapoint got into the card, and now I’ve got a huge spike, and the Y-scale is all messed up. I located the failty datapoint in the state table and removed it, but the spike is still there in the graph. What more do I need to do to remove it?
Thanks

Fiddling with the db I’d say to wipe/replace the value.

a couple solutions spring to mind
Best would be to use something similar to this snippet I ripped from a chart I use.
it simply builds the average across 15min so that a single spike sort of gets flattened out.

      all_series_config:
        type: column
        group_by:
          duration: 15m
          func: avg

Benefit, you still have the exact sensor readings in the db not just on the visualisation side.

The other idea would be you defined a valid range and skip readings being out of scope.
Something such as

    filters:
      - sliding_window_moving_average:
          window_size: 16
          send_every: 8

If I were you … lean back the spike moves to the left by time. And better concentrate to code not only so that it works if every is right, but also the code covers situations when something goes wrong.

Thanks! It’s three months I have to see that spike if I just wait it out.

I’ll try to see if I can make the filter work. Not sure where it should go in. It’s a apex_config section I assume?

For me, I’d prefer to get the value to disappear. As I wrote I deleted it from the state-table, but it’s still present. I’ve tried to see if it’s in the “statistics” table now, but haven’t been able to find it.

EDIT: Noticed something strange. If i edit the card, it shows correct, without the spike, but as soon as I leave edit mode it doesn’t. And the thing is, I shouldn’t need to use any filter or averages because the value I read is the sensors own “average” attribute.

It’s the nordpool-sensor I try to fix, which shows the spot electricity prices over the day, but it also has a attribute that is the average price today, and I beleive that is not calculated but something that is read from the nordpool API. I use this attribute to graph the last three months of daily averages.

In “edit” mode:

image

Not in “edit” mode:

image

Had a quick look at the github nordpool thing and it’s lovelace example code.
I would limit the upper and lower bound within the apexchart lovelace yaml since averaging financial things is surely the wrong way. It is in common, to not modify sensordata but cure the representation.

And yes, edit mode in Apex Charts isn’t WYSIWYG … it’s something close but not identical.

I’m having a strange issue with my month view. I only have 2 datapoints this month and it shows the graph in a strange way:


The previous month with all data points works just fine, and the day view where not all data points are present also just works fine:

Is there any setting I’m missing? The graph_span is month and the start or end can either be week, doesn’t matter.

type: custom:apexcharts-card
          style: |
            #header__states {
              display: grid !important;
              grid-auto-flow: row;
              grid-template-columns: repeat(3, 30%);
            }

            #states__state {
              flex-basis: 30%;
              margin: 5px;
            }
          apex_config:
            chart:
              stacked: true
              type: area
              height: 150px
            legend:
              show: false
            fill:
              type:
                - gradient
              gradient:
                shadeIntensity: 1
                inverseColors: false
                opacityFrom: 0.45
                opacityTo: 0.05
                stops:
                  - 20
                  - 100
                  - 100
                  - 100
            stroke:
              show: true
              curve: smooth
            yaxis:
              forceNiceScale: true
              min: 0
              decimals: 2
            responsive:
              - breakpoint: 10000
                options:
                  chart:
                    height: 250px
          graph_span: 1month
          span:
            start: month
            offset: ${('-' + states['input_number.offset_energy_month'].state + 'month')}
          header:
            show: true
            title: Stroom
            standard_format: true
            show_states: true
            colorize_states: true
          now:
            show: true
          series:
            - entity: sensor.daily_energy_meter_no_wallbox
              type: column
              group_by:
                func: max
                duration: 1d
              stroke_width: 2
              color: "#6BA547"
              show:
                in_header: false
                legend_value: false
            - entity: sensor.util_wallbox_daily
              type: column
              group_by:
                func: max
                duration: 1d
              stroke_width: 2
              extend_to: now
              color: "#619ED6"
              show:
                in_header: false
                legend_value: false

I’m trying to make a graph that starts at the beginning of the month, and extends up until now, or at least the end of today. I thought using

span:
   start: month 

would work, but somehow that makes the graph span only the first day of the month. Closest I’ve gotten is using end and graph span, however I believe that isn’t templatable. Current code for the two options is:

type: vertical-stack
cards:
  - type: custom:apexcharts-card
    style: 'ha-card { height: 100%; }'
    view_layout:
      grid-area: timeline
    header:
      show: true
      title: Eieren gegeten
      show_states: true
      colorize_states: true
    series:
      - entity: pyscript.eilijst_stats_persist
        name: ' '
        extend_to: now
    graph_span: 3d
    span:
      end: hour
    show:
      loading: false
  - type: custom:apexcharts-card
    style: 'ha-card { height: 100%; }'
    view_layout:
      grid-area: timeline
    header:
      show: true
      title: Eieren gegeten
      show_states: true
      colorize_states: true
    series:
      - entity: pyscript.eilijst_stats_persist
        name: ' '
    span:
      start: month
    show:
      loading: false

Which has them showing up like this:


The top one is what the graph should look like, but it won’t be correct yesterday. The bottom graph starts at the end of November 30th and extends to the start of December 2nd, hence it’s missing 2 days right now. I think I’m simply missing something obvious here, but so far haven’t been able to figure it out.

Hello from Germany :slight_smile:

I’ve been playing with ApexCharts a while now and I must say: love it! Should be a standard in HA.

I’ve build several charts now and this is one of them:

What I want to do is display the water consumption costs together with the amount - like this:

However, the price here in this chart is calculated using a fixed number (2.5) in the dataLabel formatter:

  dataLabels:
    enabled: true
    offsetY: -10
    background:
      padding: 2
      opacity: 0.7
    formatter: |
      EVAL:function(value) {
        return [value , "(" + ((value/1000)*2.5).toFixed(2) + "€)"]
      }

I’ve got an input_number entity that holds the price and I would like to use that in the formatter:

    formatter: |
      EVAL:function(value) {
        return [value , "(" + ((value/1000)*(hass.states['input_number.water_price'].state)).toFixed(2) + "€)"]
      }

This, however, does not work :frowning:

Does anyone have an idea what I’m doing wrong or is the hass object not available for the dataLabel formatter?

Entire card code
type: custom:apexcharts-card
graph_span: 1w
span:
  start: isoWeek
show:
  last_updated: false
  loading: false
header:
  show: true
  title: ''
  show_states: true
  colorize_states: false
all_series_config:
  unit: liter
series:
  - entity: sensor.water_usage_daily
    type: column
    show:
      datalabels: true
      legend_value: false
    color: dodgerblue
    name: Daily
    group_by:
      func: max
      duration: 1d
  - entity: sensor.water_usage_weekly
    type: line
    show:
      datalabels: false
      legend_value: false
      offset_in_name: false
    color: deepskyblue
    opacity: 0.7
    stroke_width: 2
    name: Daily average
    offset: '-1w'
    transform: return x / 7;
    group_by:
      func: max
      duration: 1w
  - entity: sensor.water_usage_daily
    type: column
    show:
      in_header: false
      datalabels: false
      legend_value: false
      offset_in_name: false
    color: '#eeeeee'
    opacity: 0.7
    name: Previous week
    offset: '-1w'
    group_by:
      func: max
      duration: 1d
apex_config:
  dataLabels:
    enabled: true
    offsetY: -10
    background:
      padding: 2
      opacity: 0.7
    formatter: |
      EVAL:function(value) {
        return [value , "(" + ((value/1000)*2.5).toFixed(2) + "€)"]
      }
  chart:
    height: 180px
  legend:
    show: true
  xaxis:
    labels:
      format: ddd
  plotOptions:
    bar:
      horizontal: false
      borderRadius: 0
      columnWidth: 70%

Tinus

1 Like