ApexCarts card

Hello, trying to add some “fix time” areas (to show validity of electricity low tariff) into the apex charts card. I’m using annotations but cannot get that are displayed in the chart. Here is my code:

type: custom:apexcharts-card
header:
  show: true
  show_states: true
  colorize_states: true
graph_span: 2d
span:
  start: day
now:
  show: true
  label: Now
series:
  - entity: sensor.current_spot_electricity_price
    float_precision: 2
    type: column
    show:
      in_header: raw
    data_generator: |
      return Object.entries(entity.attributes).map(([date, value], index) => {
        return [new Date(date).getTime(), value];
      });
apex_config:
  annotations:
    xaxis:
      - x: ${new Date().setHours(20,0,0,0)}
        x1: ${new Date().setHours(22,0,0,0)}
        label:
          text: NT
          borderWidth: 0
          style:
            background: '#0000'

Looks there is some issue with the time format but I cannot find the cause. Can somebody help please?

Thanks

The example annotation on the ApexCharts page looks different to yours. I’d start with that first to see if you can get it working, and modify from there. Their code is below.

annotations: {
  xaxis: [
    {
      x: new Date('23 Nov 2017').getTime(),
      borderColor: '#775DD0',
      label: {
        style: {
          color: '#fff',
        },
        text: 'X-axis annotation - 22 Nov'
      }
    }
  ]
}

This look a long time to research, but yes I finally managed to get it to work.

apex_config:
  annotations:
    xaxis:
      - x: EVAL:new Date().setHours(16,0,0)
        x2: EVAL:new Date().setHours(19,0,0)
        label:
          text: Peak
          borderWidth: 0
          style:
            background: '#0000'
  • the second field is ‘x2’
  • this needs the EVAL: operator (use at your own risk) to generate the unix timestamps
  • you can’t use annotations with ‘now’ option

Hello, thanks for your reply. However when I tried in my HA instance, still no success. I was playing a bit with the card setup but xaxis annotation still doesn’t display. Also tried to add yaxis annotation which works, but xaxis even I used “EVAL:” still doesn’t. Here is the latest code snippet I used:

apex_config:
  annotations:
    xaxis:
      - x: EVAL:new Date().setHours(16,0,0)
        label:
          text: Peak
          borderColor: '#0048ba'
          borderWidth: 0
          style:
            background: '#0000'
    yaxis:
      - 'y': 3
        strokeDashArray: 0
        borderColor: '#0048ba'
        borderWith: 6
        label:
          text: test

Any ideas what else can I try?

Thanks

Apex graphs are excellent, however the configuration has to be 100% correct or nothing displays, which makes debugging challenging.

You have the Y axis annotation working, that shows we are on the right track.

I assume that you do not have the now option in your config. That puts now on the x axis timeline and stops other annotation from working.

The obvious point is that the value given for the x must lie within the graph time period, as this is where the annotation is plotted. Your data generator suggests you are using

new Date(date).getTime()

to create what is a Unix Millisecond time based on UTC. Hence your x axis will be in Unix milliseconds (something like 1699958049853).

If you replace the EVAL bit with a valid Unix time (literal), then you can check that this displays correctly (hence the config is right, it is just the EVAL that is not).

You can use https://www.unixtimestamp.com/ to generate now, or a time that is in the middle of your current graph time period. This is what I did to check the config before I worked on the EVAL bit.

If that works, then it is just the EVAL.
I am in the UK, so for us our local time is GMT which is the same as UTC, so I don’t have to worry about timezones, but I also cannot check my code for timezones. If you live outside the UK, and your date in your data generator is a string with a TZ code, then this will shift local time to UTC, and this shift may have to be accounted for when getting the correct UTC equivalent of 16:00 local time.

The EVAL operator relies on the latest version of Apex Charts, so make sure this is up to date.
https://github.com/RomRider/apexcharts-card/releases

After that, yes before I worked out how to use the EVAL operator, I loaded and used the config-template card. This card allows for running JavaScript to create variables that can be later templated into a sub-card config, so as to modify that card’s config before the card is called. Neat stuff. That all worked nicely, it just seemed that the EVAL was an easier approach.

You can find the config-template card at https://github.com/iantrich/config-template-card

I successfully set up a graph using that approach. Here is my config for reference. The bit up to card is the config-template doing its stuff creating variables, then these variables are referenced in the apexcharts-card config using “${name}”.

It all works perfectly for me, but again the JS new Date().setHours(16,0,0) returns Unix Milliseconds based on local time, which for me is UTC and matches the UTC time used by my energy company here in the UK.

type: custom:config-template-card
variables:
  pstime: new Date().setHours(16,0,0)
  petime: new Date().setHours(19,0,0)
  ostime: new Date().setHours(2,0,0)
  oetime: new Date().setHours(5,0,0)
entities:
  - sensor.octopus_agile_prices
card:
  type: custom:apexcharts-card
  header:
    show: true
    title: Octopus Agile Prices - experimental card
  show:
    last_updated: true
  now:
    show: false
    label: now
  graph_span: 24h
  span:
    start: day
    offset: '-1h'
  series:
    - entity: sensor.octopus_agile_prices
      data_generator: |
        let prices = entity.attributes.array;
        let ends = prices.length-1;
        let final = prices.map((item, index) => {
          return [item.from, item.import];
        });
        final.push([prices[ends].upto, prices[ends].import]);
        return final;
      curve: smooth
      name: Import
      show:
        legend_value: false
      stroke_width: 2
      color: orange
    - entity: sensor.octopus_agile_prices
      data_generator: |
        let prices = entity.attributes.array;
        let ends = prices.length-1;
        let final = prices.map((item, index) => {
          return [item.from, item.export];
        });
        final.push([prices[ends].upto, prices[ends].export]);
        return final;
      curve: stepline
      name: Export
      show:
        legend_value: false
      stroke_width: 2
      color: green
  apex_config:
    annotations:
      xaxis:
        - x: ${pstime}
          x2: ${petime}
          label:
            text: Peak
            borderWidth: 0
            style:
              background: '#0000'
        - x: ${ostime}
          x2: ${oetime}
          label:
            text: Cheap
            borderWidth: 0
            style:
              background: '#0000'

Picture to show it working - impressive stuff!

apex charts card with x axis annotation

Hello, apologize for late reply and thanks for exhaustive explanation. Switching off the “now” option did the trick for me. I can see the desired x-axis annotations now. I’m based in the Czech Rep. and timezone works properly as well.

Hi,

I have a quick question: How can I use a y-value that comes from a sensor instead of manually defining a fixed value as in the examples above?

For example a price threshold that adapts depending on the current price?

Thanks!