ApexCharts card - A highly customizable graph card

FYI - I’ve solved my own problem. It was not showing the correct range. Updated YAML below
Screenshot 2022-02-14 182815

type: custom:apexcharts-card
graph_span: 24h
span:
  start: minute
header:
  show: true
  title: Amber Electricty Forecast
  show_states: false
  colorize_states: true
series:
  - entity: sensor.amberelectricity_general_forecast
    float_precision: 2
    data_generator: |
      return entity.attributes.forecasts.map((entry) => {
        return [new Date(entry.nem_date), entry.per_kwh];
      });
yaxis:
  - min: 0
    max: ~0.40
    decimals: 2
    apex_config:
      forceNiceScale: true

Is there a simple way (does someone have example code) to have a horizontal dotted line in the diagram to display a threshold? I would assume that it just needs a single value via the data generator which is then prolonged endlessly, but I am not sure how this would practically look like

Do i do this correctly?
I want to update the chart not at every change (this works, but is way to often with my sensor).
When i insert the update_interval: 5min nothing updates at all. Delete it - it updates again with every sensor update.

- type: custom:apexcharts-card
  update_interval: 5min
  header:
    title: test (48h)

Thank you.

Hi,

thanks for great chart!

I’m currently configuring my first chart and I have a question: my chard displays only one sensor data for period of 2 days. Is it possible to display max value of sensor on the right side of div id=header__states and how to do that?

I checked this (https://github.com/RomRider/apexcharts-card/issues/218), but this is not what I want. I want to see max history value “max 25.4°C” in the header.

This is my card:

type: custom:apexcharts-card
hours_12: false
graph_span: 2d
header:
  show: true
  title: Out temperature
  show_states: true
  colorize_states: true
show:
  loading: true
  last_updated: true
experimental:
  color_threshold: true
series:
  - entity: sensor.viking_0203502038_51_06_temperature
    stroke_width: 4
    type: column
    group_by:
      func: avg
      duration: 30min
    color_threshold:
      - value: 0
        color: blue
      - value: 1
        color: yellow
      - value: 10
        color: orange
      - value: 25
        color: red

Thanks for help.

The help of the transform function says:
With transform, you can modify raw data comming from Home-Assistant’s history using a javascript function.

I try to use that to draw a line that is always 4 points below another sensor being displayed in the same graph. But I would expect that this considers also the history and therefore moves up and down as per the reference sensor, but it doesn’t - instead it draws a straight line where the last point of the reference sensor is. Have I misunderstood something?

grafik
The red line should move up and dosn with the blue line, 4 points below. But it remains a straight line.

Here is my code:

type: custom:apexcharts-card
header:
  show: true
  show_states: true
  colorize_states: true
series:
  - entity: sensor.bsb_lan_trinkwassertemperatur
    stroke_width: 3
  - entity: sensor.bsb_lan_trinkwassersollwert
    stroke_width: 2
    curve: stepline
    fill_raw: last
  - entity: sensor.bsb_lan_kesseltemperatur
    transform: return x = hass.states['sensor.bsb_lan_trinkwassersollwert'].state - 4
    stroke_width: 1
    unit: °C
    curve: stepline

Btw., the help on the github page is not really clear about the statements of the transform function, thas was quite some try and error to get at least anything displayed.

Can’t find a way to define number of decimals in the header (only yaxis), can someone pelase point me in the right direction?

Edit: The float_precision: 2 works but if the value is “1” it is just shown as “1” instead of “1.00”.

Hello! With my Heat/AC pump model Daikin there was created a sensor named “sensor.daikinap42587_heat_energy_consumption”.
And according to this site It do show me the energy kwh per hour:

This is how it looks in the settings:

Knowing that, if i put that sensor in this code:

type: custom:apexcharts-card
graph_span: 168h
header:
  title: Värmepump Energi Värme 24h
  show: true
series:
  - entity: sensor.daikinap42587_heat_energy_consumption
    type: column
    name: Värmepump Energi Värme
    group_by:
      func: sum
      duration: 24h

Will that show me correct consumption per day?
It do show up like this:

But it seem to show the energy between the middle of the days? Not 00:00 to 24:59?
Or am I missing something?

Thanks!

I think I have found a bug.

In the chart below I only want one series to be drawn in the graph, and that is “Aktuell förbrukning”. The other two, “Easee-laddning” and “Ampere fas 1” should only be shown in the header. The problem is that the yaxis get’s a scale that also takes “Ampere fas 1” into consideration.

If I also plot the “Ampere fas 1” you see why the yaxis goes all the way up to 25:

One work around would be to use max: 5 but since I already have min: 0 I haven’t been able to combine them. Code below, all help with getting this to look correct would be appreciated.

type: custom:apexcharts-card
header:
  title: ''
  show: true
  show_states: true
graph_span: 24h
apex_config:
  tooltip:
    enabled: true
  yaxis:
    forceNiceScale: true
  xaxis:
    axisBorder:
      show: false
    labels:
      style:
        fontSize: 10px
        fontFamily: Segoe UI Light
  chart:
    height: 225
  grid:
    show: false
    borderColor: '#404040'
    strokeDashArray: 3
    position: back
  legend:
    show: false
  dataLabels:
    enabled: false
  stroke:
    width: 0
  fill:
    type: gradient
    gradient:
      type: vertical
      shadeIntensity: 0
      inverseColors: false
      opacityFrom: 0.9
      opacityTo: 0.6
      stops:
        - 10
yaxis:
  - min: 0
    apex_config:
      forceNiceScale: true
      decimalsInFloat: 1
      labels:
        style:
          fontSize: 10px
          fontFamily: Segoe UI Light
series:
  - entity: sensor.el_forbrukning_kw
    name: Aktuell förbrukning
    color: white
    float_precision: 2
  - entity: sensor.easee_laddbox_power
    color: white
    name: Easee-laddning
    show:
      in_chart: false
    float_precision: 1
  - entity: sensor.el_forbrukning_kw
    name: Aktuell avg förbrukning
    type: column
    color: fc7703
    show:
      in_header: false
      legend_value: true
    fill_raw: last
    group_by:
      func: avg
      duration: 15min
    float_precision: 2
  - entity: sensor.current_l1_vagen
    name: Ampere fas 1
    color: white
    type: column
    float_precision: 1
    show:
      in_chart: true
style: |
  ha-card {
     --ha-card-background: rgba(0, 0, 0, 0);
     box-shadow: none;
     margin: 8px 8px 38px 8px;
     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
   }

Hi I have a string of dates and I’m trying to parse them onto the chart. On the javascript compiler, it works fine, but when I try to use it in a data_generator it would just load infinitely.

The string is: "2022-02-17 04:00:00+02:00 2022-02-17 02:00:00+02:00 2022-02-17 03:00:00+02:00"

var dates = "2022-02-17 04:00:00+02:00   2022-02-17 02:00:00+02:00   2022-02-17 03:00:00+02:00"

console.log(dates.split("   ").map((entry) => {return [new Date(entry).getTime() + 7200000, 1];}))

And the compiler outputs

[ [ 1645070400000, 1 ],
  [ 1645063200000, 1 ],
  [ 1645066800000, 1 ] ]
- type: 'custom:apexcharts-card'
        view_layout:
          grid-area: col3
        header:
            show: true
            title: Electricity Price Today & Tomorrow
            show_states: false
        graph_span: 2d
        span:
            start: day
        series:
            - entity: sensor.nordpool_hours_to_charge_today
              name: Today
              data_generator: |
                 return entity.split("   ").map((entry) => {
                   return [new Date(entry).getTime() + 7200000, 1];
                 });
              type: column
              show:
                 legend_value: false
                 in_header: false
              extend_to_end: false

However this chart is stuck at Loading… Any suggestions?

Thank you!

EDIT: I believe the problem was that I needed to add .state next to entity return entity.state.split
the graph now loads however it doesn’t show any data

My sensor:
image

Any ideas what could it be?

SOLVED: it appears that the spaces between the dates were actually “\n \n \n” so adding these to the split solved the issue

The transform function seems to really not do what it should. Referring to my post above (ApexCharts card - A highly customizable graph card - #1427 by flobidan), without changing the code, now it looks like this:
grafik

The red line is supposed to be parallel to the blue line, because it takes the blue line minus 4. Where is this time shift coming from? And as soon as the blue line goes down to 44 again, the red line does also change for the past.

There does not seem to be that much support here for that otherwise great project, many questions but only few answers :frowning:

This comment is very unfair to the author of ApexCharts.
I think we can agree that RomRider is a developer who answers most questions in his limited time.
By the way, I had the same problem as you and I found the solution by searching this thread.
I wish you success .

2 Likes

Hi,
I store daily values on a simple database, 2 columns date and value. I’ve created a sensor that returns the values based on a selected month (input_select) and return the values from that month. Till here all work fine.
I’m now trying to create the graph showing the selected month.
If I query the last 30 days it work without issues, the problem is if I select a specific month, as I I can’t manage to define the xaxis range, it always show the latest 30days (defined on graph_span) and not the values on queried interval.
Does anyone have any tip to overcome this? I’ve search a solution but couldn’t find so far.
Many thanks in advance

This is not against the author personally. Compared to e.g. button-cards, where always someone has an answer, I just see a mismatch of people that try to use this and people that have the necessary experience with this. Scroll up and you see more than a week of multiple questions by multiple people, no reply on any of them.
But thanks for sharing the solution. “I know something, but I don’t tell you”.

Has anyone been able to remove the red part below? Feels like the date information is unnecessary to show twice? Or is it possible to show the value in the red part and skip the top tooltip?

I have a slight problem.
I have one chart that measure my heat pump energy “per hour” and one for “per day”.
And it didnt match what numbers the heat pumps own app said.
The heat-energ-sensor gives me the pumps kWh per hour.
But when I look more into it it seems that the chart takes the value in the “00:00:00” and put that value in the next day. But that is wrong and the first value for the new day should be at “01:00:00”.
How do I tell the chart to do this?

This is my code atm:

type: custom:apexcharts-card
graph_span: 48h
yaxis:
  - min: 0
    max: 1.5
span:
  end: hour
header:
  standard_format: true
  title: Värmepump - Per Timme
  show: true
  show_states: true
  colorize_states: true
all_series_config:
  type: column
  group_by:
    func: sum
    duration: 1h
series:
  - entity: sensor.daikinap42587_heat_energy_consumption
    name: Värmepump Värme Energi

Hi, not sure if will solve your issue, but try to add: “extend_to_end: false” under “series”.

hm, nope it still count that data from 00:00 from the day before.
Do I need to remove something when adding it?
If I set the duration to 23 hour I get the correct sum of the kWh this current day! But is that the real solution here? hm…

I think this did it for me…

span:
  end: day
  offset: +1h

That way it start the day from the data of 01 !

Unfortunately the library I use doesn’t allow to hide a serie from the legend.

Only way would be to set the number of ticks I believe

If the color threshold give a weird look, it’s because you have null data in your chart, that could be fixed with fill_raw: last

For your other question, you have the option to create a gradiant with options from here

That’s not possible unfortunately. One way to hack it is to make 2 series, on which filters out everything that is >0 and displayed as an area and the other one which filters everything that is <0 and displayed as a line

Not sure I understand what you want to achieve :blush:

Why not create a utility meter which resets every hour? (not sure it’s possible though)

Why not use an annotation to highlight a band in the chart?

You’ll need to prepend the current value with the current timestamp in the data generator

Not possible to skip a period on the timeline unfortunately. You could however stack the 3 days on top of each other using offset and reduce the timeline to only 6-22 in this case

You could use card-mod for that

You can use group_by with the diff function and a duration of 1d

You can remove the legend with:

apex_config:
  legend:
    show: false

Not at the moment, but I might add templates like in button-card at some point

That is something that might be able to fix, please open a feature request

Not possible at the moment, please open a feature request

The gradient configuration supports to be defined as an array, that’s the way to fix your issue

Yes, you can use annotations

That is not possible, at least for now.

Just do return x - 4;

You’ll need end: day to align the chart to the end of the day

That might be a bug, please open one on gh

You can remove that with

apex_config:
  xaxis:
    tooltip:
      enabled: false

You can’t, apexcharts-card relies on your history, so you need to fix your sensor (or ignore the first hour like you did)

5 Likes

Is there a way to calculate the number of ticks?
i.e. for the humidity example above: (max - min) / 10 + 1 → (90 - 50) / 10 + 1 = 5