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上效果如下:
好的,希望可以给需要的朋友一点帮助。