uniapp中echart (renderjs)的tooltip.formatter失效
uniapp echart renderjs tooltip formatter 失效
·
1、先说原因:renderjs和普通的js不同,如果想在<script module="echarts" lang="renderjs">
获得<script>
中的数据,虽然也是用this,但是这个this中的所有回调函数都会被私有化,读不出来。
2、举例:
<script>
export default {
data(){ // 原始情况是在prop中的,这里直接写在data
return{
option:{
...... // 省略option中其他设定
tooltip:{
...... // 省略tooltip中其他设定
formatter:e=>{console.log('我是formatter函数')}
}
}
}
}
}
</script>
<script module="echarts" lang="renderjs">
export default {
mounted(){
console.log(this.option.tooltip.formatter) //打印出来的是:function () { [native code] }
// 因此在this.chart.setOption的时候,这个设定就失效了
}
}
</script>
3、解决办法
(I)既然renderjs读不到普通js中的内容,在renderjs中写formatter函数即可
<script module="echarts" lang="renderjs">
export default {
mounted(){
this.option.tooltip.formatter=e=>{console.log('我是formatter函数')} // 添加这句,在this.chart.setOption之前重新设定tooltip.formatter
this.chart.setOption(this.option)
}
}
</script>
(II)因为想组件化,只想用一个renderjs统筹管理所有的echart,又想到一个方法:
既然renderjs中不支持从js中接收函数类型。那么,先从js中接收一个字符串,再在renderjs中把这个字符串转换成函数。
函数转换成字符串有tostring方法,字符串转函数没原型链上的方法,查到一个String.prototype.toFunction=function(){ return eval('('+this+')')}; //作者@行列[xxooyy]
,直接绑到原型链或者renderjs中的methord中写一个方法都可以。
4、最终解决以后的代码
文件目录:
———static——echarts.js // echart官网下载的js压缩文件
∟——components——echart.vue // echart组件
∟——index.vue // 主要页面
// index.vue 中的代码
<template>
<view>
<echarts style="{'height': 500px}" :option="option"></echarts>
</view>
</template>
<script>
import echarts from '@/components/echart.vue'
export default {
components:{
echarts
},
data() {
return {
option: { // 删减后,不确定有没有删掉必要的设定
tooltip: {
show: true,
formatterFunction:`function(params) {
return 'asf'
}` // 这里不是formatter,而是formatterFunction,因为echart原有的更新是增量式的,当然如果没更新功能,则用啥都无所谓。(怎么看有无更新:this.chart.setOption(option, option.notMerge)中有无第二个入参)
// 所以这里不如直接当做有更新来处理,万无一失。
// 如果检测formatter的有无,来改变formatter自己,会无限循环。
// 举例:xAxis.data变化,echart.js会构造一个新的option,其内容为option:{xAxis:{data:[xxxxxxx,xxxx,x,x,x,xx,x]}},重新绘图。
// 回到formatter: 检测formatter的有无 -> 改变formatter -> 生成新option{formatter:xxxxxx} -> 检测formatter的有无 -> 改变formatter ......无限循环
// 使用formatterFunction:检测formatterFunction的有无 -> 改变formatter -> 生成新option{formatter:xxxxxx} -> 检测formatterFunction的有无 -> 无 -> 停止
},
xAxis: {
type:'category',
data: ["2022-02-10","2022-02-11","2022-02-12"] // x轴数据
},
yAxis: {
type: 'value',
},
series: [{
type: 'bar',
data: [15,20,25], // y轴数据
}]
},
}
}
</script>
// echart.vue 中的代码
<template>
<view class="echarts" :prop="option" :change:prop="echarts.update"></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.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) {
if (option.tooltip.formatterFunction){
console.log(1111111)
option.tooltip.formatter=this.toFunction(option.tooltip.formatterFunction)
}
}
// 设置新的option
this.chart.setOption(option, option.notMerge)
}
}
},
/**
* 字符串类型转换成函数类型(renderjs不支持函数类型的传递)
* @param {Object} value
*/
toFunction(e){
return eval('('+e+')')
}
}
}
</script>
<style lang="scss" scoped>
.echarts {
width: 100%;
height: 100%;
}
</style>
更多推荐
已为社区贡献7条内容
所有评论(0)