ApexCharts card - A highly customizable graph card

Ah, I see. I was wondering why opacity was not working. Wish I had read the buglist before I spent hours trying to get it to work. :smile: Thank you @RomRider for clarifying. Do you actually do anything else with your life other than answer hundreds of questions, queries, improvements and bugs? :crazy_face:

Haha, yeah, I have a real job which is definitely not being a developer, you’d know if you had a look at the code :sweat_smile:
But I don’t sleep much, it’s cheating :rofl:

There’s a feature request already for that, I didn’t make my min on how I’ll do it yet :blush:

I appreciate the words, thanks :blush: as I said a bit above, I do this for fun and my reward is you, users, using this card.
I’d rather you spend that money on charities instead :wink:

The ApexCharts doc says that it doesn’t work on datetime charts like you use for the x-axis:

Note: tickAmount doesn’t have any effect when xaxis.type = datetime

So I guess it’s not possible :blush:

2 Likes

What a Guy ! I’d second the offer to buy you a virtual beer if you PM a paypal addy. After all, you do seem to be doing this for charity :grinning: and putting a huge amount of effort for tens maybe hundreds of forumites . Anyway upto you. :white_check_mark:

I guess I could extend the fill_raw feature to support data_generator to fill the gaps. Would that work for you?

Or even simpler, you return 0 (or don’t return anything) instead of null when the data is null. I don’t know what null means for precipitation in your case: is it actually 0? Or is it really missing data and the integration doesn’t know what value it should be?

It’s not so complex in reality :slight_smile:

Remove null entirely:

data_generator: |
  return entity.attributes.forecast.flatMap((entry) => {
    if (entry.precipitation === null) return [];
    return [[new Date(entry.datetime).getTime(), entry.precipitation]];
  });

Return 0 instead of null:

data_generator: |
  return entity.attributes.forecast.map((entry) => {
    return [new Date(entry.datetime).getTime(), entry.precipitation || 0];
  });
1 Like

Right :slight_smile: Yeah I looked at those options at various points and they were a bit of a hassle. Anyway, very happy that you have cracked a comprehensive charting solution.

How would this work for selecting the sensor? I tried the below which doesn’t work…

type: 'custom:apexcharts-card'
graph_span: 24h
apex_config:
  plotOptions:
    pie:
      donut:
        total:
          show: true
          showAlways: true
          formatter: sensor.daily_energy_house_total
span:
  start: day
  offset: '-1d'
header:
  show: true
  title: Power consumption daily
chart_type: donut
series:
  - entity: sensor.daily_energy_boiler_total
    name: Boiler
  - entity: sensor.daily_energy_dishwasher_total
    name: Dishwasher

@RomRider I tried to use are type of chart to draw my router throughput with fill and nice gradient, by I come to somehow strange, unexpected result:
Screenshot 2021-02-06 at 10.34.48
As you can see direction of gradient in bottom and upper parts is the same (with colored part up and blackened down), while I’d expect colored part of gradient to be towards peaks of graph. Is this Apex bug or something controllable?
Here is teh code I use for this setup:

type: 'custom:apexcharts-card'
show:
  loading: false
apex_config:
  stroke:
    width: 2
  chart:
    height: 250
  fill:
    type: gradient
    gradient:
      type: vertical
      shadeIntensity: 0.8
      stops:
        - 0
        - 500
      inverseColors: false
header:
  show: false
graph_span: 5min
series:
  - entity: sensor.internet_speed_in1
    color: var(--light-magenta)
    name: in
    type: area
  - entity: sensor.internet_speed_out1
    color: var(--yellowish)
    name: out
    invert: true
    type: area

BTW, for my use this is the most amazing card available for HA at the moment! My wish come to live! Thank you so much for AWESOME work you did bringing this to community!

Thx, fill_raw is the easy way as it will work “always”

did test your 2 scripts. first:

second:

second option works out…
thanks…

Hello all.
RomRider! those graphs are sick! Thank you very much for your work.

I have a question, maybe not exactly related to those graphs, but after ApexCharts appeared I came to idea of monitoring ISP quality pinging some selected hosts.

I figured out, that if several consecutive ping failures are registered into binary sensor, those are not counted. I suppose it is how it should work indeed, cause binary_sensor state is changing for the first registered failure, then does nothing until ping succeeds.

Two ideas came in my mind:
To count number of failures storing them into sensor then reset every hour (to get totals per hour). It has one cons, that counter are reset at data generation stage not on presentation layer.
Another idea is to reset state of binary sensor after every failed ping.
But maybe there better way? I’m asking before I jump into inventing the wheel.

this is a draft of what I’m goint to achieve. it works but obviously doesn’t count consecutive failures
Thank you in advance

If there’s no new state writen (it could be off and still have consecutive off state written in the history), there’s not much you’ll be able to do even with automation / other template sensors. I don’t know how the ping binary_sensor works under the hood so not sure I can help.

It’s always from bottom to top if you use shade. Not much I can do, as that’s how it’s supposed to work in Apexcharts.
Instead you can try opacityFrom and opacityTo which supports arrays (one array item per serie) and thus you could invert them for one of the 2 series

Understood. Thank you for answer.
Now I went the road down toward counting messages (failures) and resetting counter periodically. For test purposes I’m testing not existent IP. This way I’ve get 4 failed pings per 15 secs.

Now I have doubts how it works. Dev tools definitively shows the state is published to HA (I’ve added timestamp as attribute). So during a minute I have state reports, however with the same value.

But it strangely calculates sum

type: 'custom:apexcharts-card'
graph_span: 60m
series:
  - entity: sensor.isp4_fail_counts
    name: 192.168.100.2
    type: column
    group_by:
      func: sum
      duration: 1min


It should show 16 per minute… but still shows 4

It’s even more strange when using ‘fill’ option:

type: 'custom:apexcharts-card'
graph_span: 60m
series:
  - entity: sensor.isp4_fail_counts
    name: 192.168.100.2
    type: column
    group_by:
      func: sum
      duration: 1min
      fill: 'zero'

This hight bar has value 87, which are 2 consecutive values: 83 and 4 recorded in history. Then following “fours” are recorded but somehow ignored by the graph
Other ‘random’ trials suggests that repeating values are treated as non-existing ones. But it’s my rough guess. Obviously I’m missing something.

Edit: I’ve checked HA history… indeed this “4” is recorded only once.


then how work with same values and missing ones?

I don’t think it does :slight_smile:
group_by 1min over 60min is creating 60 buckets worth of 1min of state history (if there’s nothing in the history for a specific bucket, because there is no home assistant state change, by default it will fill the empty buckets with the last known value). The groups are starting to be created from the end of the chart (minus 1min for each bucket), the end of the chart in your case being exactly now (at the millisecond precision). So it will sum 83 and 4, giving you 87, then everything after is just getting 1 value of 4 (because of fill: last) or 0 (if fill: zero).

You can’t, there’s not way to create data out of missing data :man_shrugging:

Yeah… understand that you cannot do anything if HA doesn’t provide data.
Strange is, that subsequent sensor values of the same value are intercepted by the HA, but somehow history provides the first one only.
This trying to imagine if it couldn’t be a problem while measuring other things. Like power which doesn’t change over time, but is still provided.

So for me, the only way is to count missing pings to infinity

Are you sure that last_updated or last_changed in your sensor is upating for consecutive states with the same value?
You might want to look at: https://developers.home-assistant.io/docs/api/rest/ -> /api/history/period/<timestamp>

If you can check that with significant_changes_only=0 it reports those consecutive states with the same value, and with significant_changes_only=1 it only provides the first one, then I can maybe do something for you. :slight_smile:

Yes. I’m sure. Developer Tools shows the timestamp changing while value remains the same.

Ok, I suppose I can add that feature then. :slight_smile:
Mind opening a feature request?

I’ll do that.
Yet checking the API you asked for.

If manage to do it, please paste a slice of the json with several consecutive states with the same value in the feature request. It will help :slight_smile:

Is there any way to add a mdi icon in the header? (Tried searching the thread and github without success.)