ApexCharts card - A highly customizable graph card

Thanks,

but an awfull lot is from you answering my question or other peoples questions
And for that power stuff you need an awfull lot to get it fixed especially for elderly people that need a 50+ inch Screen to read Home Assistant

What I did not find is how to increase the font size on the vertical axis.

Where can I start looking ?

I have used this for xaxis, but doing the same for yaxis did not work at all to my surprise.

apex_config:
  legend:
    show: true
    showForZeroSeries: true

  yaxis:
    labels:
      style:
        colors: black
        fontSize: 16px
        fontWeight: normal

  xaxis:
    labels:
      style:
        colors: black
        fontSize: 16px
        fontWeight: normal

Currently working on replacing some of my mini-graph-cards with ApexCharts and have a couple of questions regarding what’s possible. Apologies if this has been discussed before.

  1. Is it possible to fill the area between to lines?
    For example, I have a min and max temperature on my thermostat and would like to highlight just the space between, vs the space from the line to the bottom of the graph (‘area’ type).

  2. Is it possible to toggle what entities are displayed based on their value?
    Example: When the thermostat is set to heat or cool, the setpoint is a single value. When it’s toggled to heat/cool mode, that value becomes ‘NaN’ and Min and Max become readable. I’d like to use one chart to display both variants based on their value (hidden when NaN, shown when not) or based on the current climate state. Currently, I am using two separate charts with a conditional card to toggle between them, but this leads to ‘broken’ data on them when the mode is changed.

  3. Any reasons why ‘stroke_width: 0’ would still display a line?
    I’m using a few binary_sensors with ‘transform’ to show heating and cooling state, and would just like the area fill when on, without the line(s) living at the bottom of the graph when off.
    image

Card YAML
type: custom:apexcharts-card
apex_config:
  stroke:
    width: 2
  chart:
    zoom:
      type: x
      enabled: true
    toolbar:
      show: true
    height: auto
experimental:
  color_threshold: true
header:
  show: true
  title: Inside Temp
  show_states: true
  colorize_states: true
all_series_config:
  group_by:
    func: last
graph_span: 1d
span:
  end: day
yaxis:
  - id: first
    opposite: false
    min: "|-2|"
    max: "|+2|"
    decimals: 0
  - id: second
    show: false
    decimals: 0
    opposite: true
    min: 0
    max: 1
series:
  - entity: sensor.living_room_thermostat_temperature
    yaxis_id: first
    name: Current
    color: orange
    curve: smooth
  - entity: climate.living_room_thermostat
    attribute: target_temp_high
    name: Target high
    unit: °F
    color: red
    curve: stepline
    yaxis_id: first
  - entity: climate.living_room_thermostat
    attribute: target_temp_low
    name: Target Low
    unit: °F
    color: blue
    curve: stepline
    yaxis_id: first
  - entity: binary_sensor.heating_on
    transform: "return x === 'on' ? 1 : 0;"
    name: Heating
    yaxis_id: second
    type: area
    opacity: 0.5
    curve: stepline
    stroke_width: 0
    color: red
    show:
      in_header: false
      legend_value: false
  - entity: binary_sensor.cooling_on
    transform: "return x === 'on' ? 1 : 0;"
    name: Cooling
    yaxis_id: second
    type: area
    opacity: 0.5
    curve: stepline
    stroke_width: 0
    color: blue
    show:
      in_header: false
      legend_value: false
  - entity: zone.home
    name: Occupancy
    curve: stepline
    color: grey
    opacity: 0.1
    type: area
    transform: "return x > 0 ? 1 : 0;"
    stroke_width: 0
    show:
      in_header: false
      legend_value: false
    yaxis_id: second

1.)

    grid:
      yaxis:
        lines:
          show: false
      row:
        colors:
          - lightgrey
          - transparent
        opacity: 0.05

I agree not too obvious but since you can have multiple y-axis it is under that config section and not on the ‘main’

1 Like

Only option I know is to use config card templater, with that you can use templates to show/hide things from the graph based on entity values, i.e. you would need to hide the line and the legend and the header I assume

2 Likes

It is ‘area’ related and thus expected as it is the line around the area (I assume)

Maybe you can use my yaml code (Work in progress) take and adjust what you like.
There are some issues in the code - like the outside Temp line color is yellow instead of blue (according to the temperature)

What I still like to accomplish is:

  • forecast data only on the right side of the “Now” Indicator
  • outside temperature forcast
  • make it zoomable
  • make it responsive so its also showing nicely on the smartphone
  • use the declutter card to have reusable and easy to edit a template of the apex chart card for all the dashboards
type: custom:config-template-card
variables:
  mytime: new Date().getTime()
entities:
  - sensor.time
card:
  type: custom:apexcharts-card
  header:
    show: true
    show_states: true
    colorize_states: true
    title: Temperatur
  cache: true
  graph_span: 26h
  span:
    offset: "-1h"
    start: day
  apex_config:
    chart:
      redrawOnWindowResize: true
    forceNiceScale: true
    legend:
      show: false
    annotations:
      position: front
      xaxis:
        - x: ${{ mytime }}
          strokeDashArray: 0
          borderColor: "#F91639"
          opacity: 1
          offsetX: 0
          offsetY: 10
          label:
            borderColor: "#2F0611"
            borderWidth: 0
            text: >-
              ${{ "Now " + states['sensor.time'].state + " " +
              states['sensor.pws14_sun_deconz_daylight'].state }}
            position: middle
            orientation: vertical
            offsetY: -100
            textAnchor: middle
            style:
              background: crimson
              color: "#ffffff"
              fontSize: 10px
        - x: ${new Date(states["sensor.pws14_sun_rising"].state).getTime()}
          strokeDashArray: 0
          stroke_width: 4
          stroke_dash: 0
          opacity: 0.25
          borderColor: "#FEFBA1"
          borderWidth: 1
          label:
            text: >-
              ${"☀️" + new
              Date(states["sensor.pws14_sun_rising"].state).toLocaleTimeString([],
              {hour: '2-digit', minute: '2-digit'}) +" Sunrise"}
            position: bottom
            orientation: vertical
            borderWidth: 0
            style:
              color: yellow
              fontSize: 10px
              background: none
              rotate: 90
            offsetY: -100
        - x: ${new Date(states['sensor.pws14_sun_solar_noon'].state).getTime()}
          strokeDashArray: 0
          borderColor: "#FFFA34"
          borderWidth: 0
          label:
            text: >-
              ${ new
              Date(states["sensor.pws14_sun_solar_noon"].state).toLocaleTimeString([],
              {hour: '2-digit', minute: '2-digit'}) +" APEX"}
            position: bottom
            orientation: vertical
            borderWidth: 0
            style:
              color: white
              fontSize: 10px
              background: none
              rotate: 90
            offsetY: -150
        - x: ${new Date(states["sensor.pws14_sun_dusk"].state).getTime()}
          strokeDashArray: 0
          borderColor: "#CD6462"
          borderWidth: 1
          label:
            text: >-
              ${"🌙" + new
              Date(states["sensor.pws14_sun_dusk"].state).toLocaleTimeString([],
              {hour: '2-digit', minute: '2-digit'})  +" Sunset"}
            position: bottom
            orientation: vertical
            borderWidth: 0
            style:
              color: orange
              fontSize: 10px
              background: none
              rotate: 90
            offsetY: -100
        - x: ${new Date(states['sensor.sun_next_noon'].state).getTime()}
          strokeDashArray: 0
          borderColor: "#FFFA34"
          borderWidth: 0
          label:
            text: >-
              ${{ "☀️ " + Math.floor(states['sensor.pws14_sun_daylight'].state)
              +  "h " +  Math.round((states['sensor.pws14_sun_daylight'].state %
              1) * 60) +  "min " + "daylight" }}
            position: bottom
            orientation: horizontal
            borderWidth: 0
            style:
              color: white
              fontSize: 10px
              background: none
              rotate: 90
            offsetY: -125
    xaxis:
      labels:
        datetimeFormatter:
          hour: HH:mm
          tickAmount: 30
        show: true
        rotate: -45
        rotateAlways: true
        hideOverlappingLabels: false
        style:
          fontSize: 10px
    yaxis:
      - id: first
        title:
          text: Temperature in °C
        tickAmount: 5
        axisTicks:
          show: true
    grid:
      yaxis:
        lines:
          show: false
      row:
        colors:
          - lightgrey
          - transparent
        opacity: 0.05
    dataLabels:
      enabled: false
      zoom:
        enabled: true
      toolbar:
        show: true
        tools:
          download: true
          zoom: true
          zoomin: false
          zoomout: false
          pan: false
          reset: true
    tooltip:
      enabled: true
      theme: light
      style:
        fontsize: 6px
      onDatasetHover:
        highlightDataSeries: true
      x:
        show: true
        format: ddd dd MMM yyyy HH:mm
      marker:
        show: true
      fixed:
        enabled: true
        position: topRight
        offsetX: -10
        offsetY: 0
    fill:
      type: fill
      gradient:
        shadeIntensity: 0.1
        opacityFrom: 0.25
        opacityTo: 0.5
        inverseColors: true
        stops:
          - 0
          - 1
          - 3
  yaxis:
    - id: first
      min: ~0
      max: ~30
      decimals: 0
    - id: second
      show: false
      min: ~0
      max: ~60
      decimals: 0
      opposite: true
    - id: third
      show: false
      min: ~0
      max: ~10
      decimals: 0
      opposite: true
  experimental:
    disable_config_validation: true
    color_threshold: true
  all_series_config:
    stroke_width: 4
    group_by:
      duration: 15min
      func: avg
    show:
      show:
        extremas: max+time
        in_header: true
        in_chart: false
        datalabels: false
      header_color_threshold: true
      name_in_header: false
      datalabels: false
      legend_value: true
      extremas: true
  series:
    - entity: sensor.aktuelle_temperatur_arbeitszimmer_mittelwert
      yaxis_id: first
      name: Inside
      extend_to: now
      color_threshold:
        - value: -10
          color: blue
          opacity: 1
        - value: 0
          color: "#99CCFF"
        - value: 10
          color: "#5CADFF"
        - value: 15
          color: "#1F8FFF"
        - value: 20
          color: "#f39c12"
        - value: 21
          color: "#d35400"
        - value: 22
          color: "#c0392b"
        - value: 25
          color: "#F55A5A"
      show:
        name_in_header: true
        in_header: true
        legend_value: true
        extremas: true
    - entity: sensor.aktuelle_temperatur_arbeitszimmer_mittelwert
      yaxis_id: first
      name: Gestern
      offset: "-24h"
      extend_to_end: false
      stroke_width: 2
      stroke_dash: 4
      opacity: 0.5
      color: "#CCCCCC"
      show:
        name_in_header: false
        in_header: false
        legend_value: true
        extremas: false
      extend_to: false
      group_by:
        duration: 180min
        func: avg
    - entity: sensor.hk_arbeitszimmer_nachste_geplante_temperatur
      yaxis_id: first
      type: line
      curve: stepline
      filter:
        time_range:
          start: ${{ mytime }}
          end: "20:00:00"
      name: geplante Temperatur
      color: darkgreen
      show:
        name_in_header: false
        in_header: false
        datalabels: false
        legend_value: false
        extremas: false
      stroke_width: 1
      stroke_dash: 4
      opacity: 0.75
      extend_to: end
    - entity: climate.hk_arbeitszimmer
      attribute: temperature
      yaxis_id: first
      name: Target Temp.
      type: line
      color: "#59F564"
      stroke_width: 2
      stroke_dash: 0
      curve: stepline
      show:
        header_color_threshold: true
        extremas: true
        in_header: true
        name_in_header: true
        legend_value: false
      extend_to: now
    - entity: sensor.aussentemperatur_mittlerer_wert
      yaxis_id: first
      type: line
      name: Outside
      color_threshold:
        - value: -10
          color: blue
          opacity: 1
        - value: 0
          color: "#99CCFF"
        - value: 10
          color: "#5CADFF"
        - value: 15
          color: "#1F8FFF"
        - value: 20
          color: "#f39c12"
        - value: 21
          color: "#d35400"
        - value: 22
          color: "#c0392b"
        - value: 25
          color: "#F55A5A"
      show:
        name_in_header: true
        in_header: true
        legend_value: true
        extremas: true
      extend_to: now
    - entity: sensor.temperatur_vorhersage_der_nachsten_stunden
      yaxis_id: first
      type: line
      curve: stepline
      stroke_width: 2
      stroke_dash: 2
      opacity: 0.75
      name: Außen
      color_threshold:
        - value: -10
          color: blue
          opacity: 1
        - value: 0
          color: "#99CCFF"
        - value: 10
          color: "#5CADFF"
        - value: 15
          color: "#1F8FFF"
        - value: 20
          color: "#f39c12"
        - value: 21
          color: "#d35400"
        - value: 22
          color: "#c0392b"
        - value: 25
          color: "#F55A5A"
      show:
        name_in_header: false
        in_header: false
        legend_value: true
        extremas: true
      extend_to: now
    - entity: binary_sensor.fenster_arbeitszimmer_offnung
      transform: "return x === 'on' ? 60 : 0;"
      yaxis_id: second
      type: area
      curve: stepline
      name: Fenster
      color: "#00E396"
      show:
        name_in_header: true
        in_header: false
        datalabels: false
        legend_value: true
        extremas: false
      stroke_width: 0
      opacity: 0.25
      extend_to: false
    - entity: sensor.shellypro_1pm_ac_og_power
      transform: return x/1000
      yaxis_id: third
      color: blue
      type: column
      opacity: 0.25
      unit: kwh
      name: Stromverbrauch Klimaanlage
      extend_to: false
      show:
        name_in_header: false
        in_header: false
        legend_value: false
        extremas: false
    - entity: sensor.gasverbrauch_in_kwh_pro_15min
      name: Gasverbrauch Gestern
      filter:
        time_range:
          start: ${{ mytime }}
          end: "24:00:00"
      offset: "-24h"
      curve: stepline
      stroke_width: 1
      stroke_dash: 4
      opacity: 0.5
      unit: kWh
      group_by:
        duration: 0.5h
        func: avg
      show:
        extremas: false
        datalabels: true
        name_in_header: false
        in_header: false
        legend_value: false
      yaxis_id: third
      color: yellow
      fill:
        opacity: 0.25
      float_precision: 0
      extend_to: false
    - entity: sensor.gasverbrauch_in_kwh_pro_15min
      name: Gasverbrauch
      type: column
      unit: kWh
      group_by:
        duration: 0.5h
        func: avg
      show:
        extremas: false
        datalabels: true
        name_in_header: false
        in_header: false
        legend_value: false
      yaxis_id: third
      color: rgba(228,224,17,128)
      opacity: 0.5
      float_precision: 0
      extend_to: false
    - entity: sensor.pws14_sun_elevation
      yaxis_id: second
      name: Sun elevation
      color: yellow
      transform: |
        return Number(x) < 0 ? 0 : Number(x);
      type: area
      opacity: 0.5
      stroke_width: 0
      show:
        name_in_header: false
        in_header: false
        datalabels: false
        legend_value: false
        extremas: false
        in_chart: true
      extend_to: false
      group_by:
        duration: 5min
        func: max
    - entity: sensor.pws14_sun_elevation
      offset: "-24h"
      yaxis_id: second
      name: Sun elevation yesterday
      color: yellow
      transform: |
        return Number(x) < 0 ? 0 : Number(x);
      type: line
      stroke_width: 1
      stroke_dash: 4
      opacity: 0.5
      show:
        name_in_header: false
        in_header: false
        datalabels: false
        legend_value: false
        extremas: false
        in_chart: true
      extend_to: false
      group_by:
        duration: 5min
        func: max
    - entity: sensor.pws14_sun_elevation
      transform: "return x < 0 ? 60 : 0;"
      yaxis_id: second
      name: Nighttime
      type: area
      curve: stepline
      color: midnightblue
      opacity: 0.5
      stroke_width: 0
      show:
        datalabels: false
        in_header: false
        extremas: false
  card_mod:
    class: middle-right
grid_options:
  columns: full
1 Like

I guess I have asked you this before and remember now reading that you found a solution I will check when i am back home

Where did you get that from cause it is not in the romrider apexchart github documentation

And I guess you had told me back then more or less that there are possibilites sometimes that are in the apexchart.js documentation well epxlained.

If I remember right you had taught me how and where to look for these annotations and how to use now with a sensor or so.

I can remember that cause that was the point when I started to document every single keyword or function I had used cause it was an eye opener that I could at least try how it could work based on that documentation.
I made a dozens of annotations to find out usecases and used just 1 or 2, but spend 2 or 3 days and loved how those worked together.

So now I will check your solution (which I bet i will work, but then check the apex charts.js website, if I can find it somewhere there. I had searched for that there over weeks from time to time and could not find it therefore I wanna know where I can find that in the documentation.

THANKS A LOT

Okay,

sorry for the missunderstanding cause i meant the size of the figures along the yaxis and not a title along tthe yaxis

The red ones are bigger … and I had found the solution for the xaxis fontsize so tried it for the yaxis which did not work at all ?

Any ideas to get the size changed cause I have to deal with elderly that struggle with HA and Apex standard font sizes especially the yaxis

thanks a lot

@typxxi Thx

Servus,

First of all thank you so much for all the Work you are doing . I am very new to HA and visualization and have no JS or Web Programming skills. So this makes it not so easy to get this done what i want to get out .

I am trying to create and chart which shows the Power Distribution of my house . I am already happy with it, but some things do not work. ( this is already some copy to have something to start with … - so not my “work” )

I have 4 enties where 1 is the sum of the 3 others .
I want to show the Summary of the day in the header
I want to show the Summary per Day in the Chart .
I do not want to stack the Summary onto the column .

Problem’s:

  • Tooltip / Mouse over does not show all Enties because of column + line usage
  • The Line entity “somehow” plots data into the Future (+1 day ) and shows data from today.

There is no need to have the line chart if i somehow get the summary calculated as Datalabel on top + shown in the tooltip history .

I tried with offsets on the line series, but this ofc does not work. For me it looks that the line is simply going into the “future” with the today’s current value …

If i mouse over on the line chart i see Data from 21.12 (+1 day)

This is “the” code

type: custom:apexcharts-card
stacked: true
header:
  show: true
  title: " "
  show_states: true
  colorize_states: true
apex_config:
  chart:
    height: 350
    zoom:
      type: x
      enabled: true
      autoScaleYaxis: false
    toolbar:
      show: true
      autoSelected: zoom
    xaxis.type: datetime show
series:
  - entity: sensor.daily_direct_energy_consumption
    name: Solarverbrauch
    type: column
    group_by:
      func: max
      duration: 23.9h
  - entity: sensor.daily_battery_discharge
    name: Batterieverbrauch
    type: column
    group_by:
      func: max
      duration: 23.9h
  - entity: sensor.daily_imported_energy
    name: Netzverbrauch
    type: column
    group_by:
      func: max
      duration: 23.9h
  - entity: sensor.daily_consumed_energy
    name: Hausverbrauch
    type: line
    group_by:
      func: max
      duration: 23.9h
    show:
      datalabels: true
      in_chart: true
graph_span: 8d
span:
  end: day

I am sure there is a lot of not needed code in there ( from my trial and error ) . I have seen some posts where some JS Code was added for the tooltip , i tried to copy this - but it never worked out for me ( because i have no idea how the series data is handled in the sort of “array’s” / states in there . ( … you get it - i have no idea ) .

Any help would be great on this.

Greetings from Vienna,

Best regards, Dietmar

ps. for me an Option would be great for a column : show datalabel true, hide in stack true ( not hide in chart ) . This would solve the tooltip as all entities are column and it would show the summary per day .

Similar with ‘labels’

1 Like

Hi,

There is some more behavior which i do not understand.

If i filter the series in the legend , the mouse over just shows/focus the series on the place they are in the chart . If i click on the Legend to filter out a series of the stacked column i get different results depending which series i use .

For me it looks like:

If the 1st series is filter’d no value is displayed at all.

If the series of the series is a row the get stacked ( entity 1 and 2 )

if the series are not in series the next entities resets to 0 on the axis . ( 1 and 3 )

The reason is that i want to show the “Batterieverbrauch” over time only which is/was not possible.

Thx, Dietmar

The behavior is indeed a bit odd, can you try to see what happens if you put the Batterieverbrauch first entity in the yaml?
EDIT: and I remember some issue with stacked…check the github issue list of apexcharts/romrider

Hi,

Yes i can confirm, changing in yaml does exaclty that. The first entity in the yaml is a must to show (filted) values at all , and the first entity is the only one which could end up in a single (filted) chart.

Thx, Dietmar

Not the expected behavior but a stacked-setup is a real challenge from a card-develop perspective

I think it will be too complicated to just keep the stacked correct if running filter - i would suggest to just overlay all colums and filter them out as wanted would be much easier and more predictable …

awesome - my notes get longer and longer

so it feels that more or less every item is adressable if you know the proper name
I had not thought that label would be that description of the figures of a scale

But what about the header here like the first one 2,8 kWh
I know that it is turned on as header and that I can decide what sensors can appear with that show in header: true or so feature

But how can i change the fontsize and color of the name of the title ?
It is far too tiny for my elderly and also grey ish instead of black
I know it blongs to the sensor, so I had thougt I put it here

  - entity: sensor.growatt_akku_entladerate
    name: "\_H.AKKU ENTLADEN"
     style:
       colors: black
        fontSize: 14px
        fontWeight: normal
    unit: "\_W H.AKKU ENTLADEN"
    yaxis_id: first
    stroke_width: 1

Then I have inserted a “apex_config:”

  - entity: sensor.growatt_akku_entladerate
    name: "\_H.AKKU ENTLADEN"
    apex_config:
      name:  
        style:
          colors: black
          fontSize: 14px
          fontWeight: normal
    unit: "\_W H.AKKU ENTLADEN"
    yaxis_id: first
    stroke_width: 1

but no success

Any ideas or suggestions where to start ?

I never could get this to work properly, I believe it is because the header values are not really apexcharts but HA. I can add a title and have that nicely enlarged but as soon as I try to apply the suggested values-sizing, the title moves below the values, again…I think because title is still apex and headers not.
EDIT: there are other exampes of card_mod with ha-card but for some reason they donot work with me (with others they do)…if you find something, please share :slight_smile:

And I myself was thinking to provide layout-tweaking page to the romrider github to summarize all thse things that are not easy to find.

1 Like

Hi all,
truly amazing card! I just started to dabble with it but hit a wall I can’t seem to get through quite early. Perhaps I’m just missing something really simple.

I have a restful sensor with a list of data that starts on a specific date. The list will update irregularly. I want to show all values starting on the specific date up until today, but can’t find a solution which does exactly this. I found workarounds, but those involve that I update the YAML now and then which is not ideal.

Any suggestions?