apexcharts / vue3-apexcharts

📊 Vue-3 component for ApexCharts
MIT License
314 stars 35 forks source link

Custom Tooltip with another Chart in it. Data's appear but not the bars #110

Open florianFM opened 4 months ago

florianFM commented 4 months ago

Hi!

I want to create a chart and when you hover a bar you've got a tooltip with another chart in it. To do so I created a new component to replace the tooltip.

You can see that the component displayed normally displays everything but the one called within the tooltip doesn't have color pie.

Screenshot 2024-07-02 at 14 03 39

Main Component:

<template>
  <apexchart
    height="20"
    type="bar"
    :options="options"
    :series="options.series"
    data-cy="environment-tab-chart-render"
    class="lca-graph"
  />
  <TooltipComponent />
</template>

<script setup lang="ts">
import { h, render } from 'vue';
import TooltipComponent from './TooltipComponent.vue';

const options = {
  series: [
    {
      name: 'Marine Sprite',
      data: [44],
    },
    {
      name: 'Striking Calf',
      data: [53],
    },
    {
      name: 'Tank Picture',
      data: [12],
    },
    {
      name: 'Bucket Slope',
      data: [9],
    },
    {
      name: 'Reborn Kid',
      data: [25],
    },
  ],
  chart: {
    type: 'bar',
    stacked: true,
    stackType: '100%',
    toolbar: {
      show: false,
    },
    sparkline: {
      enabled: true,
    },
  },
  plotOptions: {
    bar: {
      horizontal: true,
    },
  },
  colors: [
    '#E78CBB',
    '#2F4644',
    '#122146',
    '#91A8A7',
    '#CFC385',
    '#E3BCBA',
    '#D3DDDC',
    '#F0D2A4',
    '#8A4417',
    '#B68867',
    '#FFE380',
  ],
  xaxis: {
    labels: {
      show: false,
    },
    axisBorder: {
      show: false,
    },
    axisTicks: {
      show: false,
    },
  },
  yaxis: {
    labels: {
      show: false,
    },
    axisBorder: {
      show: false,
    },
    axisTicks: {
      show: false,
    },
  },
  legend: {
    show: false,
  },
  grid: {
    show: false,
  },
  dataLabels: {
    enabled: false,
  },
  tooltip: {
    custom({
      series,
      seriesIndex,
      dataPointIndex,
      w,
    }: {
      series: string[][];
      seriesIndex: number;
      dataPointIndex: number;
      w: any;
    }) {
      const tooltipEl = document.createElement('div');

      const vnode = h(TooltipComponent, { series, seriesIndex, dataPointIndex, w });
      render(vnode, tooltipEl);

      return tooltipEl.innerHTML;
    },
    y: {
      formatter(val: string) {
        return `${val}%`;
      },
    },
    x: {
      show: false,
    },
  },
};
</script>

Tooltip Component:

<template>
  <div class="custom-tooltip">
    <!-- <div class="color-circle" :style="`background-color: ${color}`" />
    <p class="text-p2-medium">{{ name }}</p>
    <p class="text-p2-medium">{{ data }}</p> -->
    <div class="test" id="mount-point" ref="mountPoint" />
  </div>
</template>

<script setup lang="ts">
// This component is used as a custom tooltip for the ApexCharts
// We can't use quasar components in the tooltip because it's rendered in a different context
import { onMounted, ref } from 'vue';
import ApexCharts from 'apexcharts';

defineProps({
  series: {
    type: Array<Array<string>>,
    required: false,
  },
  seriesIndex: {
    type: Number,
    required: false,
  },
  dataPointIndex: {
    type: Number,
    required: false,
  },
  w: {
    type: Object,
    required: false,
  },
});

// const data = props.series[props.seriesIndex][props.dataPointIndex];
// const name = props.w.globals.seriesNames[props.seriesIndex];
// const color = props.w.globals.colors[props.seriesIndex];

const options = {
  series: [44, 55, 13, 43, 22],
  chart: {
    width: 380,
    type: 'pie',
  },
  labels: ['Team A', 'Team B', 'Team C', 'Team D', 'Team E'],
  responsive: [
    {
      breakpoint: 480,
      options: {
        chart: {
          width: 200,
        },
        legend: {
          position: 'bottom',
        },
      },
    },
  ],
  stroke: {
    show: false,
  },
};

const mountPoint = ref(null);

onMounted(() => {
  const mainChart = new ApexCharts(mountPoint.value, options);
  mainChart.render();
});
</script>

<style lang="scss" scoped>
@use 'src/css/_typography.scss' as *;

.custom-tooltip {
  @extend .text-p2-medium;

  display: flex;
  align-items: center;
  background-color: white;
  border: 1px solid #ccc;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.1);
}

.color-circle {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
  margin-right: 5px;
}

.test {
  border: 1px solid red;
}
</style>

If someone has any idea