echart引入和组件封装

图表组件(Echarts)封装

一.依赖

echarts官网:Apache Echarts

常用的echarts网站:

PPChart:http://ppchart.com/

Make A Pie:https://madeapie.com/

Isqqw:https://www.isqqw.com/

echarts官网示例:https://echarts.apache.org/examples/zh/index.html#chart-type-bar

1.安装

//echarts插件
npm install echarts --save

//3D地图插件
npm install echarts-gl --save   

//水球插件
npm install echarts-liquidfill --save

2.版本

echarts 、echarts-gl、echarts-liquidfill版本需要对应起来,不然会报错

echarts 4.0
“echarts”: “^4.9.0”, 
“echarts-gl”: “^1.1.2”,
"echarts-liquidfill": "2.0.6",
echarts 5.0
"echarts": "5.4.0",
"echarts-gl": "^2.0.8",
"echarts-liquidfill": "3.0.0",

二.封装Char组件

1.Chart 组件

chart.vue

<template>
	<div :id="id" :class="className" :style="{ height: height, width: width }" />
</template>

<script>
import * as echarts from "echarts"; //引入echarts5
// import Echarts from 'echarts' //引入echarts4
import "echarts-gl"; //引入echarts-gl,3D地图插件
import "echarts-liquidfill"; // 水球插件
import { graphic } from "echarts"; //引入graphic
require("echarts/theme/macarons"); // echarts主题
import resize from "./mixins/resize"; //重绘图表函数并自适应
export default {
	name: "Echart",
	mixins: [resize],
	props: {
		// class名
		className: {
			type: String,
			default: "chart",
		},
		// id,自定义 且必须唯一,不能重复
		id: {
			type: String,
			default: "chart",
		},
		// 图表宽度
		width: {
			type: String,
			default: "100%",
		},
		// 图标高度
		height: {
			type: String,
			default: "100%",
		},
		// 传入的数据
		options: {
			type: Object,
			// required: true,
			default: () => ({}),
		},
	},
	data() {
		return {
			chart: null, //chart实列
		};
	},
	//监听图表数据时候变化,重新渲染图表
	watch: {
		options: {
			handler(val) {
				// 存在chart时,对chart重绘
				if (this.chart) {
					this.chart.setOption(val, true);
				}
			},
			deep: true,
		},
	},
	mounted() {
		// 初始化chart
		this.$nextTick(() => {
			this.initChart();
		});
	},
	//页面销毁前,销毁事件和实例
	beforeDestroy() {
		if (!this.chart) {
			return;
		}
		this.chart.dispose();
		this.chart = null;
	},
	methods: {
		/**
		 * @description 初始化chart
		 */
		initChart() {
			if (this.chart) {
				this.chart.dispose();
			}
			this.$nextTick(() => {
				setTimeout(() => {
					//使用 macarons 主题
					//配置为 svg 形式,预防页面缩放而出现模糊问题;图表过于复杂时建议使用 Canvas
					this.chart = echarts.init(this.$el, "macarons", { renderer: "svg" });
					this.chart.setOption(this.options, true);
				}, 200);
			});
		},
	},
};
</script>

<style></style>

2.resize.js

import { debounce } from '@/utils' // 引入防抖函数

export default {
	data() {
		return {
			$_sidebarElm: null,
			$_resizeHandler: null
		}
	},
	mounted() {
		this.initListener()
	},
	activated() {
		if (!this.$_resizeHandler) {
			// 避免重复 init
			this.initListener()
		}
		// 防止 keep-alive 之后图表变形
		// 当 keep-alive 图表激活时,自动调整大小
		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()
			}
		},
		/**
		 * @description 自适应不同屏幕时改变图表尺寸
		 */
		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)
		},
		/**
		 * @description 销毁事件和实例
		 */
		destroyListener() {
			window.removeEventListener('resize', this.$_resizeHandler)
			this.$_resizeHandler = null

			this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
		},
		/**
		 * @description 重绘图表函数
		 */
		resize() {
			const { chart } = this
			chart && chart.resize()
		}
	}
}

3.防抖


/**
 * @description 防抖函数
 * @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
			}
		}
	}

	return function (...args) {
		context = this
		timestamp = +new Date()
		const callNow = immediate && !timeout
		// 如果延时不存在,重新设定延时
		if (!timeout) timeout = setTimeout(later, wait)
		if (callNow) {
			result = func.apply(context, args)
			context = args = null
		}

		return result
	}
}

三.chart组件使用

<template>
	<div class="echarts-box" style="width: 100%; height: 100%">
		<Echart :options="options" id="barChart1"></Echart>
	</div>
</template>

<script>
import { graphic } from "echarts";

export default {
	data() {
		return {
			options: {},
		};
	},
	mounted() {
		this.init();
	},
	methods: {
		init() {
            //柱状图
			this.options = {
				backgroundColor: "#03213D",
				tooltip: {
					trigger: "axis",
					backgroundColor: "rgba(0,0,0,.6)",
					borderColor: "rgba(147, 235, 248, 0)",
					textStyle: {
						color: "#FFF",
					}, 
				},
				grid: {
					left: "10%",
					top: "5%",
					right: "5%",
					bottom: "15%",
				},
				xAxis: {
					data: [
						"宜宾第五初级中学",
						"王场初级中学",
						"商周镇小学",
						"凉水井中学",
						"正兴中学",
						"文昌中学",
						"富加中学",
					],
					axisLine: {
						show: true, //隐藏X轴轴线
						lineStyle: {
							color: "#163a5f",
							width: 2,
						},
					},
					axisTick: {
						show: false, //隐藏X轴刻度
						alignWithLabel: true,
					},
					axisLabel: {
						show: true,
						color: "#ddd", //X轴文字颜色
						fontSize: 12,
						interval: 0,
						formatter: function (value) {
							var ret = ""; //拼接加\n返回的类目项
							var maxLength = 4; //每项显示文字个数
							var valLength = value.length; //X轴类目项的文字个数
							var rowN = Math.ceil(valLength / maxLength); //类目项需要换行的行数
							if (rowN > 1) {
								//如果类目项的文字大于5,
								for (var i = 0; i < rowN; i++) {
									var temp = ""; //每次截取的字符串
									var start = i * maxLength; //开始截取的位置
									var end = start + maxLength; //结束截取的位置
									//这里也可以加一个是否是最后一行的判断,但是不加也没有影响,那就不加吧
									temp = value.substring(start, end) + "\n";
									ret += temp; //凭借最终的字符串
								}
								return ret;
							} else {
								return value;
							}
						},
					},
				},
				yAxis: [
					{
						splitArea: { show: false },
						type: "value",
						name: "",
						nameTextStyle: {
							color: "#ddd",
							fontSize: 12,
						},

						splitLine: {
							show: false,
							lineStyle: {
								color: "rgba(255, 255, 255, 0.15)",
								// type: 'dashed', // dotted 虚线
							},
						},
						axisTick: {
							show: false,
						},
						axisLine: {
							show: true, //隐藏X轴轴线
							lineStyle: {
								color: "#163a5f",
								width: 1,
							},
						},
						axisLabel: {
							show: true,
							color: "#ddd",
							fontSize: 12,
						},
					},
					{
						type: "value",
						splitArea: { show: false },
						name: "",
						nameTextStyle: {
							color: "#ddd",
							fontSize: 12,
						},
						splitLine: {
							show: false,
							lineStyle: {
								width: 1,
								color: "#CED2DB",
							},
						},
						axisTick: {
							show: false,
						},
						axisLine: {
							show: false, //隐藏X轴轴线
							lineStyle: {
								color: "#163a5f",
								width: 2,
							},
						},
						axisLabel: {
							show: false,
							color: "#797A7F",
							fontSize: 12,
						},
					},
				],
				series: [
					{
						name: "下载数",
						type: "bar",
						barWidth: 15,
						itemStyle: {
							// color: new graphic.LinearGradient(0, 0, 0, 1, [
							//    {
							//       offset: 0,
							//       color: "#00A2FF",
							//    },
							//    {
							//       offset: 1,
							//       color: "#00CCD2",
							//    },
							// ]),
							color: {
								type: "linear",
								x: 0, //右
								y: 0, //下
								x2: 0, //左
								y2: 1, //上
								colorStops: [
									{
										offset: 0.1,
										color: "#13D5FC", // 0% 处的颜色
									},
									{
										offset: 1,
										color: "#2059B8", // 100% 处的颜色
									},
								],
							},
							borderRadius: [20, 20, 20, 20],
						},
						label: {
							show: true,
							position: "top",
							distance: 0,
							color: "#1ACDDC",
							formatter: "{c}" + "次",
						},
						data: [63, 99, 65, 85, 75, 78, 55],
					},
					{
						// name: '背景',
						type: "bar",
						barWidth: "15px",
						xAxisIndex: 0,
						yAxisIndex: 1,
						barGap: "-110%",
						data: [100, 100, 100, 100, 100, 100, 100], //背景阴影长度
						itemStyle: {
							color: "rgba(255,255,255,0.039)",
							borderRadius: [20, 20, 20, 20],
						},
						tooltip: {
							show: false,
						},
						zlevel: 9,
					},
				],
			};
		},
	},
};
</script>

<style lang="scss" scoped></style>
  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值