ApexCharts card - A highly customizable graph card

Brilliant idea, kudo’s !

I have a small problem with my electric price graph. To show extremas, it seems like I have to use “group_by” to make it show up. But if I use group_by, the todays graph extends to the right all the way. Even though I have stated “extend_to_end: false”.

image

Is this a bug or can I stop the orange todays graph from filling up behind tomorrows blue price graph?

This is without group_by on the orange graph which is correct, but the two extremas values disappear:

image

Take a look at GitHub - markcocker/influxdb-query-to-entity: HACS Pyscript to query an InfluxDB database and copy key:value pair results into a Home Assistant entity and let me know what you think.

4 Likes

This is brilliant - I’ve been able to get a graph of the last 30 days of temperature/weather at home going in about 20 minutes,

    - type: "custom:apexcharts-card"
      header:
        title: Weather - Last 30 Days
        show: true
        show_states: false
      apex_config:
        chart: { type: "area", height: 300 }
        stroke: { show: true, lineCap: "square", dashArray: [0, 0, 10] }
        dataLabels: { enabled: true }
        legend: { show: false }
        fill:
          {
            type: "gradient",
            gradient:
              {
                shadeIntensity: 1,
                inverseColors: false,
                opacityFrom: 0.45,
                opacityTo: 0.05,
                stops: [20, 100, 100, 100],
              },
          }
        yaxis:
          - seriesName: "High"
            title:
              text: "Temperature (°C)"
          - seriesName: "High"
            show: false
          - seriesName: "Rainfall"
            title:
              text: "Rainfall (mm)"
            min: 0
            opposite: true
      series:
        - entity: sensor.home_outsidetemp_max_30day
          name: High
          type: area
          color: "da1e28"
          extend_to_end: false
          stroke_width: 3
          unit: "°C"
          show:
            extremas: true
          data_generator: |
            let res = [];
            for (const [key, value] of
                Object.entries(entity.attributes)) {
                res.push([new Date(key).getTime(), value]);
            }
            return res.sort((a, b) => { return a[0] - b[0] });
        - entity: sensor.home_outsidetemp_min_30day
          name: Low
          type: area
          color: "#0043ce"
          extend_to_end: false
          stroke_width: 3
          unit: "°C"
          show:
            extremas: true
          data_generator: |
            let res = [];
            for (const [key, value] of
                Object.entries(entity.attributes)) {
                res.push([new Date(key).getTime(), value]);
            }
            return res.sort((a, b) => { return a[0] - b[0] });

        - entity: sensor.home_rain_30day
          name: Rainfall
          type: area
          color: "#1192e8"
          extend_to_end: false
          stroke_width: 2
          unit: "mm"
          show:
            extremas: true
          data_generator: |
            let res = [];
            for (const [key, value] of
                Object.entries(entity.attributes)) {
                res.push([new Date(key).getTime(), value]);
            }
            return res.sort((a, b) => { return a[0] - b[0] });
      graph_span: 30days
      all_series_config:
        type: line
        group_by:
          func: sum
          duration: 1d
3 Likes

Is it possible to have a graph over a two years period displayed as two graphs in a one year period?

Where is the data for the two years? The Home Assistant recorder purge_keep_days default is 10 days.

If you want one graph with two series - one for last year and a separate one for this year, then use graph_span: 1year, add two series for the same sensor, and for the second series specify offset: -1year . For an example see GitHub - RomRider/apexcharts-card: 📈 A Lovelace card to display advanced graphs and charts based on ApexChartsJS for Home Assistant

If you trying to do somthing else, perhaps mock up what you’re trying to achieve?

1 Like

Thanks for you suggestion.
The data come from an external Mysql database.

hello, I have the following code:

type: 'custom:apexcharts-card'
graph_span: 3d
header:
  show: true
  title: Balance Last Three Days
  show_states: true
  colorize_states: true
series:
  - entity: sensor.nh_nicehash_totalbalance_usd
    fill_raw: last
    color: red
  - entity: sensor.nh_nicehash_totalbalance
    fill_raw: last
    color: blue
apex_config:
  yaxis:
    - title:
        text: USD
      opposite: true
      decimalsInFloat: 0
      min: 55
    - title:
        text: BTC
      labels:
        show: true
      decimalsInFloat: 5
      min: 0.001

Is it possible to make min values to be dynamically calculated as min value of the entity being displayed?

I have a chart showing the last 30 days of electricity cost + usage. It would be nice to have an X axis annotation at each Monday, but I can’t see a way to nicely automate that. An alternative would be to have a binary sensor that turns on each Monday, and off for other days of the week, and use that as a chart series on a secondary Y axis. Anybody got something like this working?

To answer my own question, I ended up creating a series in the chart using data_generator…

config
  • entity: sensor.octopus_electricity_agile_cost_30days
    fill_raw: zero
    type: area
    color: grey
    curve: stepline
    name: Start of week
    extend_to_end: true
    opacity: 0.2
    stroke_width: 1
    data_generator: >
    let res = [];
    var startOfWeek = new Date();
    startOfWeek.setHours(0,0,0,0);
    startOfWeek.setDate(startOfWeek.getDate() - (startOfWeek.getDay() + 6) % 7);
    var startOfWeekTime = startOfWeek.getTime();
    var day = 2460601000;
    res.push([startOfWeekTime, 1]);
    res.push([startOfWeekTime- (8
    day), 0]);
    res.push([startOfWeekTime-(14day), 1]);
    res.push([startOfWeekTime-(22
    day), 0]);
    res.push([startOfWeekTime-(28day), 1]);
    res.push([startOfWeekTime-(36
    day), 0]);
    return res.sort((a, b) => {return a[0] - b[0] });

3 Likes

Is it possible to transform both value 50 and 51 to booleans according to transform: 'return x == ''50'' ? 1 : 0;'?

How would one “transform” data_genetatored values?

  - entity: weather.openweathermap
    name: Precipitation
    type: column
    group_by:
      func: avg
      duration: 1h
    show:
      datalabels: false
      in_header: false
    data_generator: |
      return entity.attributes.forecast.map((entry) => {
        return [new Date(entry.datetime).getTime(), entry.precipitation];
      });

I’ve tried adding the transform option but it gets ignored, I feel I need to add it in the data genetor somewhere but not very good with javascript or whatever it is.

Essentially, I’d like the precipitation value for the forecasted data to be multiplied by 4.

Hi everyone,

First of all, thank you for this amazing card!
I am trying to have only two y-axis for four series. Any clue how to do that?

image

type: 'custom:apexcharts-card'
graph_span: 10d
hours_12: false
y_axis_precision: 0
all_series_config:
  stroke_width: 3
  show:
    legend_value: false
header:
  show: true
  title: Conso. quotidienne
  show_states: true
  colorize_states: true
  standard_format: true


apex_config:
  yaxis:
    - show: true
      decimalsInFloat: 0
      forceNiceScale: true
    - show: true
      decimalsInFloat: 0
      forceNiceScale: true

    - show: true
      opposite: true
      decimalsInFloat: 0
      forceNiceScale: true
    - show: true
      opposite: true
      decimalsInFloat: 0
      forceNiceScale: true

series:
  - entity: sensor.gazpar_energy_price
    name: Gaz
    type: column
    group_by:
      func: max
      duration: 1d
  - entity: sensor.myenedis_cost_yesterday_pdl
    name: Électricité
    type: column
    group_by:
      func: max
      duration: 1d
  - entity: sensor.outside_temperature
    name: T° ext. maximale
    show:
      in_header: false
      offset_in_name: false
    offset: '-1d'
    group_by:
      func: max
      duration: 1d
  - entity: sensor.outside_temperature
    name: T° ext. minimale
    show:
      in_header: false
      offset_in_name: false
    offset: '-1d'
    group_by:
      func: min
      duration: 1d

Can extremas be tweaked to only show maximum and not minimum?

You can switch show: true to show: false on the two y-axis entries you don’t want to appear. Although I would recommend setting some max/min values so they align with the visible axis values to avoid confusion.

1 Like

I love it, thank you @Kinetic21
image

2 Likes

When I combine two sensors in one diagram (with two y-axis) the automatic scaling changes it’s behavior in a manner, that only the max value seems to work and the min value is always zero.
Both diagrams show the same sensor in red, left combined with another sensor. Both no max or min.

Is there a way to have the y-axis scaling automic for max and min?

type: 'custom:apexcharts-card'
graph_span: 24h
header:
  show: true
  title: Außen
  show_states: true
  colorize_states: true
series:
  - entity: sensor.xiaomiaqara_1_temperature
    name: Temperatur
    color: '#ff444f'
  - entity: sensor.xiaomiaqara_1_humidity
    name: Feuchte
    color: '#00b4fb'
all_series_config:
  type: area
  curve: smooth
  show:
    extremas: true
  group_by:
    func: avg
    duration: 5m
apex_config:
  stroke:
    width: 2
  yaxis:
    - decimalsInFloat: 0
    - decimalsInFloat: 0
      opposite: true
  fill:
    type:
      - gradient
    gradient:
      type: vertical
      opacityFrom: 0.7
      opacityTo: 0.3
  tooltip:
    x:
      format: 'HH:mm'

Is it possible :

  • to show the numbers of every month
  • completely occupy the x-axis

Why does a duration of 31 days cause a column overflow?

type: 'custom:apexcharts-card'
graph_span: 365d
update_interval: 1hour
cache: true
span:
  end: month
header:
  show: false
apex_config:
  xaxis:
    labels:
      format: MM
      show: true
      showAlways: true
  yaxis:
    forceNiceScale: false
    decimalsInFloat: 0
  chart:
    type: area
    height: 300
  stroke:
    show: true
    width: 1
  legend:
    show: true
  dataLabels:
    enabled: false
    distributed: true
  fill:
    type: gradient
    gradient:
      shadeIntensity: 0.1
      opacityFrom: 0.25
      opacityTo: 1
      inverseColors: true
      stops:
        - 0
        - 90
        - 100
series:
  - color: 'rgb(20,129,238)'
    entity: sensor.conso_eau_mois
    type: column
    name: Eau
    float_precision: 2
    group_by:
      func: max
      duration: 30d

** EDIT** Nevermind, there was a spacing issue… seems to work now. Thanks for the example!!!

Hi Mark thanks for putting this up on github, I looked at it and am working on doing the same thing in nodered since I already have this up and there is an influxdb node. I just wanted to see if I am formatting the sensor the same as you for your data_generator function. Is the below correct?