封装 ECharts 容器组件监听图表大小变化使用了 ResizeObserver 函数监听容器大小变化,变化时调用 chart.resize() 重新渲染图表。监听图表大小变化的代码js自动换行复制// 监听容器大小变化,实现图表自适应 const resizeObserver = new ResizeObserver((entries) => { console.log(entries, "容器大小变化") this.chart.resize() }) resizeObserver.observe(this.$refs.container) 容器组件完整代码防抖节流函数js自动换行复制// 函数防抖 function debounce(fn, wait = 500) { let timeout = null return function () { // eslint-disable-next-line prefer-rest-params const args = arguments if (timeout !== null) clearTimeout(timeout) timeout = setTimeout(() => { fn.apply(this, args) }, wait) } } // 函数节流 function throttle(fn, delay = 500) { let lastTime let timer return function () { // eslint-disable-next-line prefer-rest-params const args = arguments // 记录当前函数触发的时间 const nowTime = Date.now() if (lastTime && nowTime - lastTime < delay) { clearTimeout(timer) timer = setTimeout(() => { // 记录上一次函数触发的时间 lastTime = nowTime }, delay) } else { lastTime = nowTime fn.apply(this, args) } } } export { debounce, throttle } 38 行html自动换行复制<template> <div class="container" ref="container"></div> </template> <script> import * as echarts from "echarts" import { SVGRenderer, CanvasRenderer } from "echarts/renderers" import { debounce } from "./utils/DebounceThrottle.js" echarts.use([SVGRenderer, CanvasRenderer]) export default { data() { return { chart: null, resizeObserver: null, } }, props: { options: { type: Object, default: () => {}, required: true, }, render: { type: String, default: "canvas", required: false, validator(type) { return ["canvas", "svg"].includes(type) }, }, }, watch: { options: { handler(newOptions) { console.log("options update") this.chart.setOption(newOptions) }, deep: true, }, }, methods: {}, mounted() { this.chart = echarts.init(this.$refs.container, null, { render: this.render, locale: "ZH", useDirtyRect: true, }) this.chart.setOption(this.options) // 监听容器大小变化,实现图表自适应 if (window.ResizeObserver) { this.resizeObserver = new ResizeObserver( debounce((entries) => { console.log(entries, "容器大小变化") this.chart.resize() }) ) this.resizeObserver.observe(this.$refs.container) } }, beforeDestroy() { console.log("销毁") if (this.chart) { this.chart.dispose() } if (window.ResizeObserver && this.resizeObserver) { this.resizeObserver.unobserve(this.$refs.container) } }, } </script> <style lang="less" scoped> .container { width: 100%; height: 100%; } </style> 81 行使用 ECharts 容器组件组件内部监听外部传入数据变化,变化后使用 watch 更新 options。圆环图表示例代码html自动换行复制<template> <ChartContainer :options="options" /> </template> <script> import ChartContainer from "./ChartContainer.vue" export default { components: { ChartContainer, }, props: { pData: { type: Array, default: [], required: false, }, }, data() { return { options: {}, } }, watch: { pData: { handler() { this.options = this.barChartOptions() }, immediate: true, }, }, methods: { barChartOptions() { const data = this.pData.map((item) => { return { value: item.fieldCountNum, name: item.fieldName, } }) return { tooltip: { trigger: "item", }, legend: { top: "bottom", left: "center", }, series: [ { type: "pie", radius: ["35%", "60%"], padAngle: 3, itemStyle: { borderRadius: 5, }, labelLine: { show: true, }, data, }, ], } }, }, } </script> 66 行
评论区
评论加载中...