Uniapp项目中使用echarts图表

1.新建组件

 其中echarts.vue代码如下,复制粘贴即可:

<template>
	<view>
		<view class="echarts" :prop="option" :change:prop="echarts.update"></view>
	</view>
</template>
 
<script>
	export default {
		name: 'Echarts',
		props: {
			option: {
				type: Object,
				required: true
			}
		}
	}
</script>
 
<script module="echarts" lang="renderjs">
	export default {
		data() {
			return {
				chart: null
			}
		},
		mounted() {
			if (typeof window.echarts === 'object') {
				this.init()
			} else {
				// 动态引入类库
				const script = document.createElement('script')
				script.src = './static/echarts.min.js'
				// script.src = './static/echarts/echarts.min.js'
				script.onload = this.init
				document.head.appendChild(script)
			}
		},
		methods: {
			/**
			 * 初始化echarts
			 */
			init() {
				this.chart = echarts.init(this.$el)
				this.update(this.option)
			},
			/**
			 * 监测数据更新
			 * @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 = 5
					} else { //左边放的下
						posX = x - boxWidth
					}
					if (y < boxHeight) { //上边放不开
						posY = 5
					} else { //上边放得下
						posY = y - boxHeight
					}
					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.下载echarts.min.js

        在echarts官网(ECharts 在线构建)定制下载,柱状图,折线图,饼图基本能够满足使用。下载完成后放在项目static目录下使用即可。

3.main.js中注册全局组件

import echarts from './components/echarts/echarts.vue'
//注册全局组件
Vue.component('echarts',echarts)

4.页面中使用

        项目情形是在几个不同vue页面中调用后台接口获取数据,在tabbar页面上点击某处实现内容切换,所以index页面继续使用组件,目录结构如下:

        index页面中可以按照具体项目动态显示,这里有一个坑,必须要使用v-if控制内容的切换,而不能使用v-show,使用v-show在切换组件时,echarts图表会缩成一团,使用v-if则不会。

         在index页面中methods定义方法getList,在onShow方法中调用,其中各个组件内的获取后端数据的方法就是下面的getRepair(具体名称自己修改,但是要统一):

getList(){
	this.$nextTick(()=>{
		this.$refs[this.type].getRepair();
    })
},

 5.组件示例

 在data中定义变量,methods中定义方法,最后调用,更改具体数据:

option:{},
option2:{},
//表格数据
sectionRepairTable: null,
//饼图数据
sectionRepairStatistics: null,
//第二张饼图数据
sectionRepairStatistics2: null,
drawLines() {
				let XData = []
				let seriesData = []
				let finishData = []
				for (let i = 0; i < this.sectionRepairStatistics.length; i++) {
				  XData.push(this.sectionRepairStatistics[i].month + '月')
				  seriesData.push(Number(this.sectionRepairStatistics[i].num))
				  finishData.push(Number(this.sectionRepairStatistics[i].finishNum))
				}
				this.seriesData = seriesData
				let option = {
				  title: {
				    text: '报修量/完成量'
				  },
				  tooltip: {
				    trigger: 'axis',
				    axisPointer: {
				      type: 'shadow'
				    }
				  },
				  legend: {
				    //   指示框名字  注意!要和下方series中的name一起改
				    data: ['报修量', '完成量'],
				    // 指示框位置  距离上下左右多少
				    right: '5%',
				    // top: '50%',
				    textStyle: {
				      color: '#4F4F4F' //字体颜色
				    }
				  },
				  grid: {
				    left: '3%',
				    right: '4%',
				    bottom: '3%',
				    containLabel: true
				  },
				  xAxis: [{
				    type: 'category',
				    data: XData,
				    axisTick: {
				      alignWithLabel: true
				    },
					axisLabel:{
						interval:0,
						rotate:45
					}
				  }],
				  yAxis: [{
				    type: 'value'
				  }],
				  series: [{
				    barWidth: 10, //柱子宽度
				    name: '报修量',
				    type: 'bar',
				    // barWidth: '60%',
				    data: seriesData,
				    itemStyle: {
				      //颜色样式部分
				      normal: {
				        barBorderRadius: [20, 20, 0, 0], //圆角[上左,上右,下右,下左]
				      }
				    }
				  },{
				    barWidth: 10, //柱子宽度
				    name: '完成量',
				    type: 'bar',
				    // barWidth: '60%',
				    data: finishData,
				    itemStyle: {
				      //颜色样式部分
				      normal: {
				        barBorderRadius: [20, 20, 0, 0], //圆角[上左,上右,下右,下左]
				      }
				    }
				  }]
				}
				this.option = option
				
				window.addEventListener('resize', () => {
					this.myChart.resize()
				});
				
			},

最终在app上效果如下:

 好的,希望可以给需要的朋友一点帮助。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值