Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Charts are being duplicated #3

Closed
Oleksii14 opened this issue Nov 30, 2020 · 34 comments · Fixed by #50
Closed

Charts are being duplicated #3

Oleksii14 opened this issue Nov 30, 2020 · 34 comments · Fixed by #50

Comments

@Oleksii14
Copy link

Env:

"apexcharts": "^3.22.2",
"vue": "^3.0.2",
"vue3-apexcharts": "^1.1.1"

My options:

{
 chart: {
        height: 590,
        type: "area",
      },
      dataLabels: {
        enabled: false,
      },
      stroke: {
        curve: "smooth",
      },
      xaxis: {
        labels: {
          showDuplicates: false,
          hideOverlappingLabels: true,
          offsetY: 20,
          style: {
            colors: "#979797",
          },
        },
      },
}

Template:

<apexchart type="area" :height="590" :options="options" :series="series" />

Result:

image

Note: when I change a screen resolution, the duplicated one disappears

@junedchhipa junedchhipa transferred this issue from apexcharts/vue-apexcharts Dec 15, 2020
@junedchhipa
Copy link
Contributor

Sorry for the late response.
Can you please create a Codesandbox demo to reproduce this?

@oleksii-shaposhnikov
Copy link

Sorry for the late response.
Can you please create a Codesandbox demo to reproduce this?

I have fixed this issue by using apexcharts package without vue wrapper. I will attach demo link ASAP

@lucasdcrk
Copy link

Same issue here using the latest versions of Vue, VueApexCharts and ApexCharts
I created a Codesandbox here: https://codesandbox.io/s/cool-jennings-qbbr5?file=/src/App.vue

@mijreed
Copy link

mijreed commented May 8, 2021

Having the same issue. I have to integrate with Vue3 so I can't use ApexCharts native. Any resolution to it?

@Oleksii14
Copy link
Author

@mijreed you can use it like

<template>
  <div id="chart" />
</template>

<script lang="ts">
import { defineComponent, onMounted } from "vue";
import ApexChart from "apexcharts";

export default defineComponent({
  setup() {
    let chartInstance;

    const options = {
      colors: ["#1890FF", "#FA4F60"],
      chart: {
        type: "area",
      },
      stroke: {
        curve: "smooth",
      },
    };

    const getChartData = () => [
      {
        name: "Test",
        data: [
          {
            x: "1",
            y: 2,
          },

          {
            x: "2",
            y: 2,
          },
        ],
      },
    ];

    onMounted(() => {
      chartInstance = new ApexChart(document.querySelector("#chart"), {
        ...options,
        series: getChartData(),
      });
      chartInstance.render();
    });
  },
});
</script>

@mijreed
Copy link

mijreed commented May 11, 2021

That worked. Thank you!

@kalenpw
Copy link

kalenpw commented Jul 9, 2021

I can confirm, it is a problem with Vue3 using Vite as well. Same issue where if a resize happens the duplicate disappears.

@NWBY
Copy link

NWBY commented Jul 21, 2021

Having this issue too. Opening the development tools or resizing the window causes the duplicate to disappear.

@0x62
Copy link

0x62 commented Aug 6, 2021

+1 also having this issue with Vue 3 and Vite

@lukesnowden
Copy link

mounted() {
    this.$nextTick(() => {
        window.dispatchEvent(new Event('resize'));
    });
}

Will fix the issue for now

@horia161999
Copy link

Having the same issue.

@IvanBalakirev
Copy link

IvanBalakirev commented Oct 30, 2021

The same here! Hack with event works but doesn't look like a right solution

@elreco
Copy link

elreco commented Nov 8, 2021

same issue :/

@haroon97
Copy link

Facing the exactly same issue

@andreashe
Copy link

andreashe commented Dec 12, 2021

Me too!

mounted() was too eary for me scenario. I moved the snipped from above to updated().

@mjwweb
Copy link

mjwweb commented Jan 23, 2022

Still not fixed

@Flloooow
Copy link

You just need to change mounted() to created(), resolving the issue for me

@mperrien
Copy link

And if you're using the Composition API (ie <script setup> syntax) use onBeforeMount instead of onMounted.

@gorillaworkout
Copy link

And if you're using the Composition API (ie <script setup> syntax) use onBeforeMount instead of onMounted.

its worked well. awesome

@razorness
Copy link
Contributor

razorness commented Jul 19, 2022

This happens because you mount the component and use reactivity too quickly before the apex component can be initialized. In this case, the init method of the component will be triggered twice, because it is waiting for the next tick to continue.
So, instead of arguing with triggering the resize event and having duplicates for a short time, you should wrap your data binding in a call of nextTick. Or add a v-if to your apex component to render it only when all your data has been bound.

This is my work around as long as #50 is not accepted, which adds an additional check within the init method.

@acidjazz
Copy link

May I ask why this is closed? I had to implement the nextTick workaround I found via https://stackoverflow.com/a/70826352/2817604 - looks like it was picked from #3 (comment)

@razorness
Copy link
Contributor

Which version are you using?

@acidjazz
Copy link

"vue3-apexcharts": "^1.4.1",

NuxtJS V3 project using a plugin:

import VueApexCharts from 'vue3-apexcharts'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(VueApexCharts)
})

@acidjazz
Copy link

just saw your PR and the fix - nice work @razorness - can we get a patch release? i'll update that SO question

@Jonorusc
Copy link

Jonorusc commented Nov 8, 2022

this.$nextTick(() => {
window.dispatchEvent(new Event('resize'));
});

thank you. It works for me

@jice-lavocat
Copy link

[...] I had to implement the nextTick workaround [...]

Until the patch is released, could you share how you implemented this in Nuxt3 @acidjazz ?
I'm struggling to do it properly.

@acidjazz
Copy link

Nuxt V3:

plugins/apex.client.ts

import VueApexCharts from 'vue3-apexcharts'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(VueApexCharts)
})

components/PublicChartLine.vue

<script lang="ts" setup>
import { ApexOptions } from 'apexcharts'

const options:ApexOptions = {
  colors: ['#6667ab', 'green'],
  tooltip: { theme: 'none' },
  chart: {
    type: 'line',
    toolbar: { show: false },
    foreColor: '#6b7280',
  },
  grid: { show: false },
  markers: {
    size: 6,
    colors: ['#6667ab'],
  },
  xaxis: {
    title: { text: 'Year' },
    tooltip: { enabled: false },
    categories: [2018, 2019, 2020, 2021, 2022],
    axisBorder: { show: false },
    axisTicks: { show: false },
  },
  yaxis: {
    title: { text: 'Days' },
  },
  stroke: {
    show: true,
    curve: 'smooth',
  },
  fill: {
    type: 'gradient',
    gradient: {
      type: 'horizontal',
      colorStops: [
        {
          offset: 1,
          color: '#9c9ae3',
          opacity: 1,
        },
        {
          offset: 100,
          color: '#00c893',
          opacity: 1,
        },
      ],
    },
  },
  dataLabels: {
    style: {
      colors: ['#6667ab'],
    },
  },
}
const series = [
  {
    name: 'Days',
    data: [352, 203, 126, 51, 8],
  },
]

onMounted(() => {
  nextTick(() => {
    window.dispatchEvent(new Event('resize'))
  })
})
</script>

<template>
  <div>
    <apexchart
      class="hidden lg:block w-470px" :options="options" :series="series"
      width="470"
    />
    <apexchart
      class="lg:hidden" :options="options" :series="series"
      width="370"
    />
  </div>
</template>

@jice-lavocat
Copy link

jice-lavocat commented Nov 12, 2022

Thanks, that works like a charm.
My code was pretty similar to your, but I tried to do the refresh at the plugin side and not at the component side. Something along the lines:

plugins/apex.client.ts (not working)

import VueApexCharts from 'vue3-apexcharts'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(VueApexCharts)

  nuxtApp.hook('page:finish', (pageComponent) => {
    nextTick()
    window.dispatchEvent(new Event('resize'))
  })

})

But I couldn't find why this didn't work (I tried several other steps of the lifecycle, like app:mounted without much success).

@thiagopetherson
Copy link

thiagopetherson commented Feb 22, 2023

I added a ":key" to the graph and it solved.

<apexchart type="area" :options="options" :series="series" :key="chart-items-${series[0].data.length}"></apexchart>

@Josmun55
Copy link

Josmun55 commented Apr 4, 2023

Window.dispatchEvent(new Event('resize')) on both onMounted and updated caused a visible flick of the duplicate before it got removed. Solved it by reassigning the data.

onMounted(() => {
      nextTick(() => {
        series.value = [...props.graphData];
      })
    })

@ravisharmaa
Copy link

Also faced this same, and updating the data on beforeMount worked for me.

@emmanuelizzy
Copy link

I added a ":key" to the graph and it solved.

<apexchart type="area" :options="options" :series="series" :key="chart-items-${series[0].data.length}"></apexchart>

I love this solution better using :key which forces a component re-render and the best thing is that apex-charts retains its animation with this approach.

@ishaiavrahami
Copy link

ishaiavrahami commented Jul 10, 2023

When installing 1.4.1 its not showing me the recent commit Any idea?

@razorness
Copy link
Contributor

New version issued just 2 days ago. This issue should not happen anymore. Your hot fixes should be safe to remove.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.