123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- <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 './echarts.min.js'
- // import * as echarts from 'echarts'
- 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: 95vw;
- height: 100%;
- // width: 700rpx;
- height: 500rpx;
- }
- </style>
|