Open bymomo opened 4 years ago
我琢磨了1天了,接近崩溃中...期望得到答复。谢谢!!!
@bymomo 能给我科普下 uni-app 的原理么?微信小程序 ECharts 的实现,本质上就是对微信非标准的 Canvas 接口做了一层兼容。
@bymomo 能给我科普下 uni-app 的原理么?微信小程序 ECharts 的实现,本质上就是对微信非标准的 Canvas 接口做了一层兼容。
目前我也不知道uni-app技术原理,它的api跟微信小程序是一致的。具体你可以看下官网介绍 uniapp官网 目前市面上的跨端开发框架就uni-app和taro比较热门,我看了issues也有人提问uniapp,taro如何使用echarts的,没得到回复。 我觉得只需要编译到微信小程序端,按理来说是应该兼容和可实现的。 最后还是希望能提供下上述的两个框架的示例程序吧,毕竟比较热门。
我没有精力再维护两个额外的框架,如果社区有人感兴趣的话,希望能有人能带头做一下这个事。
我已经将组件和部分示例提交到我的git。
如何在uni-app中使用echarts
希望作者能po个链接到readme上。
taro的 taro-echarts
我已经将组件和部分示例提交到我的git。 如何在uni-app中使用echarts 希望作者能po个链接到readme上。 taro的 taro-echarts
@bymomo 能给我科普下 uni-app 的原理么?微信小程序 ECharts 的实现,本质上就是对微信非标准的 Canvas 接口做了一层兼容。
目前我也不知道uni-app技术原理,它的api跟微信小程序是一致的。具体你可以看下官网介绍 uniapp官网 目前市面上的跨端开发框架就uni-app和taro比较热门,我看了issues也有人提问uniapp,taro如何使用echarts的,没得到回复。 我觉得只需要编译到微信小程序端,按理来说是应该兼容和可实现的。 最后还是希望能提供下上述的两个框架的示例程序吧,毕竟 楼主解决了吗?
我已经将组件和部分示例提交到我的git。 如何在uni-app中使用echarts 希望作者能po个链接到readme上。 taro的 taro-echarts
不支持新版的 taro
我已经将组件和部分示例提交到我的git。 如何在uni-app中使用echarts 希望作者能po个链接到readme上。 taro的 taro-echarts
不支持新版的 taro 试试这个 https://github.com/WsmDyj/echarts-for-taro
我已经将组件和部分示例提交到我的git。 如何在uni-app中使用echarts 希望作者能po个链接到readme上。taro 的taro-echarts
以回调函数为参数无效怎么解决呢?试了很多方式没办法解决
我在用uniapp做小程序也遇到了这个问题,找问题的 issue 和谷歌,都没法解决,初步猜测是 因为document 在 uniapp 中没有定义。
但是不知道问题根源在哪里,所以苦思好几天,后来看到 mpvue-chartsecharts.init
之前有一行 `echarts.setCanvasCreator(() => canvas)`` 发现我没有在 init 之前加这行,加完之后就正常了。
去 echarts 看了源码终于明白了,原来 setCanvasCreator 的作用是是引入 canvas 环境,再触发创建 canvas 的相关方法。证明我之前猜测没有 document 是对的,正好 与报错信息符合。
备注:setCanvasCreator的作用引用9727中Ovilia大佬的话: 它用于类似于HTML Canvas的环境,但并不完全相同
我在用uniapp做小程序也遇到了这个问题,找问题的 issue 和谷歌,都没法解决,初步猜测是 因为document 在 uniapp 中没有定义。
但是不知道问题根源在哪里,所以苦思好几天,后来看到 mpvue-charts
echarts.init
之前有一行 `echarts.setCanvasCreator(() => canvas)`` 发现我没有在 init 之前加这行,加完之后就正常了。去 echarts 看了源码终于明白了,原来 setCanvasCreator 的作用是是引入 canvas 环境,再触发创建 canvas 的相关方法。证明我之前猜测没有 document 是对的,正好 与报错信息符合。
备注:setCanvasCreator的作用引用9727中Ovilia大佬的话: 它用于类似于HTML Canvas的环境,但并不完全相同
听君一席话,少熬一天夜!感谢大佬! 虽然说问题点不一样,但是根源一样,准备洗澡睡觉!
根据前面提到的内容这里整合补充下:
// my.vue
<template>
...
<ec-canvas :ec="{ onInit: initChart }"> </ec-canvas>
...
</template>
<script>
import * as echarts from "@/wxcomponents/ec-canvas/echarts"
var g_chart = null
export default {
...
methods:{
initChart() {
echarts.setCanvasCreator(() => canvas)
const chart = echarts.init(canvas, null, {
width: width,
height: height,
devicePixelRatio: dpr
});
canvas.setChart(chart);
g_chart = chart
return chart
},
myfun() {
g_chart.setOption({...})
}
}
...
}
</script>
uni-app 下 my.vue 和 ec-canvas.js 里
import * as echarts from "..." 导出的 echarts 不是同一个对象.
虽然在ec-canvas.js 组件初始化时已经内部调用setCanvasCreator(()=>{return canvas})
替换掉了 document.createElement ,但是 我们的my.vue 调用echarts不是同一个,
还是会报错,需要显式再调用一次 setCanvasCreator 来替换成微信提供的canvas
问题1
使用 :ec="{onInit: initChart}" 直接传递是可以的, 这个方法我是尝试出来的,
有对组件传值原理比较熟悉的同学可以后面再补充解释下。
问题2 echarts.js 里的报错 "Cannot read property 'createElement' of undefined" 对应的代码段是
// echarts.js
var createCanvas = function () {
return methods.createCanvas();
};
methods.createCanvas = function () {
return document.createElement('canvas'); // 报错的地方
};
...
function setCanvasCreator(creator) {
$override('createCanvas', creator);
}
function $override(name, fn) {
methods[name] = fn;
}
这个函数是用来创建Canvas对象的,echarts 是在这个返回的canvas对象上进行绘图的。 因为小程序里是提供DOM对象(小程序和普通浏览器的区别),所有无法通过 doucment.createElement来创建Canvas对象,于是报错了。
再看下 ec-canvas 组件的初始化代码
// ec-canvas.js InitByNewWaay
const canvas = new WxCanvas(ctx, this.data.canvasId, true, canvasNode)
echarts.setCanvasCreator(() => {
return canvas
})
...
// 这里的onInit 就是我们父组件 :ec="{onInit: initChart}" 传递进来的初始化函数
this.chart = this.data.ec.onInit(canvas, canvasWidth, canvasHeight, canvasDpr)
从代码中可以知道 ec-canvas.js 组件初始化大致流程是:
init()-->initByNewWay()-->echarts.setCanvasCreator()-->initChart()
结合上面 echarts.js 里的 setCanvasCreator, $override 可以看到, 我们的initChart 是在最后面才被调用的, 此时echarts.js 里的 createCanvas 函数应该已经被替换成 ()=>{return canvas}, createCanvas内部实际调用的函数应该是 ()=>{return canvas} 才对啊,怎么还是doucment.createElement? 且整个echart.js 只有setCanvasCreator这个地方对methods.createCanvas这个函数有替换的操作。 难道还有其它运行时bug,把methods.createcanvas给改了, 真奇怪!!!
于是在猜想ec-canvas.js 里访问的 echarts 对象和 我们自己代码里的 initChart 访问的 echarts对象有没可能不是同一个? 两个地方加个万能的log把echarts对象打印出来对比看下差异. 因为js 没有内置方法可以打印对象唯一内存id? 添加一个随机数来标识。 在echarts.js 最后一行把添加两个导出
// echarts.js
exports.env = env;
exports.Model = Model;
exports.Axis = Axis;
exports.innerDrawElementOnCanvas = brushSingle;
exports.Amethods = methods; // 新增导出
exports.Arandomid = Math.random(); // 新增导出
});
ec-canvas.js 组件和我们自己的initChart 函数里添加打印
// ec-canvas.js InitByNewWaay
const canvas = new WxCanvas(ctx, this.data.canvasId, true, canvasNode)
echarts.setCanvasCreator(() => {
return canvas
})
console.log("echarts in ec-canvas.js = ", echarts) // 打印echarts
// my.vue
export default {
methods: {
initChart(canvas, width, height, dpr) {
console.log("echarts in my.vue = ", echarts) // 打印echarts
const chart = echarts.init(canvas, null, {
width: width,
...
}
}
下面是uniapp编译后到微信开发者工具上的输出结果。
可以看到Arandomid 是不一样的, 验证了是两个不同的echarts.
同样的方法对比测试了不使用 unippp, 直接在原生微信小程序上使用ec-canvas 组件,打印结果证明 ec-canvas.js, my.js import 两处导入的 echarts 是同一个, 所以使用时不会报错。
打开uniapp编译my.vue后的my.js, 可以看到my.js 对echarts.js的导入代码是这样的。
var echarts = _interopRequireWildcard(__webpack_require__(/*! @/wxcomponents/ec-canvas/echarts */ 30));
所以下一步猜测是 uniapp把my.vue 编译成my.js时这里_interopRequireWildcard(webpack_require__ 引起的问题,到这里我就没有再找下去了, 有对uniapp或webapck比较熟悉的朋友可以补充下,_interopRequireWildcard(webpack_require__ 和直接 import * as echarts from '' 有什么区别? 或是微信小程序对底层对import作了改动?
https://github.com/xbmlz/echarts-for-uniapp Apache ECharts 的uni-app版本, 支持Vue 2/3.
提问前应该做的事
请确保提问前做了以下事,将完成的项目的
[]
改为[x]
:需提供的信息
将符合项的
[]
改为[x]
,并补充需要的信息:简单描述问题:
echarts-for-weixin示例代码是可以在微信小程序上运行的,但是我使用的是uni-app编译到微信小程序,我目前也只是需要兼容的微信小程序端即可。 但是,根据把示例代码上的代码粘贴下来,无法成功运行。 问题1,绑定到组件ec属性上的对象里面的onInit传function,在组件内部接收不到。
ec: { name: 1, ces: '2', onInit: function() { console.log('回调'); } },
为了解决问题1,我改了ec-canvas.js组件内的js,通过调用父组件办法来调用到了onInit函数,于是产生了问题2:是echarts的setOption办法调用了createElement办法,而小程序上是没dom操作的thirdScriptError Cannot read property 'createElement' of undefined;at SelectorQuery callback function TypeError: Cannot read property 'createElement' of undefined
预期效果:
希望姐姐能提供uni-app使用echarts-for-weixin的示例代码 (如有需要请提供预期的图)
实际效果:
暂无 (如有需要请提供截图)
复现环境: