时间:2021-07-01 10:21:17 帮助过:55人阅读
最近群里有几个人问,如何把echarts的图表贴在three.js的模型上。这个问题其实很简单,因为二者都是渲染成canvas的,直接用echarts生成的canvas当作贴图就可以了。
方法确定可行,那么我们就直接开始撸代码。
先搭建一个three的基本场景起来,这里不在复述。
然后新建一个平面,我们把图片贴在这个平面上即可。
【相关课程推荐:JavaScript视频教程】
- addPlane() {
- var geometry = new THREE.PlaneGeometry(10,10);
- var material = new THREE.MeshBasicMaterial({
- side: THREE.DoubleSide,
- // transparent:true
- });
- this.plane = new THREE.Mesh(geometry, material);
- this.scene.add(this.plane);
- }
摆好相机的角度,此时场景中是一个白板。
然后打开echarts的官网,找到案例,来个仪表盘吧。代码拷贝下来。跑起来。
为了方便演示,我在body中创建了2个div,分别作为three和图表的容器。实际开发中图表的容器不需要显示出来的,也不需要添加到body中的。
- <div id="webgl" style="width:512px;height: 512px;float: left;"></div>
- <div id="echart" style="width:512px;height: 512px;margin-left: 620px;"></div>
- var myChart = echarts.init(document.getElementById('echart'));
- option = {
- tooltip: {
- formatter: "{a} <br/>{b} : {c}%"
- },
- //toolbox会在右上角生成两个功能按钮,咱们不需要,直接干掉。
- // toolbox: {
- // feature: {
- // restore: {},
- // saveAsImage: {}
- // }
- // },
- series: [
- {
- name: '业务指标',
- type: 'gauge',
- detail: { formatter: '{value}%' },
- data: [{ value: 50, name: '完成率' }]
- }
- ]
- };
- option.series[0].data[0].value = (Math.random() * 100).toFixed(2) - 0;
- myChart.setOption(option, true);
- const dom = document.getElementById("webgl");
- const scene = new Basescene(dom);
- scene.addPlane();
此时看到下面页面:
方法一:CanvasTexture
three.js有一个api:CanvasTexture。可以传入一个canvas对象,用这个方法可以完成上面的任务。
CanvasTexture( canvas : HTMLElement, mapping : Constant, wrapS : Constant, wrapT : Constant, magFilter : Constant, minFilter : Constant, format : Constant, type : Constant, anisotropy : Number )
- changeTextureT(texture){
- this.plane.material.map = new THREE.CanvasTexture(texture)
- this.plane.material.needsUpdate = true
- var thiscancas = document.getElementById("echart").getElementsByTagName('canvas')[0]
- scene.changeTextureT(thiscancas)
- }
运行结果如下,确实不清晰,和他们遇到的问题的一样。尝试把echarts绘制大点,但是这个是自适应的,导致仪表板很丑,不是想象的样子,如果是自己绘制的表格,就可以这样处理了。
方法二:getDataURL
既然echarts也是渲染canvas,看看api,应该有方法导出图片。就是下面的api,而且有可选参数,可以设置分辨率。
- changeTextureE(texture){
- this.plane.material.map = new THREE.TextureLoader().load(texture)
- this.plane.material.needsUpdate = true
- }
- var texture = myChart.getDataURL({
- pixelRatio: 4,
- backgroundColor: '#fff'
- });
- scene.changeTextureE(texture)
分辨率设置为4确实清晰多了。
下面三个图分别是分辨率1,分辨率4以及方法1绘制的效果对比。
3个图区别很明显,方法2>方法1。该使用什么方法已经很明白了。
下面是动态图片,开始没有贴图,然后贴上方法1生成的贴图,接着闪一下,换成方法2分辨率4生成的贴图。放大还是很清晰的。
最后问题:echarts的图表很多都是有缓冲动画的,如果也想在贴图上实时刷新,可行吗。帧率能跟上吗。
全部代码:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>three.js使用Echarts贴图</title>
- <script src="../js/three.js"></script>
- <script src="../js/controls/OrbitControls.js"></script>
- <script src="./echarts.js"></script>
- </head>
- <body>
- <div id="webgl" style="width:512px;height: 512px;float: left;"></div>
- <div id="echart" style="width:512px;height: 512px;margin-left: 620px;"></div>
- <script>
- var myChart = echarts.init(document.getElementById('echart'));
- option = {
- tooltip: {
- formatter: "{a} <br/>{b} : {c}%"
- },
- // toolbox: {
- // feature: {
- // restore: {},
- // saveAsImage: {}
- // }
- // },
- series: [
- {
- name: '业务指标',
- type: 'gauge',
- detail: { formatter: '{value}%' },
- data: [{ value: 50, name: '完成率' }]
- }
- ]
- };
- option.series[0].data[0].value = (Math.random() * 100).toFixed(2) - 0;
- myChart.setOption(option, true);
- class Basescene {
- constructor(dom) {
- this.id = (new Date()).getTime();
- this.dom = dom;
- this.divWidth = this.dom.offsetWidth;
- this.divHeight = this.dom.offsetHeight;
- this.scene = new THREE.Scene();
- this.camera = new THREE.PerspectiveCamera(45, this.divWidth / this.divHeight, 1, 2000);
- this.renderer = new THREE.WebGLRenderer({
- alpha: true,
- antialias: true
- });
- this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
- this.init();
- }
- init() {
- this.camera.position.set(0, 0, 20);
- this.camera.lookAt(this.scene.position);
- this.renderer.setClearColor(0x222222);
- this.renderer.setSize(this.divWidth, this.divHeight);
- this.dom.appendChild(this.renderer.domElement);
- // this.scene.add(new THREE.AxesHelper(10));
- this.animate();
- this.addLight();
- console.log(this.scene);
- }
- addLight() {
- const light = new THREE.AmbientLight(0xffffff);
- this.scene.add(light);
- }
- render() {
- this.renderer.render(this.scene, this.camera);
- }
- animate = () => {
- this.request = requestAnimationFrame(this.animate);
- this.render();
- }
- addPlane() {
- var geometry = new THREE.PlaneGeometry(10, 10);
- var material = new THREE.MeshBasicMaterial({
- side: THREE.DoubleSide,
- // transparent:true
- });
- this.plane = new THREE.Mesh(geometry, material);
- this.scene.add(this.plane);
- }
- changeTextureE(texture) {
- this.plane.material.map = new THREE.TextureLoader().load(texture)
- this.plane.material.needsUpdate = true
- }
- changeTextureT(texture) {
- this.plane.material.map = new THREE.CanvasTexture(texture)
- this.plane.material.needsUpdate = true
- }
- }
- const dom = document.getElementById("webgl");
- const scene = new Basescene(dom);
- scene.addPlane();
- setTimeout(() => {
- var thiscancas = document.getElementById("echart").getElementsByTagName('canvas')[0]
- scene.changeTextureT(thiscancas)
- }, 2000);
- setTimeout(() => {
- var texture = myChart.getDataURL({
- pixelRatio: 4,
- backgroundColor: '#fff'
- });
- scene.changeTextureE(texture)
- }, 4000);
- </script>
- </body>
- </html>
本文来自 js教程 栏目,欢迎学习!
以上就是echarts生成的图表在three.js中的应用详解的详细内容,更多请关注Gxlcms其它相关文章!