Nuxt3(Vue3)에서 eChart 적용 시 dom 관련 오류 해결 방법 기록

class1119·2024년 3월 20일
0

nuxt3기반 프로젝트 진행 중 echart 적용 시 dom 관련 오류가 있어 해결방법을 기록함.
참고로 nuxt.config.ts에서 ssr은 false로 적용

오류내용

[EChart] Can't get DOM width or height. Please check dom.clientWidth and dom.clientHeight. They should not be 0.For example, you may need to call this in the callback of window.onload.
[EChart] There is a chart instance already initialized on the dom

렌더링 시점 문제인 것 같아 이리저리 찾아보다가 해결 방법을 찾음.

  1. EChart Component 생성
<template>
	<div class="h-full w-full">
		<VChart class="h-full w-full" :option="pieOption" />
	</div>
</template>

<script setup>
import { PieChart } from 'echarts/charts'
import { GridComponent, LegendComponent, TitleComponent, TooltipComponent, } from 'echarts/components'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { ref } from 'vue'
import VChart from 'vue-echarts'

use([
	CanvasRenderer,
	PieChart,
	TitleComponent,
	TooltipComponent,
	LegendComponent,
	GridComponent,
])

const pieOption = ref({
	title: {
		text: 'Title Text',
		left: 'center',
		top: 'center'
	},
	tooltip: {
		trigger: 'item',
		formatter: '{a} <br/>{b} : {c} ({d}%)',
	},
	legend: {
		orient: 'horizontal',
		left: 'center',
		top: '90%',
		data: ['Direct', 'Email', 'Ad Networks', 'Video Ads', 'Search Engines'],
	},
	height: '100%',
	width: '100%',
	textStyle: {
		fontFamily: 'NanumSquareNeo'
	},
	series: [
		{
			name: 'Count',
			type: 'pie',
			radius: ['30%', '60%'],
			center: ['50%', '50%'],
			padAngle: 3,
			itemStyle: {
				borderRadius: 10
			},
			data: [
				{ value: 335, name: 'Direct' },
				{ value: 310, name: 'Email' },
				{ value: 234, name: 'Ad Networks' },
				{ value: 135, name: 'Video Ads' },
				{ value: 1548, name: 'Search Engines' },
			],
			
			emphasis: {
				itemStyle: {
					shadowBlur: 15,
					shadowOffsetX: 0,
					shadowColor: 'rgba(0, 0, 0, 0.5)',
				},
			},
		},
	],
});
</script>
<style scoped>

</style>
  1. EChart를 사용하는 상위 컴포넌트에 defineAsyncComponent를 사용할 것.
<script setup>
import {Icon} from "#components";
import { defineAsyncComponent} from "vue";
// import EChartComponent from '~/components/EChartComponent.vue';

const echart = defineAsyncComponent(() =>
	import('~/components/EChartComponent.vue')
)

</script>

<template>
	<div class="h-full flex flex-col ">
		<header class="border-b p-2 dark:border-gray-800">
			<div class="flex items-center">
				<div class="pr-1">
					<Icon name="ic:outline-area-chart" width="24" height="24" />
				</div>
				<div class="flex-1 text-lg font-bold">
					Dashboard
				</div>
			</div>
		</header>
		<main class="h-full grow p-2 flex flex-col">
			<div class="flex flex-col lg:flex-row gap-2 h-full">
				<div class="lg:basis-1/2 h-full">
					<echart />
				</div>
				<div class="lg:basis-1/2 h-full">
					<echart />
				</div>
			</div>
		</main>
	</div>
</template>

<style scoped lang="scss">

</style>

eChart나 ApexChart 사용 시 크기를 미리 지정하지 않으면 위 형태의 에러가 발생하는 것 같음.

profile
GIS, OpenLayers, OpenSource, Web, Server 관련 개발

0개의 댓글