@niu-tools/vue3
<script setup lang="ts">
import { useEChart } from '@niu-tools/vue3'
import { useResizeObserver } from '@vueuse/core'
import { onMounted, ref } from 'vue'
const data: number[][] = []
for (let i = 0; i <= 100; i++) {
let theta = (i / 100) * 360
let r = 5 * (1 + Math.sin((theta / 180) * Math.PI))
data.push([r, theta])
}
function getOptions(data) {
return {
title: {
text: 'Two Value-Axes in Polar',
},
legend: {
data: ['line'],
},
polar: {},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
},
},
angleAxis: {
type: 'value',
startAngle: 0,
},
radiusAxis: {},
series: [
{
coordinateSystem: 'polar',
name: 'line',
type: 'line',
data: data,
},
],
}
}
function handleClick(num: number) {
const data: number[][] = []
for (let i = 0; i <= num; i++) {
let theta = (i / 100) * 360
let r = 5 * (1 + Math.sin((theta / 180) * Math.PI))
data.push([r, theta])
}
setOption(getOptions(data))
}
const targetEl = ref<HTMLElement | null>(null)
const { init, clear, dispose, resize, setOption } = useEChart({
el: targetEl,
option: getOptions(data),
})
onMounted(() => {
useResizeObserver(targetEl, () => {
resize()
})
})
</script>
<template>
<div>
<n-space>
<n-button @click="handleClick(50)">50数据</n-button>
<n-button @click="handleClick(100)">100数据</n-button>
<n-button @click="clear">清除图表</n-button>
<n-button @click="dispose">销毁图表</n-button>
<n-button @click="init">初始化图表</n-button>
</n-space>
<div
style="height: 500px; resize: horizontal; overflow: auto"
ref="targetEl"
></div>
</div>
</template>
<script setup lang="ts">
import { useEChart } from '@niu-tools/vue3'
import { useResizeObserver } from '@vueuse/core'
import { onMounted, ref } from 'vue'
const data: number[][] = []
for (let i = 0; i <= 100; i++) {
let theta = (i / 100) * 360
let r = 5 * (1 + Math.sin((theta / 180) * Math.PI))
data.push([r, theta])
}
function getOptions(data) {
return {
title: {
text: 'Two Value-Axes in Polar',
},
legend: {
data: ['line'],
},
polar: {},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
},
},
angleAxis: {
type: 'value',
startAngle: 0,
},
radiusAxis: {},
series: [
{
coordinateSystem: 'polar',
name: 'line',
type: 'line',
data: data,
},
],
}
}
function handleClick(num: number) {
const data: number[][] = []
for (let i = 0; i <= num; i++) {
let theta = (i / 100) * 360
let r = 5 * (1 + Math.sin((theta / 180) * Math.PI))
data.push([r, theta])
}
setOption(getOptions(data))
}
const targetEl = ref<HTMLElement | null>(null)
const { init, clear, dispose, resize, setOption } = useEChart({
el: targetEl,
option: getOptions(data),
})
onMounted(() => {
useResizeObserver(targetEl, () => {
resize()
})
})
</script>
<template>
<div>
<n-space>
<n-button @click="handleClick(50)">50数据</n-button>
<n-button @click="handleClick(100)">100数据</n-button>
<n-button @click="clear">清除图表</n-button>
<n-button @click="dispose">销毁图表</n-button>
<n-button @click="init">初始化图表</n-button>
</n-space>
<div
style="height: 500px; resize: horizontal; overflow: auto"
ref="targetEl"
></div>
</div>
</template>
源码
查看源码
useEchart/index.ts源码
ts
export * from "./useEchart"
export * from "./useEchart"
useEchart/useEchart.ts源码
ts
import { ref, Ref, unref } from "vue"
import * as echarts from "echarts"
import type { } from "echarts"
import { useEventListener, tryOnMounted, tryOnBeforeUnmount } from "@vueuse/core";
export function useEChart(opts: { el: Ref<HTMLElement | null>; option?: any, cloneNode?: boolean }) {
const originOption = opts.option ?? {}
let myChart: ReturnType<typeof echarts.init> | null = null
let pureEl: Node | undefined
let curOption = ref(originOption)
const stop = useEventListener(window, "resize", () => {
if (!myChart) return
myChart?.resize()
})
function clear() {
if (!myChart) return
myChart?.clear()
}
function dispose() {
if (!myChart) return
if (myChart.isDisposed()) return
// curOption.value = originOption
myChart?.dispose()
if (pureEl) {
const el = unref(opts.el)
el?.replaceWith(pureEl)
opts.el.value = pureEl as any
pureEl = undefined
}
myChart = null
}
function resize() {
myChart?.resize()
}
tryOnMounted(init)
tryOnBeforeUnmount(() => {
stop()
dispose()
myChart = null
pureEl = undefined
curOption.value = undefined
})
function setOption(option: object | null = null) {
if (option) curOption.value = option
myChart && myChart.setOption(curOption.value)
}
function init() {
if (myChart) return
const el = unref(opts.el)
if (!el) {
return
}
if (opts.cloneNode) {
pureEl = el.cloneNode(true)
}
myChart = echarts.init(el)
setOption()
}
return {
init,
dispose,
clear,
resize,
setOption,
}
}
import { ref, Ref, unref } from "vue"
import * as echarts from "echarts"
import type { } from "echarts"
import { useEventListener, tryOnMounted, tryOnBeforeUnmount } from "@vueuse/core";
export function useEChart(opts: { el: Ref<HTMLElement | null>; option?: any, cloneNode?: boolean }) {
const originOption = opts.option ?? {}
let myChart: ReturnType<typeof echarts.init> | null = null
let pureEl: Node | undefined
let curOption = ref(originOption)
const stop = useEventListener(window, "resize", () => {
if (!myChart) return
myChart?.resize()
})
function clear() {
if (!myChart) return
myChart?.clear()
}
function dispose() {
if (!myChart) return
if (myChart.isDisposed()) return
// curOption.value = originOption
myChart?.dispose()
if (pureEl) {
const el = unref(opts.el)
el?.replaceWith(pureEl)
opts.el.value = pureEl as any
pureEl = undefined
}
myChart = null
}
function resize() {
myChart?.resize()
}
tryOnMounted(init)
tryOnBeforeUnmount(() => {
stop()
dispose()
myChart = null
pureEl = undefined
curOption.value = undefined
})
function setOption(option: object | null = null) {
if (option) curOption.value = option
myChart && myChart.setOption(curOption.value)
}
function init() {
if (myChart) return
const el = unref(opts.el)
if (!el) {
return
}
if (opts.cloneNode) {
pureEl = el.cloneNode(true)
}
myChart = echarts.init(el)
setOption()
}
return {
init,
dispose,
clear,
resize,
setOption,
}
}