Nick M
Nick M

Reputation: 71

How to render ApexCharts stacked bar inside modal/v-dialog component?

I'm encountering a niggly issue with vue-apexcharts - while trying to display some data in a stacked bar plot.

I have a simple component defined as follows:

<template>
    <div v-if="this.loaded">
        <apexchart
            width="100%"
            :height="this.height"
            :options="this.chartOptions"
            :series="this.chartData"
        ></apexchart>
    </div>
</template>

<script>
export default {
    name: "StackedBar",
    props: ["data", "labels", "height"],

    data() {
        return {
            loaded: false,
            chartData: [],
            chartOptions: {},
        }
    },

    async mounted() {
        await this.$nextTick()
        this.chartData = this.data
        this.chartOptions = this.buildChartOptions()
        this.loaded = true
    },

    methods: {
        buildChartOptions: function () {
            let chartOptions = {
                theme: {
                    mode: this.getTheme(),
                },
                chart: {
                    fontFamily: "Roboto Mono, Roboto, Arial, sans-serif",
                    type: "bar",
                    stacked: true,
                },
                plotOptions: {
                    bar: {
                        horizontal: true,
                    },
                },
                xaxis: {
                    categories: this.labels,
                },
                fill: {
                    opacity: 1,
                },
                legend: {
                    position: "right",
                    horizontalAlign: "left",
                },
            }

            return chartOptions
        },

        getTheme: function () {
            if (this.$vuetify.theme.dark) {
                return "dark"
            } else {
                return "light"
            }
        },
    },
}
</script>

This component is used in a vuetify v-dialog component, and only visible when a user clicks to expand the v-dialog's parent component. Ignoring the nextTick() call in the mounted hook, which seems to be necessary to get the chart to render at the first visibility toggle of the dialog component, I see the following:

  1. User clicks to expand component; dialog becomes visible. Chart is rendered as expected.
  2. User clicks to close dialog. Dialog no longer visible.
  3. User clicks to expand component; dialog becomes visible. Chart does not display, with the following error thrown:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'x')
    at t.value (apexcharts.min.js:6)
    at t.value (apexcharts.min.js:6)
    at t.value (apexcharts.min.js:6)
    at t.value (apexcharts.min.js:6)
    at s.value (apexcharts.min.js:6)
    at c (apexcharts.min.js:6)
    at s.value (apexcharts.min.js:6)
    at t.value (apexcharts.min.js:6)
    at t.value (apexcharts.min.js:14)
    at t.<anonymous> (apexcharts.min.js:6)

Interestingly, if I toggle the stacked option to false, this no longer happens, and chart is displayed as expected every time the dialog is opened/closed. This behaviour also doesn't happen if I display the data as a heatmap rather than a bar.

So my question is: is this an expected behaviour, and some operator on my end, or is this unexpected?

A stacked bar is really the most clear choice for the data I'm trying to display, and ApexCharts seems to be overwhelmingly superior to all other plotting libraries I've tried - so a solution would be wonderful.

Thanks

Upvotes: 0

Views: 1320

Answers (1)

cmfc31
cmfc31

Reputation: 1508

Since you put your component inside a v-dialog, did you add the eager prop to the dialog? The eager prop will force the components content to render on mounted.

<v-dialog v-model="dialog" eager>
   ...
</v-dialog>

Upvotes: 1

Related Questions