echarts生成的图表在three.js中的应用详解

互联网 19-11-30

最近群里有几个人问,如何把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绘制的效果对比。

下面是动态图片,开始没有贴图,然后贴上方法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中的应用详解的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: three.js
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:图片批量上传js插件 imgFileupload.js

相关资讯