ApexCharts card - A highly customizable graph card

I have no idea, where i can find something about the Loading… in my logs.

maybe in the influxdb-integration logs, Settings/Add-ons/influxdb, … or ha-logs, in some case one have to enable “loglevel- Debug” ( in configuration.yaml) default log-level in HA is “info”, so if something is “wrong” you can change loglevel

1 Like

Is it a known bug that the fontFamily and fontSize doesn’t work for the title?

When increasing the font size, the only thing that happens is that the text is moved down the more I increase the font size.

apex_config:
  title:
    text: Kompressor (Hz)
    style:
      fontSize: 150px;
      fontWeight: light
      fontFamily: Segoe Ui Light;

Here’s my 10 cents !! :stuck_out_tongue_winking_eye:

My code (ignore the javascript notations).

      title: {
        text: 'neerslag komende twee uur',
        align: 'center',
        margin: 0,
        offsetX: 0,
        offsetY: 5,
        floating: false,
        style: {
          fontSize:  '150px', //'20px',
          fontWeight:  'normal',
          fontFamily: 'Segoe Ui Light', //'Helvetica, Arial, sans-serif',
          color:  '#FFFFFF'
        },
      },       

Try adding the following for fixed location.

        margin: 0
        offsetX: 0
        offsetY: 0
2 Likes

Hi,

When implementing your code (on the Open-Meteo integration) I am getting my rain forecast shifted 1 day ahead of the rest of the graph: today, 22/03, it’s the 23/03 forecast that is displayed at the “now” level.
image

I believe it’s a detail to fix, but I don’t know how. Can you help?
Thanks

Edit: Temperature forecast come from Openweather hourly

Beautiful, worked like a charm :blush: Thank you!

Hi,

Is it possible to get 1 series with the sum of 2 entities/sensors?
I try to find the consumed solar energy by getting the difference between solar-produced energy (+ve) and exported energy (-ve).

Thanks!

It should be with data_generator but I always find it simpler to create a template sensor doing the match and then presenting the result.

Two questions about labels and their UI:

  1. Can we somehow format the extremas labels to look simolar to data labels?

  2. Is there any way of only showing a data label for a line series for the latest value? So basically the “now” function but with the actual data in the label for the most recent data point?

This is how a data label can be formatted vs. how extremas look:

Short answer to both questions. No.
Long answer to both questions. Nooooooooooooooo.

Reason 1:- extrema labels are an HA feature and have no format method.

Reason 2:- data labels for any series do have a formatter option, but any configuration applies to all dataPointIndex’s, not just the last one which you are seeking.

But (there’s always a but), you could use the “now” function in combination with the custom:config-template-card.

  now:
    show: true
    label: >-
      ${'Current Temp.' + states['sensor.meter_plus_6469_temperature'].state + '
      °C'}
2 Likes

Thank you Kertz!
That config-tempalte-card is getting closer and closer… I haven’t looked into it yet as I’m afraid it’s gonna be complicated and take away even more time to HA :slight_smile:

Didn’t do anything special.
It’s shown automatically for me with graph_span: 2d

Thanks for this, worked a treat, been looking for a way to do this for ages, also used it to changed the Now colour based on a state.

now:
      show: true
      label: >-
        ${states['climate.immersion_heater_thermostat'].attributes.current_temperature + '°'}
      color: >-
        ${states['binary_sensor.immersion_heater_heating'].state === 'on' ? 'red' : 'cyan'}
1 Like

trying to figure out the data_generator, but need some help, please…

if this is my sensor and attributes list:

how would I need to change this config, so it actually renders anything…?

  - type: custom:apexcharts-card
    graph_span: 48h
    update_interval: 1h
    header:
      show: true
      title: Solar Forecast
    span:
      start: day
    now:
      show: true
      label: Now
    yaxis:
      - id: power
        decimals: 0
    apex_config:
      plotOptions:
        bar:
          columnWidth: 100%
      stroke:
        width: 2
    series:
      - entity: sensor.solar_forecast_estimate_watts
        name: Solar power
        yaxis_id: power
        data_generator: |
          return entity.attributes.watts.map((entry) => {
            return [new Date(entry).getTime(), entry];
          });

        type: column
        show:
          extremas: true
        opacity: 1
        float_precision: 3

I’ve copied the above form some other sensor attributes for price, but they contain an actual named KVP like

and use:

    series:
      - entity: sensor.energyzero_today_energy_average_price
        name: Price this hour
        yaxis_id: price
        data_generator: |
          return entity.attributes.today.map((entry) => {
            return [new Date(entry.timestamp).getTime(), entry.price];
          });

that wont work now obviously,

but I fail to see how I should change to fix it.

please have a look? thanks!

How does this look like, if you paste the sensor in Dev-tools/state ?

Assuming that is white space before the value, you could try this.

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

thanks for your reply, unfortunately that throws an error:

Error: TypeError: entity.attributes.watts.map is not a function in 'return entity.attributes.watts.map((entry) => {
const myArray = Watts.split(" ");
  return [new Da...'

is there a way to test these data generators? given the fact its JS I cant get my head around any online tool with this, we need the frontend info?

to be precise, the output of:

{{state_attr('sensor.solar_forecast_estimate_watts','watts')}}

is:

{'2023-03-24T06:34:00+01:00': 0, '2023-03-24T07:00:00+01:00': 145, '2023-03-24T08:00:00+01:00': 222, '2023-03-24T09:00:00+01:00': 329, '2023-03-24T10:00:00+01:00': 414, '2023-03-24T11:00:00+01:00': 473, '2023-03-24T12:00:00+01:00': 515, '2023-03-24T13:00:00+01:00': 577, '2023-03-24T14:00:00+01:00': 1175, '2023-03-24T15:00:00+01:00': 1395, '2023-03-24T16:00:00+01:00': 1054, '2023-03-24T17:00:00+01:00': 627, '2023-03-24T18:00:00+01:00': 258, '2023-03-24T19:00:00+01:00': 70, '2023-03-24T19:02:00+01:00': 0, '2023-03-25T06:31:00+01:00': 0, '2023-03-25T07:00:00+01:00': 187, '2023-03-25T08:00:00+01:00': 329, '2023-03-25T09:00:00+01:00': 413, '2023-03-25T10:00:00+01:00': 480, '2023-03-25T11:00:00+01:00': 594, '2023-03-25T12:00:00+01:00': 689, '2023-03-25T13:00:00+01:00': 1207, '2023-03-25T14:00:00+01:00': 2140, '2023-03-25T15:00:00+01:00': 2188, '2023-03-25T16:00:00+01:00': 1808, '2023-03-25T17:00:00+01:00': 969, '2023-03-25T18:00:00+01:00': 360, '2023-03-25T19:00:00+01:00': 108, '2023-03-25T19:04:00+01:00': 0}

maybe I need the .items() here too, like in the jinja templates for template-entity-row I use:

      {% if states[config.entity] is not none %}
        {% set attr =
            state_attr(config.entity,'watts').items()
            |sort(attribute='1',reverse=True) %}
        {% set peak = (attr|first| default(('Unknown',0))) %}
         {{peak[1]}} W op {{as_datetime(peak[0]).strftime('%-d-%m')}} om {{as_datetime(peak[0]).strftime('%-H')}} uur
      {% else %} Initializing
      {% endif %}

or is that what the .map((entry) does in the data_generator?

maybe its no a float? figured it is, because of no quotes in the KVP

checking the objects doc on W3, doesnt help me a lot…

I have reached a similar solution a while back (lots of searching)

      - entity: sensor.solar_forecast
        show:
          in_header: false
          legend_value: false
        name: today
        yaxis_id: value
        color: '#ffa600'
        opacity: 1
        stroke_width: 1
        float_precision: 1
        unit: kWh
        offset: '-1h'
        data_generator: >
          let res = []; for (const [key, value] of
          Object.entries(entity.attributes.forecast.result)) {
            res.push([new Date(key).getTime(), value/1000]);
          } return res

in my graph (this is a combined card obviously)
image

4 Likes

EDIT:
vingerha already replied, this is the explination why.

The map function only works on ‘lists’, like arrays, you can recognize them by the square brackets [].
“entity.attributes.watts” is a dict, like objects, recognized by the curly brackets.

To convert an dict to a list, you could indeed use the items() function in jinja templates. But the data_gerenator is uses javascript. So then you use the function Object.entries().
Can you test the data_generator like this:

        data_generator: |
          return Object.entries(entity.attributes.watts).map((entry) => {
             ...
2 Likes

thanks! I figured that to be the case, but fail to fix the generator…

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

should I completely do away with the const myArray, and use the .push construction?

because I did test:

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

and still it does not render

wait, there more to change:

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

now shows!

yeas!!. Now time for some formatting :wink: maybe even color_thresholds…
cool, thx @studioIngrid and @vingerha , much appreciated!