ApexCharts card - A highly customizable graph card

In view of the fact that I agree with you about the time interval of 10 seconds, this is no explanation for the error messages and no solution.
Anyway, thanks for the tip, I’ll change it.

Hi there!

  1. Does anybody know how to get rid of that white space in the upper section in order to maximize the graph?

  2. I think I found a bug: The property borderRadiusApplication: “around” has no impact on the bar chart. Only ends gets rounded.

Bildschirmfoto 2023-06-07 um 08.34.56

  - type: custom:apexcharts-card
    card_mod:
      style: |
        ha-card {
          background-color: transparent !important;
          border-radius: 0px;
          padding: 0px !important;
          margin: 0px !important;
          border-width: 1px;
          border-color: var(--green);
        }
    header:
      show: false
      title: Stromverbrauch / 24h
    apex_config:
      plotOptions:
        bar:
          borderRadius: 5
          borderRadiusApplication: "around"
      chart:
        height: 98px
        fontFamily: Quicksand
        parentHeightOffset: 20px
      yaxis:
        forceNiceScale: true
        reversed: false
        opposite: true
      dataLabels:
        background: false
        offsetY: -10
        style:
          colors:
          - 'var(--contrast20)'
    graph_span: 24h
    update_interval: 60sec
    layout: minimal
    span:
      end: hour
    all_series_config:
      type: column
      curve: smooth
      show:
        datalabels: false
    series:
      - entity: sensor.hauszahler
        unit: Wh
        name: Stromverbrauch
        transform: "return x / 2;"
        color: "var(--green)"
        group_by:
          duration: 2h
          func: avg

Could someone help me to create a graph like this ?

My sensors are: sensor.inverter_input_power, sensor.power_meter_consumption, sensor.power_meter_exported and sensor.power_meter_active_power (this one should show negative values eg: transform: return Math.max(0,x)) or transform: return -Math.min(0,x);

How do you make red line (Grid) not to be negative ?

Screenshot 2023-06-07 at 12-34-29 Overview – Home Assistant

Here is my code

type: custom:apexcharts-card
experimental:
  color_threshold: true
header:
  show: true
  show_states: true
  colorize_states: true
  title: Power Flows
graph_span: 1d
span:
  start: day
apex_config:
  chart:
    type: area
  stroke:
    show: true
  dataLabels:
    enabled: true
  legend:
    show: true
  fill:
    type: gradient
    gradient:
      inverseColors: true
      type: vertical
      shadeIntensity: 0.7
      opacityFrom: 0.7
      opacityTo: 0.3
  grid:
    show: false
all_series_config:
  stroke_width: 1
  group_by:
    func: last
    duration: 30m
  curve: smooth
  type: area
series:
  - entity: sensor.inverter_active_power
    color: green
    extend_to: false
    name: PV Input
    transform: return x / 1000;
    unit: kW
    float_precision: 2
  - entity: sensor.power_meter_active_power
    name: Grid
    color: red
    extend_to: false
    transform: return x / 1000;
    unit: kW
    float_precision: 2
  - entity: sensor.apf_real_house_load
    color: blue
    extend_to: false
    name: House Load
    transform: return x / 1000;
    unit: kW
    float_precision: 2

I want to use a input_select as value for a annotation line. How?

apex_config:
  annotations:
    yaxis:
      - 'y': {{states['input_select.limit']}}
        borderColor: '#cf6679'
        label:
          text: Limit
          borderColor: '#cf6679'
          style:
            color: '#fff'
            background: '#cf6679'

have to do a new sensor as this:

value_template: "{{(states('sensor.power_meter_active_power') | float * -1 ) | round(2)}}"

1 Like

You could wrap it with card-templater, it allows to add templates to almost any attribute (there is another card that allows templating too)
EDIT, example where I use wto input select fields to drive the offset

2 Likes

can we rewrite a data_generator:

        data_generator: |
           return entity.attributes.prices.map((record, index) => {
            return [record.time, record.price];
           });

to use individual entities for the hourly prices?
Ive deleted that CC providing those attributes (not allowed in core HA…) but do have a rest sensor providing 24 entities :wink:

I have this in a custom:mini-graph-card config now, but would prefer it to be an apexcharts.

this is the idea currently:

      - entity: sensor.energieprijs_uur_0
        name: 00:00-01:00
      - entity: sensor.energieprijs_uur_1
        name: 01:00-02:00
      - entity: sensor.energieprijs_uur_2
        name: 02:00-03:00
      - entity: sensor.energieprijs_uur_3
        name: 03:00-04:00
      - entity: sensor.energieprijs_uur_4
        name: 04:00-05:00
      - entity: sensor.energieprijs_uur_5
        name: 05:00-06:00
      - etc!

would appreciate some nudges into the right direction , thx!

Hi, can anyone help me troubleshoot two issues please?

  1. No matter what I do, I can’t seem to disable the automatic scaling of the Y axis. I would like to be able to set min and max manually so it doesn’t constantly adjust with my MQTT sensors. However, when I do this it shows me the correct Y axis for a second whilst pulling data from my sensor, but then defaults to the max value of the sensor and continues to automatically adjust the scale. I have tried forceNiceScale with no luck.

  2. I also can’t seem to set a label on my Y axis. No matter what options I out in, nothing ever shows.

I can’t help thinking that the two issues are related, and would be very grateful if someone could point out whatever obvious point I’m missing!

Thanks in advance

title: Water
views:
  - panel: true
    cards:
      - type: custom:apexcharts-card
        graph_span: 48h
        show:
          last_updated: true
        apex_config:
          chart:
            height: 300px
            width: 100%
          yaxis:
            labels:
              show: true
        yaxis:
          - id: W
            decimals: 0
            apex_config:
              min: 0
              max: 80
              labels:
                show: true
        series:
          - entity: sensor.tank_water_temperature
            type: line
            group_by:
              func: last
              duration: 5m
            stroke_width: 2
            yaxis_id: W

try this

        yaxis:
          - id: W
            decimals: 0
            min: 0
            max: 80

D’oh! Thanks very much…

This awesome card is sometimes too awesome :slight_smile: to find your way aound

very simple, just add “-” to your return x

  - entity: sensor.power_meter_active_power
    name: Grid
    color: red
    extend_to: false
    transform: return x / -1000;
    unit: kW
    float_precision: 2
1 Like

where do I put this ?

within the series as it is a series/sensor specific choice

How do I get rid of the (-1d) and the “legend” with the date and the line also want to have gone …

Hi, your post was 2 years ago, and unfortunately I can’t help you with your question either.
But could you share the yaml for your solar forcast card? Especially the readout of the SOLCast pv_estimate10 and pv_estimate90 (both Future Forecast) with the correct timestamp would interest me. (the setting of the data_generator). Thanks a lot!

image

To generate a forecast card using Apexcharts and SolCast showing the past forecast values (forecast pv_estimate in kWh) and the future lower and upper bound probabilistic forecast data P10, P90 (detailedForecast pv_estimate10 and pv_estimate90 in kWh) and the generated PV power (solarman_total_ac_output_power_active in W):

type: custom:apexcharts-card
apex_config:
  chart:
    height: 350px
all_series_config:
  unit: kWh
  float_precision: 3
  opacity: 0.3
  stroke_width: 3
header:
  title: Daily forecast
  show: true
  standard_format: true
  show_states: true
  colorize_states: true
graph_span: 1d
span:
  start: day
  offset: '-0d'
now:
  show: true
  label: Now
yaxis:
  - id: kWh
    min: 0
    max: 0.6
    apex_config:
      tickAmount: 5
  - id: header_only
    show: false
series:
  - entity: sensor.solarman_total_ac_output_power_active
    yaxis_id: kWh
    type: area
    name: PV
    color: orange
    opacity: 0.4
    show:
      legend_value: false
      in_header: false
    stroke_width: 1
    transform: return x/1000
    group_by:
      func: avg
      duration: 1min
    extend_to: false
  - entity: sensor.solcast_forecast_today
    yaxis_id: kWh
    type: line
    name: forecast
    color: black
    opacity: 1
    stroke_width: 2
    data_generator: |
      var now = new Date().getTime();
      var today = entity.attributes.forecast
        .filter(start => new Date(start["period_start"]).getTime() < (now + 1000*60*30))
        .map((start, index) => {
        return [
          new Date(start["period_start"]).getTime(), start["pv_estimate"] || 0
        ];
      });
      var data = today
      return data;
    show:
      legend_value: false
      in_header: false
    extend_to: false
  - entity: sensor.solcast_forecast_today
    yaxis_id: kWh
    type: line
    name: detailedForecast
    color: grey
    opacity: 1
    stroke_width: 2
    data_generator: |
      var now = new Date().getTime();
      var today = entity.attributes.detailedForecast
        .filter(start => new Date(start["period_start"]).getTime() > (now - 1000*60*30))
        .map((start, index) => {
        return [
          new Date(start["period_start"]).getTime(), start["pv_estimate"] || 0
        ];
      });
      var data = today
      return data;
    show:
      legend_value: false
      in_header: false
    extend_to: false
  - entity: sensor.solcast_forecast_today
    yaxis_id: kWh
    type: line
    name: 10%
    color: grey
    opacity: 0.6
    stroke_width: 1
    data_generator: |
      var now = new Date().getTime();
      var today = entity.attributes.detailedForecast
        .filter(start => new Date(start["period_start"]).getTime() > (now - 1000*60*30))
        .map((start, index) => {
        return [
          new Date(start["period_start"]).getTime(), start["pv_estimate10"] || 0
        ];
      });
      var data = today
      return data;
    show:
      legend_value: false
      in_header: false
    extend_to: false
  - entity: sensor.solcast_forecast_today
    yaxis_id: kWh
    type: line
    name: 90%
    color: grey
    opacity: 0.6
    stroke_width: 1
    data_generator: |
      var now = new Date().getTime();
      var today = entity.attributes.detailedForecast
        .filter(start => new Date(start["period_start"]).getTime() > (now - 1000*60*30))
        .map((start, index) => {
        return [
          new Date(start["period_start"]).getTime(), start["pv_estimate90"] || 0
        ];
      });
      var data = today
      return data;
    show:
      legend_value: false
      in_header: false
    extend_to: false
4 Likes

How do you reference attributes? The docs say that you can read an attribute instead of state, but it doesn’t do anything, state is the same as the last value of the data_generator which reads an array called rates. The “current” value is also held in an attribute called rate.
In a console.log in the data_generator I can reference entity.attributes.rate.value_inc_vat, but how do I use this in the attribute?

attribute string v1.4.0 Instead of retrieving the state, it will retrieve an attribute of the entity. Make sure you increase update_delay if the chart doesn’t reflect the last value of the attribute

I have added an extra entity and hidden the incomplete graph (ends at now) and used the state from that as the header, meanwhile taken the data_generator for the same, hidden the header. Now I’m left with legend names and values at the bottom for each duplicate series How can I remove the legend at the bottom, I blanked them out but the dots remain?

graph_span: 29h
span:
  start: day
  offset: +0h

I had the span set to 24h with an 12h offset, but this needs to be more dynamic as the next day’s forecast doesn’t appear until 4pm and after midnight, the start: day really screwed things up. how can I restrict the range to consistently show previous 2 hours and as much future data at is available, sizing the graph to the available data rather than getting the flatline at the end?