uniapp使用echarts绘制各种图表(附带完整案例)

标签: uniapp  sass  vue.js

由于ucharts不能满足所需图表要求,故使用了echarts
本案例引用至:https://ext.dcloud.net.cn/plugin?id=1668#rating
然后对其进行部分优化,解决安装到自己项目中,echarts引用错误等问题。
正常适配APP和H5
完整案例下载:点击去码云下载

一、在项目中安装echarts插件

项目结构如下: 可以在自己项目里,按如下方式进行安装。
项目结构

1.实现的效果图

功图,这块数据量较大:
功图
柱图、折线图:
柱图

二、代码(这里主要是做简单说明,代码请去码云下载)

0. echarts.min.js文件

代码较大,请去码云下载

1. echarts.vue文件(这是封装好的组件,复制就可以,简单案例无需改动)

若echarts.min.js文件路径要更换,修改lang="renderjs"这个标签引用即可

import echarts from ‘@/components/echarts/echarts.min.js’

<template>
	<view>
		<view class="echarts" :id="option.id" :prop="option" :change:prop="echarts.update" @click="echarts.onClick"></view>
	</view>
</template>

<script>
	export default {
		name: 'Echarts',
		props: {
			option: {
				type: Object,
				required: true
			}
		},
		created() {
			// 设置随机数id
			let t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
			let len = t.length
			let id = ''
			for (let i = 0; i < 32; i++) {
				id += t.charAt(Math.floor(Math.random() * len))
			}
			this.option.id = id
		},
		methods: {
			/**
			 * renderjs内的点击事件,回调到父组件
			 * @param {Object} params
			 */
			onViewClick(params) {
				this.$emit('click', params)
			}
		}
	}
</script>

<script module="echarts" lang="renderjs">
	import echarts from '@/components/echarts/echarts.min.js'
	
	export default {
		data() {
			return {
				chart: null,
				clickData: null // echarts点击事件的值
			}
		},
		mounted() {
			this.init();
		},
		methods: {
			/**
			 * 初始化echarts
			 */
			init() {
				// 根据id初始化图表
				this.chart = echarts.init(document.getElementById(this.option.id))
				this.update(this.option)
				// echarts的点击事件
				this.chart.on('click', params => {
					// 把点击事件的数据缓存下来
					this.clickData = params
				})
			},
			/**
			 * 点击事件,可传递到外部
			 * @param {Object} event
			 * @param {Object} instance
			 */
			onClick(event, instance) {
				if (this.clickData) {
					// 把echarts点击事件相关的值传递到renderjs外
					instance.callMethod('onViewClick', {
						value: this.clickData.data,
						name: this.clickData.name,
						seriesName: this.clickData.seriesName
					})
					// 上次点击数据置空
					this.clickData = null
				}
			},
			/**
			 * 监测数据更新
			 * @param {Object} option
			 */
			update(option) {
				if (this.chart) {
					// 因App端,回调函数无法从renderjs外传递,故在此自定义设置相关回调函数
					if (option) {
						// tooltip
						if (option.tooltip) {
							// 判断是否设置tooltip的位置
							if (option.tooltip.positionStatus) {
								option.tooltip.position = this.tooltipPosition()
							}
							// 判断是否格式化tooltip
							if (option.tooltip.formatterStatus) {
								option.tooltip.formatter = this.tooltipFormatter(option.tooltip.formatterUnit, option.tooltip.formatFloat2, option.tooltip.formatThousands)
							}
						}
					}
					// 设置新的option
					this.chart.setOption(option, option.notMerge)
				}
			},
			/**
			 * 设置tooltip的位置,防止超出画布
			 */
			tooltipPosition() {
				return (point, params, dom, rect, size) => {
					// 其中point为当前鼠标的位置,size中有两个属性:viewSize和contentSize,分别为外层div和tooltip提示框的大小
					let x = point[0]
					let y = point[1]
					let viewWidth = size.viewSize[0]
					let viewHeight = size.viewSize[1]
					let boxWidth = size.contentSize[0]
					let boxHeight = size.contentSize[1]
					let posX = 0 // x坐标位置
					let posY = 0 // y坐标位置
					if (x >= boxWidth) { // 左边放的下
						posX = x - boxWidth - 1
					}
					if (y >= boxHeight) { // 上边放的下
						posY = y - boxHeight - 1
					}
					return [posX, posY]
				}
			},
			/**
			 * tooltip格式化
			 * @param {Object} unit 数值后的单位
			 * @param {Object} formatFloat2 是否保留两位小数
			 * @param {Object} formatThousands 是否添加千分位
			 */
			tooltipFormatter(unit, formatFloat2, formatThousands) {
				return params => {
					let result = ''
					unit = unit ? unit : ''
					for (let i in params) {
						if (i == 0) {
							result += params[i].axisValueLabel
						}
						let value = '--'
						if (params[i].data !== null) {
							value = params[i].data
							// 保留两位小数
							if (formatFloat2) {
								value = this.formatFloat2(value)
							}
							// 添加千分位
							if (formatThousands) {
								value = this.formatThousands(value)
							}
						}
						// #ifdef H5
						result += '\n' + params[i].seriesName + ':' + value + ' ' + unit
						// #endif
						
						// #ifdef APP-PLUS
						result += '<br/>' + params[i].marker + params[i].seriesName + ':' + value + ' ' + unit
						// #endif
					}
					return result
				}
			},
			/**
			 * 保留两位小数
			 * @param {Object} value
			 */
			formatFloat2(value) {
				let temp = Math.round(parseFloat(value) * 100) / 100
				let xsd = temp.toString().split('.')
				if (xsd.length === 1) {
					temp = (isNaN(temp) ? '0' : temp.toString()) + '.00'
					return temp
				}
				if (xsd.length > 1) {
					if (xsd[1].length < 2) {
						temp = temp.toString() + '0'
					}
					return temp
				}
			},
			/**
			 * 添加千分位
			 * @param {Object} value
			 */
			formatThousands(value) {
				if (value === undefined || value === null) {
					value = ''
				}
				if (!isNaN(value)) {
					value = value + ''
				}
				let re = /\d{1,3}(?=(\d{3})+$)/g
				let n1 = value.replace(/^(\d+)((\.\d+)?)$/, function(s, s1, s2) {
					return s1.replace(re, '$&,') + s2
				})
				return n1
			}
		}
	}
</script>

<style lang="scss" scoped>
	.echarts {
		width: 100%;
		height: 100%;
	}
</style>
2. index.vue页面(数据均已内置)
<template>
	<view>
		<echarts :option="option" style="height: 300px;" @click="echartsClick"></echarts>
		<button @click="updateClick">切换数据</button>
	</view>
</template>

<script>
	import echarts from '@/components/echarts/echarts.vue'
	export default {
		data() {
			return {
				option: {},
				option2: {
					notMerge: true, // 自定义变量:true代表不合并数据,比如从折线图变为柱形图则需设置为true;false或不写代表合并
					tooltip: {
						trigger: 'axis',
						positionStatus: true,
						formatterStatus: false, // 自定义变量:是否格式化tooltip,设置为false时下面三项均不起作用
						formatterUnit: '元', // 自定义变量:数值后面的单位
						formatFloat2: true, // 自定义变量:是否格式化为两位小数
						formatThousands: true // 自定义变量:是否添加千分位
					},
					legend: {
						data: ['', '']
					},
					grid: {
						left: '8%',
						right: '8%',
						bottom: '8%',
						containLabel: true
					},
					xAxis: [{
						name: '位移(m)',
						nameLocation: 'middle', //轴位置
						nameGap: 26, //name名字与轴线间距
						type: 'value',
						axisLine: {
							onZero: false
						}
					}],
					yAxis: [{
						name: '载荷(KN)',
						nameLocation: 'middle', //轴位置
						nameGap: 26, //name名字与轴线间距
						type: 'value',
						axisLine: {
							onZero: false
						}
					}],
					series: [{
						id: 'a',
						type: 'line',
						smooth: true,
						symbolSize: 0,
						data: [
							[11.26, 44.8],
							[11.94, 44.52],
							[12.64, 44.31],
							[13.34, 44.26],
							[14.04, 44.36],
							[14.76, 44.51],
							[15.46, 44.71],
							[16.2, 44.84],
							[16.92, 44.92],
							[17.64, 44.85],
							[18.38, 44.69],
							[19.1, 44.46],
							[19.84, 44.21],
							[20.56, 44.06],
							[21.28, 43.99],
							[22, 44.03],
							[22.72, 44.14],
							[23.46, 44.27],
							[24.16, 44.36],
							[24.88, 44.38],
							[25.58, 44.31],
							[26.28, 44.2],
							[26.98, 44.07],
							[27.68, 43.97],
							[28.36, 43.91],
							[29.04, 43.89],
							[29.72, 43.94],
							[30.38, 44.02],
							[31.04, 44.13],
							[31.68, 44.22],
							[32.34, 44.26],
							[32.98, 44.28],
							[33.6, 44.26],
							[34.22, 44.24],
							[34.84, 44.19],
							[35.44, 44.19],
							[36.04, 44.18],
						]
					}]
				},
				option3: {
					notMerge: true, // 自定义变量:true代表不合并数据,比如从折线图变为柱形图则需设置为true;false或不写代表合并
					xAxis: {
						type: 'category',
						data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
					},
					yAxis: {
						type: 'value'
					},
					series: [{
						data: [120, 200, 150, 80, 70, 110, 130],
						type: 'bar',
						showBackground: true,
						backgroundStyle: {
							color: 'rgba(220, 220, 220, 0.8)'
						}
					}]
				}
			};
		},
		components: {
			echarts
		},
		onLoad() {
			this.option = this.option2
		},
		methods: {
			/**
			 * 点击事件
			 * @param {Object} params
			 */
			echartsClick(params) {
				console.log('点击数据', params)
			},
			/**
			 * 切换数据
			 */
			updateClick() {
				if (this.option === this.option2) {
					this.option = this.option3
				} else {
					this.option = this.option2
				}
			}
		}
	};
</script>

<style></style>

3. page.json中添加页面配置
{
	"pages": [
		{
			"path": "pages/index",
			"style": {
				"navigationBarTitleText": "echarts-renderjs"
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	}
}
版权声明:本文为weixin_46752896原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_46752896/article/details/107844214

智能推荐

使用 ECharts 在网页上绘制图表

为什么80%的码农都做不了架构师?>>>    ECharts 是一个纯 Javascript 的图表库。用到博客里还是很酷炫的。 式例 main 是一个 div 的容器,ECharts 会将图表内容填充在这个容器中。 通过  var myChart = echarts.init(document.getElementById('main')) 指定容器进行填...

Linux信号及工作原理

  什么是信号     信号可以理解为软件中断,是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是差不多的。信号是异步的,一个进程不必通过任何操作来等待信号的到达。信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。   谁来产生信号 信号事件的发生有两个...

手机端图片放大,双指放大,元素的双指缩放

在做webapp时候,遇到一个需要做双指放大的功能,需求是:一张带有坐标的图片上有固定的点,需要点击这些坐标上的点进入相应的商品,并且需要对这一块进行双指可以缩放,双击缩放; 一开始是自己写监听touch事件进行处理,但是再缩放的时候,偶尔出现卡顿闪烁,用户体验不很好,后来采用插件 pinch-zoom GitHub地址: https://github.com/manuelstofer/...

leetcode 剑指offer 54 二叉搜索树的第k大节点

第 K 大节点即反中序遍历大第 K 个数。...

redis 初步了解

1.连接redis 通过java操作 1.首先 导入redis驱动 2.连接redis通过jedis 2.创建redis连接池 连接redis通过 jedis 相当于HTTPclient 1.创建单例模式的方法 在调用的时候被创建 2.创建私有静态 jedisPool 3. 创建私有类 创建静态代码块 放入连接池的基本配置 4.有 最大连接数 最大空闲书 最小空闲连接数 5. 创建连接redis对...

猜你喜欢

第6章数据类型-基本数据类型-Boolean类型-main

防采集标记:亢少军老师的课程和资料 Dart交流群:1046954554 Flutter开源项目请关注: https://github.com/kangshaojun @作者: 亢少军 '...

使用 Infura 和 web3.js 呼叫合约

如果你希望马上开始学习以太坊DApp开发,可以访问汇智网提供的出色的在线互动教程: 以太坊DApp实战入门教程 以太坊去中心化电商应用开发实战 如果你希望了解如何部署合约,可以查看另一篇文章:在truffle中使用infura部署以太坊智能合约。 Infura 提供公开的 Ethereum 主网和测试网络节点。到 Infura 官网申请,只要输入一点基本资料和 Email,就可以收到 API-ke...

手写RPC通信框架

RPC基本介绍 服务器端构建 API包下主体编写 首先初始采用Socket进行通信利用IO进行数据交互,对客户端要提供API调用接口,使得客户端可以利用API中提供的接口,获得服务器端的数据。服务器端模块目录如下: 先编写一个接口,该接口放置在api模块下,实现类放置在provider模块下,这样做目的是让客户端仅加载API包的条件下,可以调用服务器端的实现类完成具体业务逻辑。 服务器端需要客户端...

Highcharts饼状图Ajax动态赋值的问题

这种饼状图是动态的当鼠标放上面那一部分会突出的 Highcharts下载:点击下载 Highcharts-zh_CN.js下载:点击下载 效果图: 前台js代码: 控制层代码: 其中用到两种传值方式一种JSON另一种用Map传值给Ajax,下面为取到的值。 两个饼状图并列展示前台代码: 给饼状图赋值主要就是取json拼接成 data:[[name,y],[name,y]]这样的数组 注意y后面的数...

Qt工程Windows下的安装包制作

工具 Depends.exe nisedit2.0.3.exe nsis-2.50-setup.exe 先安装nsis-2.50-setup.exe, 在安装nisedit2.0.3.exe. 都按默认安装即可. Depends.exe不需要安装. 步骤 1, 在工程中的main()函数里添加如下代码解决库路径问题. 2, 在工程文件.pro中添加如下内容, 其中”DESTDIR=in...