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

梦辰吖_1712

梦辰吖_1712

2019-11-30

5389人浏览

转载

最近群里有几个人问,如何把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);
}

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

1.jpg

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

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

<div></div>
<div></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();

 此时看到下面页面:

2.jpg

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

3.jpg

ECharts Master
ECharts Master

ECharts 图表大师。根据用户数据和业务上下文,自动设计并生成专业的 ECharts 可视化图表。使用场景:(1) 用户提供表格/JSON/CSV 数据需要可视化,(2) 用户说"帮我做个图"、"画个图表",(3) 需要将查询结果可视化展示。

下载

方法二:getDataURL

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

4.jpg

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确实清晰多了。

5.jpg

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

6.jpg7.jpg

8.jpg

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

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

9.gif

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

全部代码:

html>


    <meta>
    <meta>
    <meta>
    <title>three.js使用Echarts贴图</title>
    <script></script>
    <script></script>
    <script></script>
    <div></div>
    <div></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>

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

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

echarts

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

2026.10.28

40

16

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

2026.10.28

20

15

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

2026.10.28

40

10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

120

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

80

10

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

2026.10.22

80

15

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

2026.10.22

40

10

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

2026.10.22

80

25

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

2026.10.22

40

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程