注意需要下载一个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>
页面引用
<template>
<view>
<view class="pr15-pl15">
<echarts :option="option" style="height: 300px;" @click="echartsClick"></echarts>
</view>
</view>
</template>
<script>
import echartsTitle from './components/echarts-title.vue'
let vm = null;
export default {
data() {
return {
option: {
// title: {
// text: '某站点用户访问来源',
// subtext: '纯属虚构',
// left: 'center'
// },
tooltip: {
trigger: 'item'
},
legend: {
orient: 'horizontal',
bottom: '30', //图例位置
textStyle: {
color: "#666666",
fontSize:14
}, //字体颜色
icon: "circle", //图例形状设置
itemWidth: 10, // 设置宽度
itemHeight: 10, // 设置高度
formatter: function(name) {
let data = vm.option.series[0].data;
let tarValue;
let total = data.reduce((count, cur) => {
return count.value + cur.value
})
console.log(total);
for (let i = 0; i < data.length; i++) {
// total += data[i].value;
if (data[i].name == name) {
tarValue = data[i].value;
}
}
let v = tarValue;
let p = Math.round(((tarValue / total) * 100));
return `${name} (${p}%)`
}
},
series: [{
// name: '访问来源',
type: 'pie',
radius: '50%',
center: ['50%', '50%'],
data: [{
value: 321,
name: '包厢',
itemStyle: {
color: 'rgba(90,216,166,.85)'
},
label: {
show: false
},
labelLine: {
show: false
}
}, {
value: 1048,
name: '雅座',
itemStyle: {
color: 'rgba(91,143,249,.85)'
},
label: {
show: false
},
labelLine: {
show: false
}
}],
emphasis: {
itemStyle: {
}
}
}]
},
columns2: [
[
'李四',
'杨颖',
'张三',
'王五'
]
]
};
},
created() {
vm = this
},
methods: {
echartsClick(params) {
console.log('点击数据', params)
},
},
components: {
echarts
}
}
</script>
<style lang="scss" scoped>
</style>