apexcharts / vue-apexcharts

📊 Vue 2 component for ApexCharts
https://apexcharts.com
MIT License
1.33k stars 135 forks source link

Reference error - Window is not defined #307

Closed Rednas83 closed 2 months ago

Rednas83 commented 3 years ago

Just trying vue-apexchart, but I get "window is not defined" after exactly folowing the installation instructions.

Tried to reproduce it with a codepen but I got an empty window https://codepen.io/rednas83/pen/BaLRORL

I based the codepen on this one, which is following a different approach? https://codepen.io/lukaszflorczak/pen/yrpWgZ

Any idea what could be the problem?

Also I think a working codepen could be usefull. Perhaps add a link on the github page?

hyperchance commented 3 years ago

Same issue in React. Works well in browser, but fails to compile the code even in development stage, because for SSR {window} is not defined.

RahmanQureshi commented 3 years ago

any update on this?

RahmanQureshi commented 3 years ago

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });
heychazza commented 2 years ago

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

I'm facing the same issue here but with Vue, are there any similar alternatives to this but for Vue instead?

KillianLeroux commented 2 years ago

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

I'm facing the same issue here but with Vue, are there any similar alternatives to this but for Vue instead?

Same problem, does anyone have a solution please? :)

heychazza commented 2 years ago

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

I'm facing the same issue here but with Vue, are there any similar alternatives to this but for Vue instead?

Same problem, does anyone have a solution please? :)

I got it working, sharing in case it helps future Googlers. 😄

<template>
    <apex-charts />
</template>

<script setup>
const ApexCharts = defineAsyncComponent(() => import("vue3-apexcharts"));
</script>
nullr00tbyte commented 2 years ago

Im working with Quasar Framework that use Vue3

so, i have this boot.js

import VueApexCharts from "vue3-apexcharts";
import { boot } from "quasar/wrappers";

export default boot(({ app }) => {
  app.use(VueApexCharts);
});

and i got Windows is not defined when try to use SSR, any idea about how implement this Globally?

 const ApexCharts = defineAsyncComponent(() => import("vue3-apexcharts"));`
yanisalfian commented 1 year ago

@nullr00tbyte

First, you need to declare in your quasar.config.js

    boot: [
      {
        server: false,
        path: '<your-boot-file-name>'
      }
    ],

See https://quasar.dev/quasar-cli-vite/boot-files

Then you need to wrap apexchart component with <q-no-ssr> so it only render on client side. Otherwise you will get Cannot read properties of null (reading 'nodeType') error.

<q-no-ssr>
  <apexchart type="donut" :options="donutOptions" :series="series"></apexchart>
</q-no-ssr>
vinosamari commented 1 year ago

heychazza

Any workarounds for vue2?

aekiratli commented 1 year ago

cannot use useRef, it is always null

mbunico commented 1 year ago

getting the same issue right now in my nuxt project

anik8naik commented 10 months ago

heychazza

Any workarounds for vue2?

im getting same issue for vue2 . Any workaround or things to refactor?

Waishnav commented 10 months ago

cannot use useRef, it is always null

You can wrap the component through rendering it via dynamic (i.e lazy loading) in the page.js instead of using dynamic in the apexchart component itself, then you can able to set the ref and it will never be null.

JyotiKM29 commented 9 months ago

any solution ?

Rednas83 commented 9 months ago

Just tried it again and with a little help of copilot I managed to find a working solution for nuxt users. I also rewritten it for the composition api with the script setup tag.

<template>
  <component :is="chartComponent" width="500" type="bar" :options="chartOptions" :series="series" />
</template>

<script setup lang="ts">
let chartComponent = shallowRef(null);
onMounted(async () => {
  const VueApexCharts = (await import('vue3-apexcharts')).default;
  chartComponent.value = VueApexCharts;
});

const chartOptions = ref({
  chart: {
    id: "vuechart-example",
  },
  xaxis: {
    categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998],
  },
})

const series = ref([
  {
    name: "series-1",
    data: [30, 40, 35, 50, 49, 60, 70, 92],
  },
])
</script>

@brianlagunas Can you also add this solution to the docs for nuxt users?

anik8iazi commented 9 months ago

this was helpful... it worked for vue2 EOL version 2.7.16.

Ni9Logic commented 8 months ago

So yeah after implementing this solution i am getting this error now

Error 1:

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'toString')

Call Stack
t.value
node_modules/apexcharts/dist/apexcharts.common.js (6:410839)
t.value
node_modules/apexcharts/dist/apexcharts.common.js (6:406572)
t.value
node_modules/apexcharts/dist/apexcharts.common.js (14:37170)
t.eval [as create]
node_modules/apexcharts/dist/apexcharts.common.js (6:4476)
eval
node_modules/apexcharts/dist/apexcharts.common.js (14:36561)
new Promise
<anonymous>
t.value
node_modules/apexcharts/dist/apexcharts.common.js (14:21686)

So this error occurs in development and in production server this works fine.

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

This only helped solving the error in production and compilation error. I am still facing issues in development server.

Error 2: I am also getting this strange type error and I don't know how to sort this out. Type '{ series: { name: string; data: number[]; }[]; chart: { height: number; zoom: { enabled: boolean; }; }; dataLabels: { enabled: boolean; }; stroke: { width: number[]; curve: string; dashArray: number[]; }; title: { text: string; align: string; }; ... 4 more ...; grid: { ...; }; }' is not assignable to type 'ApexOptions'. The types of 'stroke.curve' are incompatible between these types. Type 'string' is not assignable to type '"straight" | "smooth" | "stepline" | "monotoneCubic" | ("straight" | "smooth" | "stepline" | "monotoneCubic")[] | undefined'.ts(2322) react-apexcharts.d.ts(29, 5): The expected type comes from property 'options' which is declared here on type 'IntrinsicAttributes & Props'

Actual Code, This is nextJS.

`
import React, { useState } from "react";
// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('react-apexcharts'), { ssr: false });
interface LineChartProps {
    invoiceCount: number[];
    jobCount: number[];
}
// Function to generate the last 12 days including today
const generateLast12Days = () => {
    const today = new Date();
    const last12Days = [];
    for (let i = 14; i >= 0; i--) {
        const date = new Date(today);
        date.setDate(today.getDate() - i);
        last12Days.push(date);
    }
    return last12Days;
};

// Function to format date as 'dd MMM'
const formatDate = (date: Date) => {
    const options: Intl.DateTimeFormatOptions = { day: '2-digit', month: 'short' };
    return new Intl.DateTimeFormat('en-US', options).format(date);
};

export const LineChart2Weeks: React.FC<LineChartProps> = ({ invoiceCount, jobCount }: LineChartProps) => {
    const [chartOption, setChartOption] = useState({
        options: {
            series: [{
                name: "Session Duration",
                data: invoiceCount
            },
            {
                name: "Page Views",
                data: jobCount
            }
            ],
            chart: {
                height: 350,
                zoom: {
                    enabled: false
                },
            },
            dataLabels: {
                enabled: false
            },
            stroke: {
                width: [5, 7, 5],
                curve: 'straight',
                dashArray: [0, 8, 5]
            },
            title: {
                text: 'Page Statistics',
                align: 'left'
            },
            legend: {
                tooltipHoverFormatter: function (val: any, opts: any) {
                    return val + ' - <strong>' + opts.w.globals.series[opts.seriesIndex][opts.dataPointIndex] + '</strong>'
                }
            },
            markers: {
                size: 0,
                hover: {
                    sizeOffset: 6
                }
            },
            xaxis: {
                categories: ['01 Jan', '02 Jan', '03 Jan', '04 Jan', '05 Jan', '06 Jan', '07 Jan', '08 Jan', '09 Jan',
                    '10 Jan', '11 Jan', '12 Jan'
                ],
            },
            tooltip: {
                y: [
                    {
                        title: {
                            formatter: function (val: any) {
                                return val + " (created)"
                            }
                        }
                    },
                    {
                        title: {
                            formatter: function (val: any) {
                                return val + " (created)"
                            }
                        }
                    },
                    {
                        title: {
                            formatter: function (val: any) {
                                return val;
                            }
                        }
                    }
                ]
            },
            grid: {
                borderColor: '#f1f1f1',
            }
        }
    }
    )
    return (

        <div className="mt-10">
            <h1>2-Weeks Statistics</h1>
            <Chart
                options={chartOption.options}
                series={chartOption.options.series}
                type="line"
                width="500"
            />
        </div>

    )
}
`
Ni9Logic commented 8 months ago

So yeah after implementing this solution i am getting this error now

Error 1:

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'toString')

Call Stack
t.value
node_modules/apexcharts/dist/apexcharts.common.js (6:410839)
t.value
node_modules/apexcharts/dist/apexcharts.common.js (6:406572)
t.value
node_modules/apexcharts/dist/apexcharts.common.js (14:37170)
t.eval [as create]
node_modules/apexcharts/dist/apexcharts.common.js (6:4476)
eval
node_modules/apexcharts/dist/apexcharts.common.js (14:36561)
new Promise
<anonymous>
t.value
node_modules/apexcharts/dist/apexcharts.common.js (14:21686)

So this error occurs in development and in production server this works fine.

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

This only helped solving the error in production and compilation error. I am still facing issues in development server.

Error 2: I am also getting this strange type error and I don't know how to sort this out. Type '{ series: { name: string; data: number[]; }[]; chart: { height: number; zoom: { enabled: boolean; }; }; dataLabels: { enabled: boolean; }; stroke: { width: number[]; curve: string; dashArray: number[]; }; title: { text: string; align: string; }; ... 4 more ...; grid: { ...; }; }' is not assignable to type 'ApexOptions'. The types of 'stroke.curve' are incompatible between these types. Type 'string' is not assignable to type '"straight" | "smooth" | "stepline" | "monotoneCubic" | ("straight" | "smooth" | "stepline" | "monotoneCubic")[] | undefined'.ts(2322) react-apexcharts.d.ts(29, 5): The expected type comes from property 'options' which is declared here on type 'IntrinsicAttributes & Props'

Actual Code, This is nextJS.

`
import React, { useState } from "react";
// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('react-apexcharts'), { ssr: false });
interface LineChartProps {
    invoiceCount: number[];
    jobCount: number[];
}
// Function to generate the last 12 days including today
const generateLast12Days = () => {
    const today = new Date();
    const last12Days = [];
    for (let i = 14; i >= 0; i--) {
        const date = new Date(today);
        date.setDate(today.getDate() - i);
        last12Days.push(date);
    }
    return last12Days;
};

// Function to format date as 'dd MMM'
const formatDate = (date: Date) => {
    const options: Intl.DateTimeFormatOptions = { day: '2-digit', month: 'short' };
    return new Intl.DateTimeFormat('en-US', options).format(date);
};

export const LineChart2Weeks: React.FC<LineChartProps> = ({ invoiceCount, jobCount }: LineChartProps) => {
    const [chartOption, setChartOption] = useState({
        options: {
            series: [{
                name: "Session Duration",
                data: invoiceCount
            },
            {
                name: "Page Views",
                data: jobCount
            }
            ],
            chart: {
                height: 350,
                zoom: {
                    enabled: false
                },
            },
            dataLabels: {
                enabled: false
            },
            stroke: {
                width: [5, 7, 5],
                curve: 'straight',
                dashArray: [0, 8, 5]
            },
            title: {
                text: 'Page Statistics',
                align: 'left'
            },
            legend: {
                tooltipHoverFormatter: function (val: any, opts: any) {
                    return val + ' - <strong>' + opts.w.globals.series[opts.seriesIndex][opts.dataPointIndex] + '</strong>'
                }
            },
            markers: {
                size: 0,
                hover: {
                    sizeOffset: 6
                }
            },
            xaxis: {
                categories: ['01 Jan', '02 Jan', '03 Jan', '04 Jan', '05 Jan', '06 Jan', '07 Jan', '08 Jan', '09 Jan',
                    '10 Jan', '11 Jan', '12 Jan'
                ],
            },
            tooltip: {
                y: [
                    {
                        title: {
                            formatter: function (val: any) {
                                return val + " (created)"
                            }
                        }
                    },
                    {
                        title: {
                            formatter: function (val: any) {
                                return val + " (created)"
                            }
                        }
                    },
                    {
                        title: {
                            formatter: function (val: any) {
                                return val;
                            }
                        }
                    }
                ]
            },
            grid: {
                borderColor: '#f1f1f1',
            }
        }
    }
    )
    return (

        <div className="mt-10">
            <h1>2-Weeks Statistics</h1>
            <Chart
                options={chartOption.options}
                series={chartOption.options.series}
                type="line"
                width="500"
            />
        </div>

    )
}
`

If someone else faces this issues this is how I fixed it. It was basically saying that type of curve is not correct. stroke: { width: [5, 7, 5], curve: 'smooth', dashArray: [0, 8, 5] },

malgorzata-stefanowicz commented 8 months ago

I encountered this problem with React + next.js, I had to add 'use client' at the top of my component file.

FarhanAnwar523 commented 8 months ago

I encountered the same issue and resolved it with the solution provided above.

github-actions[bot] commented 2 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.