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

fe45a5b5d6d81ae41500cdac6f9e8aba.png

最近群里有几个人问,如何把echarts的图表贴在three.js的模型上。这个问题其实很简单,因为二者都是渲染成canvas的,直接用echarts生成的canvas当作贴图就可以了。

方法确定可行,那么我们就直接开始撸代码。

先搭建一个three的基本场景起来,这里不在复述。

然后新建一个平面,我们把图片贴在这个平面上即可。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);

}

摆好相机的角度,此时场景中是一个白板。

7ff0d0c60589f0960774a1a510f029d7.png

然后打开echarts的官网,找到案例,来个仪表盘吧。代码拷贝下来。跑起来。

为了方便演示,我在body中创建了2个div,分别作为three和图表的容器。实际开发中图表的容器不需要显示出来的,也不需要添加到body中的。

option = {

tooltip: {

formatter: "{a}
{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();

此时看到下面页面:

e7d31d150ea61439cbd875eedda840c5.png

方法一: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绘制大点,但是这个是自适应的,导致仪表板很丑,不是想象的样子,如果是自己绘制的表格,就可以这样处理了。

edd18e3c99fb9f0d3a12ee637d495552.png

方法二:getDataURL

既然echarts也是渲染canvas,看看api,应该有方法导出图片。就是下面的api,而且有可选参数,可以设置分辨率。

e050a9f9f328effa5595648855540c4e.pngchangeTextureE(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确实清晰多了。

063317fb8d2b952cbe860b0f63289d1a.png

下面三个图分别是分辨率1,分辨率4以及方法1绘制的效果对比。

b29aaa1d6bee1fb887873be8e5c14bb5.png

99ce20951f94e243975d9982906dd225.png

463ce19a4ba8f3ab3c37574d11557068.png

3个图区别很明显,方法2>方法1。该使用什么方法已经很明白了。

下面是动态图片,开始没有贴图,然后贴上方法1生成的贴图,接着闪一下,换成方法2分辨率4生成的贴图。放大还是很清晰的。

06165ffb7c2399a4a9c761e5c3fc236e.gif

最后问题:echarts的图表很多都是有缓冲动画的,如果也想在贴图上实时刷新,可行吗。帧率能跟上吗。

全部代码:

three.js使用Echarts贴图

var myChart = echarts.init(document.getElementById('echart'));

option = {

tooltip: {

formatter: "{a}
{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);

本文来自 js教程 栏目,欢迎学习!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值