ApexCharts card - A highly customizable graph card

so, full config now:

Why is there a 0 in the legend…?

  - type: custom:apexcharts-card
    graph_span: 48h
    update_interval: 1h
    header:
      show: true
      title: Solar Forecast
    experimental:
      color_threshold: true
    span:
      start: day
    now:
      show: true
      label: Now
    yaxis:
      - id: estimate
      - id: actueel
        show: false
    apex_config:
      plotOptions:
        bar:
          columnWidth: 100%
    series:
      - entity: sensor.solar_forecast_estimate_watts
        name: Solar power
        yaxis_id: estimate
        data_generator: |
          let res = []; for (const [key, value] of
            Object.entries(entity.attributes.watts)) {
            res.push([new Date(key).getTime(), value]);
            } return res;
        color_threshold:
          - value: 0
            color: cornsilk
          - value: 500
            color: papayawhip
          - value: 1000
            color: yellow
          - value: 1500
            color: gold
          - value: 2000
            color: orange
          - value: 2500
            color: darkorange
          - value: 3000
            color: tomato
          - value: 3500
            color: sandybrown
          - value: 4000
            color: peru
          - value: 4500
            color: orangered
          - value: 5000
            color: maroon
          - value: 5500
            color: purple
          - value: 6000
            color: darkred
        type: column
        show:
          extremas: true
        opacity: 1
        float_precision: 0
        stroke_width: 5

      - entity: sensor.zp_actuele_opbrengst
        yaxis_id: actueel
#         transform: return x /1000;
#         unit: kW
        type: line
        name: Actueel
        stroke_width: 2
        extend_to: false
        color: grey
        group_by:
          func: min
          duration: 60m
        show:
          legend_value: true
        float_precision: 0

aside form the colors threshold colors (the lower colors are too light), id love to have those bars we wider, and leave less whitespace. Is there some default config setting for that, or do I simply need to set the stroke_width to a higher number.
figured the columnWidth: 100% should be doing that, but apparently not.

I can set the
stroke:
width:

global option, because then it also makes the secondary line fat and I want that to be a thinner line. like in

more like this, whihc I copied at first, but still showed very thin bars…

Try with:

group_by:
   func: last ( or raw )

maybe also “duration: 1month” beneath “func”

Try this “Global”(by this you can control columWidth), and then you can stil add on a individual line-serie “stroke_width: 5”


    all_series_config:
      stroke_width: 1
      group_by:
        func: min
        duration: 1h

PS: No need for “stroke_width” on/inside column-serie

1 Like

thanks, that works beautifully. And not needing an individual stroke_width now:

type: custom:apexcharts-card
graph_span: 48h
update_interval: 1h
header:
  show: true
  title: Solar Forecast
experimental:
  color_threshold: true

all_series_config:
  stroke_width: 1
  group_by:
    func: min
    duration: 1h

span:
  start: day
now:
  show: true
  label: Now
yaxis:
  - id: estimate
    decimals: 0
  - id: actueel
    decimals: 0
    show: false
apex_config:
  plotOptions:
    bar:
      columnWidth: 100%
series:
  - entity: sensor.solar_forecast_estimate_watts
    name: Solar power
    yaxis_id: estimate
    data_generator: |
      let res = []; for (const [key,value] of
        Object.entries(entity.attributes.watts)) {
        res.push([new Date(key).getTime(),value]);
        } return res;
    color_threshold:
      - value: 0
        color: moccasin
      - value: 500
        color: khaki
      - value: 1000
        color: yellow
      - value: 1500
        color: gold
      - value: 2000
        color: orange
      - value: 2500
        color: darkorange
      - value: 3000
        color: tomato
      - value: 3500
        color: sandybrown
      - value: 4000
        color: peru
      - value: 4500
        color: orangered
      - value: 5000
        color: maroon
      - value: 5500
        color: purple
      - value: 6000
        color: darkred
    type: column
    show:
      extremas: true
#       legend_value: true
#         opacity: 1
#         float_precision: 0
#     stroke_width: 8

  - entity: sensor.zp_actuele_opbrengst
    yaxis_id: actueel
#         transform: return x /1000;
#         unit: kW
    type: line
    name: Actueel
#     stroke_width: 1
    extend_to: false
    color: grey

shows as:

still dont get the legend to be 0 on Solar power though. does this not find the value in the data object maybe?
btw, can we set the left Y-axis scale to use the same numbers as I set in the color_thresholds, this is a bit random somehow…

If you are interested:

Did not work, because the variable “Watts” was never defined.

This is a little more complicated. The map function is essentially shorthand for the “for” function. So here you try to do a double “for”.

Good luck with your next coding adventure.

yeah, the second of your post above I get :wink:
and I had already seen and changed that into:

    data_generator: |
      let res = []; for (const [key,value] of
        Object.entries(entity.attributes.watts)) {
        res.push([new Date(key).getTime(),value]);
        } return res;

however, on your first remark on the variable not being defined in

        data_generator: |
          return Object.entries(entity.attributes.watts).map((entry) => {
          const myArray = Watts.split(" ");
            return [new Date(myArray[0]).getTime(), myArray[1]];
          });

how could I fix that (so define Watts)? simply by adding

let Watts = [];

?

cant test right now, because forecast solar is out for the moment

Hi Marius,

The line const myArray = Watts.split(" ");. means, take the string (it only works on strings) from Watts and split in into a list on every space.

You are correct let Watts would define the variable, and let Watts = [] would fill that variable with an empty list. But there isn’t any actual data there, only an empty list. So you would need a function to fill the variable Watts with a string of data.

The function list.map(x)=>{}, it is the same as a for loop: for x in list. Within the {} you can use the value x.

We know the value x will consist of two fields: a time and a value. Thats what the const [key, value] means. It says to not return the values as one variable x, but as two separate variables a key and a value.

Is there anything you would still like to accomplice?

I’ve got a ApexChart working fine for most devices:

type: custom:apexcharts-card
graph_span: 24h
span:
  start: day
now:
  show: true
  label: Nu
header:
  show: true
  title: Stroomprijs vandaag (€/kWh)
series:
  - entity: sensor.nextenergy_average_electricity_price_today
    stroke_width: 2
    float_precision: 3
    type: column
    opacity: 1
    color: ''
    data_generator: |
      return entity.attributes.prices.map((record, index) => {
        return [record.time, record.price];
      });
yaxis:
  - id: Prijs
    decimals: 2
    min: 0

For some reason this one stays completely empty on my wallmount iPad Air 2 (ios maxed at 15.7.3). Other ApexCharts do show. Is this known or is there something wrong in my code?

For reference, the chart does show on iphone devices with ios 16 and Windows / MacOS devices.

well first of all, thanks.

I guess I would like to use the simplest, of, rephrase, most economical of generators. If any difference at all.

since I can only get the

    data_generator: |
      let res = []; for (const [key,value] of
        Object.entries(entity.attributes.watts)) {
        res.push([new Date(key).getTime(),value]);
        } return res;

to do what is required, I seem to have no choice, but, you might yet see a better way of converting those KVP and feeding them to the apex-chart.
If that were the case, Id be very interested.

one other detail:
my data refreshes each hour, but the secondary (now) entity is a life updating entity. Updating the apex-chart per hour as I do, might require some further customizing of the handling of that entity in the chart?

always check the repo for issues: Graph not displayed on iPad/ iPhone companion app or Safari IOS · Issue #434 · RomRider/apexcharts-card · GitHub
seems identical?

Sure looks like the same issue. I’ll add my experiences to this issue. thanks.

The issue has been marked closed because of inactivity. So I won’t get my hopes up.

I know I can use tickAmount to set a fixed amount of ticks, but depending on the series values I often end up like below. What I would like to have is in the exmaple below even “5 ticks”, so for the right series “0, 5, 10, 15…”. Is that possible somehow? I can change tickAmount and get it to look good, but when sensors increase/decrease this all changes again. Not sure what to search for:)

type: custom:apexcharts-card
header:
  title: ''
  show: false
  show_states: true
graph_span: 7day
update_interval: 1min
apex_config:
  title:
    text: Luftfuktighet & utetemp
    align: left
    margin: 0
    offsetX: 0
    offsetY: 10
    floating: false
    style:
      fontSize: 15px
      fontWeight: 200
      fontFamily: Segoe UI Light
      color: '#FFFFFF'
  tooltip:
    enabled: true
    x:
      format: HH:MM
  xaxis:
    tooltip:
      enabled: false
    axisBorder:
      show: false
    labels:
      style:
        colors: white
        fontSize: 9px
        fontFamily: Arial
  chart:
    height: 225
  grid:
    show: true
    borderColor: rgba(220, 220, 220, 0.1)
    strokeDashArray: 4
    position: back
  legend:
    show: false
  plotOptions:
    bar:
      borderRadius: 1
yaxis:
  - id: left
    min: 25
    max: ~50
    apex_config:
      tickAmount: 5
      forceNiceScale: true
      decimalsInFloat: 0
      labels:
        style:
          colors: '#ffffff'
          fontSize: 9px
          fontFamily: Arial
  - id: right
    min: ~0
    max: ~15
    opposite: true
    apex_config:
      tickAmount: 6
      forceNiceScale: true
      decimalsInFloat: 0
      labels:
        style:
          colors: '#ffffff'
          fontSize: 9px
          fontFamily: Arial
series:
  - entity: sensor.arbetsrummet_humidity
    name: Arbetsrummet
    yaxis_id: left
    type: line
    stroke_width: 1.5
    color: 2eb9ff
    group_by:
      func: avg
      duration: 120min
  - entity: sensor.sovrummet_luftfuktighet
    name: Sovrummet
    yaxis_id: left
    type: line
    stroke_width: 1
    color: rgba(240, 240, 240, 0.7)
    group_by:
      func: avg
      duration: 120min
  - entity: sensor.nibe_105703_40004
    name: Utetemperatur
    yaxis_id: right
    type: column
    stroke_width: 1
    color: 1b6d96
    group_by:
      func: avg
      duration: 120min

1 Like

This probably won’t be fixed other than buying a modern device.

No use adding identical info there.

@Mariusthvdb which integration offers you that sensor (solar forecast estimate watts) ? I have [Forecast.Solar] installed as integration but don’t have that sensor.

Check the opening post, it’s a test sensor I made there

And that would be very reasonable, of course. Now I don’t agree iOS 15.7.2 isn’t modern, but if it lacks certain features to show the charts that’s fine and nothing anyone can help. I hoped to find an explanation of why some charts do work and some don’t so I can change my charts to work. Never the less; thanks for your reply and help.

They sometimes say that 4 eyes are better than 2 !!

So post 2 graphs, one that works and the other one that is not working (not images).

I or someone else might be able to spot the problem :slightly_smiling_face:

Hi, thanks for your reply. I added the charts to Graph not displayed on iPad/ iPhone companion app or Safari IOS · Issue #434 · RomRider/apexcharts-card · GitHub. Could you have a look?

So, first thing I do not like is

color: ''

Inset a valid hex value between the quotes.

Add the

min: 0

to your series.

Then change this line

return [record.time, record.price];

to

return [record.time, record.price.toFixed(2)];

Then remove this code

yaxis:
  - id: Prijs
    decimals: 2
    min: 0

and test.

color changed to #ffa500
added min: 0
altered the retrun code
removed yaxis section

Saved, the values have changed a bit, which is fine. Unfortunately, the iOS device still shows nothing. It’s just completely empty. To clarify, there are no values, so the yaxis and xaxis are there, but no values.

For reference, the current code:

type: custom:apexcharts-card
graph_span: 24h
span:
  start: day
now:
  show: true
  label: Nu
header:
  show: true
  title: Stroomprijs vandaag (€/kWh)
series:
  - entity: sensor.nextenergy_average_electricity_price_today
    stroke_width: 2
    float_precision: 3
    type: column
    opacity: 1
    min: 0
    color: '#ffa500'
    data_generator: |
      return entity.attributes.prices.map((record, index) => {
        return [record.time, record.price.toFixed(2)];
      });