vue之echart图表的封装
1、构建echart公用组件
<template> <div :class="className" :style="{ width, height }"></div> </template> <script> import echarts from "echarts"; require("echarts/theme/macarons"); // echarts theme import resize from "./mixins/resize"; export default { mixins: [resize], props: { className: { type: String, default: "chart", }, width: { type: String, default: "100%", }, height: { type: String, default: "300px", }, chartOption: { type: Object, default: () => {}, }, }, data() { return { chart: null, }; }, watch: { chartOption: { deep: true, handler() { if (this.chart) this.initChart(); }, }, }, mounted() { this.$nextTick(() => { this.initChart(); }); }, methods: { initChart() { this.chart = echarts.init(this.$el, "macarons"); this.chart.showLoading({ maskColor: "rgba(255, 255, 255, .2)" }); this.setOptions(); }, setOptions() { setTimeout(() => { this.chart.hideLoading(); this.chart.setOption(this.chartOption); }, 1000); }, }, }; </script>
2、页面尺寸改变时,改变图表尺寸的方法
import { debounce } from '@/utils' export default { data() { return { $_sidebarElm: null, $_resizeHandler: null } }, mounted() { this.initListener() }, activated() { if (!this.$_resizeHandler) { // avoid duplication init this.initListener() } // when keep-alive chart activated, auto resize this.resize() }, beforeDestroy() { this.destroyListener() }, deactivated() { this.destroyListener() }, methods: { // use $_ for mixins properties // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential $_sidebarResizeHandler(e) { if (e.propertyName === 'width') { this.$_resizeHandler() } }, initListener() { this.$_resizeHandler = debounce(() => { this.resize() }, 100) window.addEventListener('resize', this.$_resizeHandler) this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) }, destroyListener() { window.removeEventListener('resize', this.$_resizeHandler) this.$_resizeHandler = null this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) }, resize() { const { chart } = this chart && chart.resize() } } }
3、防抖函数
/** * @param {Function} func * @param {number} wait * @param {boolean} immediate * @return {*} */ export function debounce(func, wait, immediate) { let timeout, args, context, timestamp, result const later = function () { // 据上一次触发时间间隔 const last = +new Date() - timestamp // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait if (last < wait && last > 0) { timeout = setTimeout(later, wait - last) } else { timeout = null // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 if (!immediate) { result = func.apply(context, args) if (!timeout) context = args = null } } }
4、组件使用,如下:
<!-- 产品排行 --> <product-rank-top2 :chartOption="productRankTop2Option" />
5、echart 的配置项
const colorList = [ { offset: 0, color: "#53639F", }, { offset: 1, color: "#1F305D", }, ]; const setBackgroundColor = ({ type = "linear", x = 0, y = 0, x2 = 1, y2 = 1, colorStops = colorList, } = {}) => { return { type, x, y, x2, y2, colorStops, }; }; weekNewBadComplaintOption: { backgroundColor: setBackgroundColor(), title: { text: "新增不良投诉", left: "center", top: 10, textStyle: { color: "#fff", }, }, tooltip: { trigger: "axis", axisPointer: { type: "cross", crossStyle: { color: "#999", }, }, }, grid: { left: "5%", right: "5%", }, dataZoom: [ { type: "slider", show: true, start: 60, end: 100, textStyle: { color: "#fff" }, handleSize: 20, handleStyle: { color: "#fff" }, xAxisIndex: [0], filterMode: "filter" } ], xAxis: { type: "category", data: [], axisLabel: { textStyle: { color: "#fff" }, formatter: (value, index) => { if(index > 25) { return ""; } else { return value; } } }, boundaryGap: false }, yAxis: { type: "value", axisLabel: { color: "#fff", }, }, color: ["#5C9EDB"], series: [ { data: [], type: "bar", barMinWidth: 50, barMaxWidth: 80, label: { show: true, position: "inside", color: "#f00", }, showBackground: true, backgroundStyle: { color: "rgba(180, 180, 180, 0.2)", }, }, ], },