ApexCharts card - A highly customizable graph card

I did some more adjustments.
It seems that the unit of measurement cannot be pulled into tooltip.custom.

Changes:

  • Unit of measurement is now hardcoded
  • Data series names and corresponding values are aligned in a table (names with left alignment and values with right alignment)

Now it looks as follows:


Here’s some code-p*rn (as this workaround is slightly pervert):

type: custom:apexcharts-card
graph_span: 1d
span:
  end: day
all_series_config:
  fill_raw: last
  extend_to: false
  show:
    legend_value: false
header:
  show: false
apex_config:
  stroke:
    show: true
    width: 1
    dashArray:
      - 2
      - 0
  dataLabels:
    enabled: true
  chart:
    height: 560px
  legend:
    showForZeroSeries: true
  tooltip:
    enabled: true
    custom: |
      EVAL:function({ series, seriesIndex, dataPointIndex, w }) {
        const hoverXaxis = w.globals.seriesX[seriesIndex][dataPointIndex];
        const seriesX = w.globals.seriesX.map(seriesX => seriesX.findIndex(x => x >= hoverXaxis));

        function formatNumber(value) {
          value = Number(value);
          if (isNaN(value)) return 'n/a';
          const [integerPart, decimalPart] = value.toFixed(1).split('.');
          return integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, '.') + ',' + decimalPart;
        }

        const formattedDate = new Date(hoverXaxis).toLocaleDateString('en-GB', {
          day: '2-digit',
          month: 'short',
          year: 'numeric'
        });
        const formattedTime = new Date(hoverXaxis).toLocaleTimeString('en-GB', {
          hour: '2-digit',
          minute: '2-digit'
        });

        const hoverList = `<table style="width: 100%; border-collapse: collapse; font-family: Helvetica, Arial, sans-serif; font-size: 12px;">
          ${w.globals.seriesNames.map((seriesName, i) => {
            const data = series[i];
            const index = seriesX[i];
            const value = (index >= 0 && index < data.length && w.globals.seriesX[i][index] >= hoverXaxis)
              ? formatNumber(data[index]) + ' W'
              : 'n/a';
            return `<tr>
              <td style="padding: 2px 5px; text-align: left; vertical-align: middle; max-width: 50%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
                <span class="apexcharts-tooltip-marker" style="background-color: ${w.globals.markers.colors[i]}; width: 8px; height: 8px; display: inline-block; border-radius: 50%; margin-right: 5px;"></span>
                ${seriesName}:
              </td>
              <td style="padding: 2px 5px; text-align: right; vertical-align: middle; max-width: 50%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
                <strong>${value}</strong>
              </td>
            </tr>`;
          }).join('')}
        </table>`;

        return `<div class="apexcharts-tooltip-title" style="font-family: Helvetica, Arial, sans-serif; font-size: 12px; padding-bottom: 5px;">
          ${formattedDate}, ${formattedTime}
        </div>${hoverList}`;
      }
series:
  - entity: sensor.solcast_pv_forecast_prognose_heute
    name: PV-Forecast
    data_generator: >
      return entity.attributes.detailedForecast.map(entry => [new
      Date(entry.period_start), entry.pv_estimate * 1000]);
    color: lightgrey
    group_by:
      func: avg
      duration: 1min
  - entity: sensor.inverter_pv_leistung
    type: area
    name: PV-Eingangsleistung
    color: '#37872D'
    opacity: 0.2
    group_by:
      func: avg
      duration: 1min
  - entity: sensor.inverter_eingangsleistung_verlustkorrigiert
    color: '#73BF69'
    name: PV-Eingangsleistung (verlustkorr.)
    group_by:
      func: avg
      duration: 1min
  - entity: sensor.hausverbrauchsleistung
    type: area
    color: '#B877D9'
    opacity: 0.2
    name: Gesamtverbrauch
    group_by:
      func: avg
      duration: 1min
  - entity: sensor.power_meter_netzbezug
    type: area
    color: '#F2495C'
    opacity: 0.2
    name: Netzbezug
    group_by:
      func: avg
      duration: 1min
  - entity: sensor.battery_lade_entladeleistung_verlustkorrigiert
    type: area
    color: '#5794F2'
    opacity: 0.2
    name: Akku Ladung/Entladung
    group_by:
      func: avg
      duration: 1min
  - entity: sensor.power_meter_netzeinspeisung
    type: area
    invert: true
    color: '#FF9830'
    opacity: 0.2
    name: Netzeinspeisung
    group_by:
      func: avg
      duration: 1min
view_layout:
  grid-area: pvchart
card_mod:
  style: |
    ha-card {
      height: 572px !important;
    }
1 Like