xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

shit uni-app All In One

shit uni-app All In One

  1. 不支持 echarts 获取点击的 series 数据

  2. 垃圾文档 demo

https://ext.dcloud.net.cn/plugin?id=1207

<template>
  <view class="content">
    <!-- #ifdef APP-PLUS || H5 -->
    <view
      @click="echarts.onClick"
      :prop="option"
      :change:prop="echarts.updateEcharts"
      id="echarts"
      class="echarts">
    </view>
    <button @click="changeOption">更新数据</button>
    <!-- #endif -->
    <!-- #ifndef APP-PLUS || H5 -->
    <view>非 APP、H5 环境不支持</view>
    <!-- #endif -->
  </view>
</template>

<script>
  export default {
    data() {
      return {
        option: {
          title: {
            text: 'ECharts 入门示例'
          },
          tooltip: {},
          legend: {
            data: ['销量']
          },
          xAxis: {
            data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
          },
          yAxis: {},
          series: [{
            name: '销量',
            type: 'bar',
            data: [5, 20, 36, 10, 10, 20]
          }]
        }
      }
    },
    onLoad() {

    },
    methods: {
      changeOption() {
        const data = this.option.series[0].data
        // 随机更新示例数据
        data.forEach((item, index) => {
          data.splice(index, 1, Math.random() * 40)
        })
      },
      onViewClick(options) {
        console.log(options)
      }
    }
  }
</script>

<script module="echarts" lang="renderjs">
  let myChart
  export default {
    mounted() {
      if (typeof window.echarts === 'function') {
        this.initEcharts()
      } else {
        // 动态引入较大类库避免影响页面展示
        const script = document.createElement('script')
        // view 层的页面运行在 www 根目录,其相对路径相对于 www 计算
        script.src = 'static/echarts.js'
        script.onload = this.initEcharts.bind(this)
        document.head.appendChild(script)
      }
    },
    methods: {
      initEcharts() {
        myChart = echarts.init(document.getElementById('echarts'))
        // 观测更新的数据在 view 层可以直接访问到
        myChart.setOption(this.option)
      },
      updateEcharts(newValue, oldValue, ownerInstance, instance) {
        // 监听 service 层数据变更
        myChart.setOption(newValue)
      },
      onClick(event, ownerInstance) {
        // 调用 service 层的方法 ??? 💩 WTF 
        // 如何获取点击的 series 数据 ❓
        let index = 0;
        const series = this.option.series[index];
        ownerInstance.callMethod('onViewClick', series);
        // ownerInstance.callMethod('onViewClick', {
        //   test: 'test'
        // });
      }
    }
  }
</script>

<style>
  .content {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .echarts {
    margin-top: 100px;
    width: 100%;
    height: 300px;
  }
</style>



    initEcharts() {
        console.log('this.$ownerInstance', this.$ownerInstance);
        this.sendChartId(this.$ownerInstance);
        setTimeout(() => {
            this.myChart = echarts.init(document.getElementById(`echarts-${this.chartId}`));
            // 观测更新的数据在 view 层可以直接访问到
            console.log('this.myChart', this.myChart);
            this.myChart.setOption(this.options);
            this.myChart.on('click', 'series', function (params) {
                console.log('params', params, params.name);
            });
            // echarts的点击事件
            this.myChart.on('click', function (params) {
                console.log('params', params, params.name, e);
            });
            // this.myChart.on('click', params => {
            //     console.log('click params', params, params.name, params.componentType);
            //     // 把点击事件的数据缓存下来
            //     // this.clickData = params;
            // });
        }, 200);
    },


https://github.com/dcloudio/uni-app

https://github.com/dcloudio/uni-app/issues?q=echarts

Q & A

https://blog.csdn.net/weixin_41612150/article/details/109624440

https://ask.dcloud.net.cn/question/99777?notification_id-826356rf-falseitem_id-144275#!answer_144275

solution 🚀 OK

import echarts

uni-app 里面使用 echarts 获取点击的 series 数据


<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) {
				console.log('2 viewclick', 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 => {
					// 把点击事件的数据缓存下来
				    console.log('0 clickData', params);
                    // componentIndex
                    // componentSubType
                    // componentType
                    // echarts.vue:25 Uncaught TypeError: Converting circular structure to JSON at JSON.stringify (<anonymous>)
				    // console.log(JSON.stringify(params));
					this.clickData = params;
				})
			},
			/**
			 * 点击事件,可传递到外部
			 * @param {Object} event
			 * @param {Object} instance
			 */
			onClick(event, instance) {
				console.log('1 click');
				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>

refs

https://uniapp.dcloud.io/frame?id=renderjs

https://uniapp.dcloud.io/component/canvas



©xgqfrms 2012-2020

www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2021-04-17 22:10  xgqfrms  阅读(124)  评论(7编辑  收藏  举报