效果图:
1.1renderjs引入echarts
组件zmui-echarts.vue:
html
<template>
<view class="zmui-echarts" :prop="option" :change:prop="echarts.delay"></view>
</template>
<script>
export default {
name: 'zmuiEcharts',
props: {
option: {
type: Object,
required: true
}
}
}
</script>
//使用renderjs 就让app拥有类似有.HTML文件的环境 能直接挂载.js的能力
<script module="echarts" lang="renderjs">
export default {
data() {
return {
timeoutId: null,
chart: null
}
},
mounted() {
if (typeof window.echarts === 'object') {
this.init()
} else {
// 动态引入类库
const script = document.createElement('script') //创建个标签
script.src = './static/echarts.min.js' //引入echarts.min.js
script.onload = this.init
document.head.appendChild(script) //全局挂载echarts.min.js
}
},
methods: {
/**
* 初始化echarts
*/
init() {
// 根据id初始化图表
this.chart = echarts.init(this.$el)
this.update(this.option)
},
/**
* 防抖函数,500毫秒内只运行最后一次的方法
* @param {Object} option
*/
delay(option) {
if (this.timeoutId) {
clearTimeout(this.timeoutId)
this.timeoutId = null
}
this.timeoutId = setTimeout(() => {
this.update(option)
}, 500)
},
/**
* 监测数据更新
* @param {Object} option
*/
update(option) {
console.log('option', 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)
}
}
// legend
if (option.legend) {
console.log('option.legend', option.legend)
if (Object.prototype.toString.call(option.legend) == '[object Array]') {
for (let i in option.legend) {
if (option.legend[i].formatterStatus) {
option.legend[i].formatter = this.legendFormatter(option.legend[i].formatterType, option.legend[i].formatterArr)
}
}
console.log(12)
} else {
if (option.legend.formatterStatus) {
console.log(56)
// option.legend.formatter = this.legendFormatter(option.legend.formatterType, option.legend.formatterArr)
// option.legend.formatter = function(value) {
// return '1'
// }
}
console.log(34)
}
}
// y轴
if (option.yAxis) {
if (option.yAxis.axisLabel) {
if (option.yAxis.axisLabel.formatterStatus) {
option.yAxis.axisLabel.formatter = this.yAxisFormatter(option.yAxis.axisLabel.formatterData)
}
}
if (option.yAxis[0].axisLabel.water) {
let currentChooseName = option.yAxis[0].axisLabel.water.currentChooseName
let name = option.yAxis[0].axisLabel.water.name
console.log('name========>', name,currentChooseName)
option.yAxis[0].axisLabel.formatter = function(value) {
let level = null
if (currentChooseName == '西铝饮用水' || currentChooseName == '和尚山') {
if (name == 'CODMn') {
switch (value) {
case 2:
level = 2.0;
break;
case 4:
level = 4.0;
break;
case 6:
level = 6.0;
break;
case 10:
level = 10.0;
break;
}
return level;
}else if (name == 'TP') {
switch (value) {
case 0.02:
level = 0.02;
break;
case 0.1:
level = 0.1;
break;
case 0.2:
level = 0.2;
break;
case 0.3:
level = 0.3;
break;
}
return level;
}else if (name == 'DO') {
switch (value) {
case 7.5:
level = 7.5;
break;
case 6:
level = 6.0;
break;
case 5:
level = 5.0;
break;
case 3:
level = 3.0;
break;
}
return level;
}else if (name == 'TN') {
switch (value) {
case 0.2:
level = 0.2;
break;
case 0.5:
level = 0.5;
break;
case 1:
level = 1.0;
break;
case 1.5:
level = 1.5;
break;
}
return level;
} else if (name == 'NH3-N') {
switch (value) {
case 0.15:
level = 0.15;
break;
case 0.5:
level = 0.5;
break;
case 1:
level = 1.0;
break;
case 1.5:
level = 1.5;
break;
}
return level;
}
}else if(currentChooseName !== '西铝饮用水' || currentChooseName !== '和尚山') {
if (name == 'CODMn') {
switch (value) {
case 4:
level = 4.0;
break;
case 6:
level = 6.0;
break;
case 10:
level = 10.0;
break;
case 15:
level = 15.0;
break;
}
return level;
}else if (name == 'TP') {
switch (value) {
case 0.1:
level = 0.1;
break;
case 0.2:
level = 0.2;
break;
case 0.3:
level = 0.3;
break;
case 0.4:
level = 0.4;
break;
}
return level;
} else if (name == 'DO') {
switch (value) {
case 6:
level = 6.0;
break;
case 5:
level = 5.0;
break;
case 3:
level = 3.0;
break;
case 2:
level = 2.0;
break;
}
return level;
}else if (name == 'TN') {
switch (value) {
case 0.5:
level = 0.5;
break;
case 1:
level = 1.0;
break;
case 1.5:
level = 1.5;
break;
case 2:
level = 2.0;
break;
}
return level;
} else if (name == 'NH3-N') {
switch (value) {
case 0.5:
level = 0.5;
break;
case 1:
level = 1.0;
break;
case 1.5:
level = 1.5;
break;
case 2:
level = 2.0;
break;
}
return level;
}
}
}
}
}
// 颜色渐变
if (option.series) {
for (let i in option.series) {
let linearGradient = option.series[i].linearGradient
if (option.series[i].axisLabel && option.series[i].axisLabel.formatterText) {
option.series[i].axisLabel.formatter = function(value) {
if (value === 0) {
return '0 \n 健康';
} else if (value === 1) {
return '50 \n 优';
} else if (value === 2) {
return '100 \n 良';
} else if (value === 3) {
return '150 \n 轻度';
} else if (value === 4) {
return '200 \n 中度';
} else if (value === 5) {
return '300 \n 重度';
} else if (value === 6) {
return '500 \n 严重';
}
}
}
if (linearGradient) {
option.series[i].color = new echarts.graphic.LinearGradient(linearGradient[0], linearGradient[1],
linearGradient[2], linearGradient[3], linearGradient[4])
}
if (option.series[i].itemStyle) {
if (option.series[i].itemStyle.normal) {
if (option.series[i].itemStyle.normal.formatterColor) {
option.series[i].itemStyle.normal.color = this.colorFormatter(option.series[i].itemStyle.normal.formatterType,option.series[i])
}
}
}
if (option.series[i].markLine) {
if (option.series[i].markLine.label) {
if (option.series[i].markLine.label.normal) {
if (option.series[i].markLine.label.normal.formatterLabel) {
option.series[i].markLine.label.normal.formatter = this.labelFormatter(option.series[i].markLine.label.normal
.formatterType, option.series[i].markLine.label.normal.formatterValue)
}
}
}
}
}
}
}
console.log(option)
this.chart.clear() // 这个不要删掉哟,不然切换不同图形的时候会有bug
// 设置新的option
this.chart.setOption(option, option.notMerge)
}
},
waterFormatterYAxis (value) {
/* let name = null
switch (value) {
case 2:
name = 2.0;
break;
case 4:
name = 4.0;
break;
case 6:
name = 6.0;
break;
case 10:
name = 10.0;
break;
} */
console.log('value', value)
// return name;
},
/**
* 设置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 => {
if (Array.isArray(params)) {
var params = params[0]
// #ifdef H5
var result = params.data.fullDate + '/n' + params.seriesName + ":" + params.data.value
// #endif
// #ifdef APP-PLUS
var result = params.data.fullDate + '</br>' + params.seriesName + ":" + params.data.value
// #endif
} else {
// #ifdef H5
var result = params.data.fullDate + '/n' + params.seriesName + ":" + params.data.value
// #endif
// #ifdef APP-PLUS
var result = params.data.fullDate + '</br>' + params.seriesName + ":" + params.data.value
// #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
},
/**
* Y轴格式化
* @param {Object} data
*/
yAxisFormatter(data) {
return params => {
let result = []
for (let i in data) {
if (params == i) {
result.push(data[i])
}
}
return result
}
},
/**
* legend 格式
* @param {Object} Type
* @param {Object} Arr
*/
legendFormatter(Type, Arr) {
console.log('Arr', Arr)
return params => {
let result = ""
var total = 0;
for (var i = 0, l = Arr.length; i < l; i++) {
total += Arr[i].value;
}
let res = Arr.filter(v => v.name === params)
let val = res[0].value
let precent=((val/total)*100).toFixed(2) + '%'
// #ifdef H5
result = params +"("+ val+"件)"
// #endif
// #ifdef APP-PLUS
result = params +"("+ val+"件)"
// #endif
return result
}
},
/**
* 颜色设置
* @param {Object} Type
*/
colorFormatter(Type,series) {
let value =0;
return params => {
//如果series 里面包含aqiData 数据 按AQI 的值来渲染颜色
let value =params.value;
if(series['aqiData']!=null){
value =series['aqiData'][params.dataIndex];
}
let result = ""
if (Type === 'one') {
result = "rgb(126,0,35)"
if (value > 0 && value < 51) {
result = "#00e400"
} else if (value >= 51 && value < 101) {
result = "#ffff00"
} else if (value>= 101 && value < 151) {
result = "#ff7e00"
} else if (value >= 151 && value < 201) {
result = "#ff0000"
} else if (value >= 201 && value < 301) {
result = "#7e0023"
}
}
return result
}
},
/**
* 标记线
* @param {Object} Type
* @param {Object} Value
*/
labelFormatter(Type, Value) {
return params => {
let result = ""
if (Type === 'one') {
result = Value
}
return result
}
},
}
}
</script>
<style scoped>
.zmui-echarts {
width: 100%;
height: 100%;
}
</style>
2.使用<zmuiEcharts :option="echartOptions"></zmuiEcharts>
html
import zmuiEcharts from '@/components/zmui-echarts/zmui-echarts.vue'
components: {
zmuiEcharts
},
<zmuiEcharts :option="echartOptions"></zmuiEcharts>
export default {
data(){
return{
echartOptions: {
backgroundColor: '#ffffff',
title: {
text: 'mg/L',
textStyle: {
fontSize: 12,
fontWeight: 'normal',
color: '#858585', //标题颜色
},
top: 0,
left: '4%',
},
tooltip: {
show: false
// axisPointer: {
// type: "axis",
// textStyle: {
// color: "#000"
// }
// },
// formatter: (data) => {
// // 可以自定义文字和样式,用行内样式,数据包含在data参数中
// let text = ` ${data.name}:${data.value}`
// return text
// }
},
grid: {
top: "5%",
right: "3%",
bottom: '13%',
},
xAxis: [{
data: [],
margin: 20,
interval: 0,
rotate: 40,
color: '#858585',
textStyle: {
fontSize: 12
},
axisLine: {
lineStyle: {
color: '#858585',
}
},
axisTick: {
show: true
},
}],
axisLine: {
show: false,
lineStyle: {
color: '#858585', //y轴颜色
}
},
axisTick: {
show: false
},
splitLine: {
show: false
},
dataZoom: [{
"show": true,
"height": 8,
"xAxisIndex": [
0
],
bottom: '0%',
start: 0,
end: 6,
handleIcon: "M-292,322.2c-3.2,0-6.4-0.6-9.3-1.9c-2.9-1.2-5.4-2.9-7.6-5.1s-3.9-4.8-5.1-7.6c-1.3-3-1.9-6.1-1.9-9.3c0-3.2,0.6-6.4,1.9-9.3c1.2-2.9,2.9-5.4,5.1-7.6s4.8-3.9,7.6-5.1c3-1.3,6.1-1.9,9.3-1.9c3.2,0,6.4,0.6,9.3,1.9c2.9,1.2,5.4,2.9,7.6,5.1s3.9,4.8,5.1,7.6c1.3,3,1.9,6.1,1.9,9.3c0,3.2-0.6,6.4-1.9,9.3c-1.2,2.9-2.9,5.4-5.1,7.6s-4.8,3.9-7.6,5.1C-285.6,321.5-288.8,322.2-292,322.2z",
handleSize: "130%",
handleStyle: {
color: "#fff",
shadowColor: "#B1B5B9",
shadowBlur: 5,
},
backgroundColor: "#DEE3F4",
fillerColor: "#008efe",
endValue: 5,
},
{
"type": "inside",
"show": true,
"height": 15,
"start": 1,
"end": 35
}
],
yAxis: [{
type: 'value',
min: 0,
max: 0,
interval: 0.01,
name: 'nj',
nameTextStyle: {
color: '#ffffff'
},
axisLine: {
show: true
},
axisTick: {
show: false
},
splitLine: {
show: false,
},
axisLabel: {
color: '#858585',
textStyle: {
fontSize: 13
},
formatter: function(value1) {
return value1;
},
water: {
name: 'water',
code: 'code'
},
},
}],
series: [{
label: {
normal: {
show: true,
color: '#333',
position: 'top',
}
},
name: 'nj',
type: 'bar',
data: [],
barWidth: '8px',
itemStyle: {
normal: {
formatterColor: true,
formatterType: "one",
}
},
}]
}
}
}
}