JavaScript中如何使用Three.js实现3D图表?

来源:草根站长作者:天穹小白头衔:草根站长
导读:本期聚焦于小伙伴创作的《JavaScript中如何使用Three.js实现3D图表?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript中如何使用Three.js实现3D图表?》有用,将其分享出去将是对创作者最好的鼓励。

Three.js是轻量级的JavaScript 3D库,基于WebGL封装了常用的3D功能,开发者无需深入掌握WebGL底层原理就能快速搭建3D场景。实现3D图表的核心思路是将数据值映射为3D物体的尺寸、位置等属性,再结合场景、相机、渲染器完成最终展示。

JavaScript中如何使用Three.js实现3D图表?

基础环境准备

首先需要在项目中引入Three.js库,可以通过CDN引入:

<script src="https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.min.js"></script>

实现3D柱状图的核心步骤

1. 初始化基础场景

3D场景需要包含场景、透视相机、WebGL渲染器三个核心部分,同时添加环境光让物体可见:

// 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);

// 创建透视相机 参数依次为:视角、宽高比、近裁剪面、远裁剪面
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(10, 10, 10);
camera.lookAt(0, 0, 0);

// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 添加环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
// 添加平行光增强立体感
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(10, 20, 10);
scene.add(directionalLight);

2. 数据映射为3D柱体

假设我们有以下销售数据,需要将每个数据项映射为一个3D柱体,柱体的高度对应数据值:

// 示例数据 格式为{名称: 数值}
const chartData = [
    { name: '一月', value: 5 },
    { name: '二月', value: 8 },
    { name: '三月', value: 3 },
    { name: '四月', value: 10 },
    { name: '五月', value: 7 }
];

// 柱体参数配置
const barWidth = 1; // 柱体宽度
const barDepth = 1; // 柱体深度
const barGap = 1.5; // 柱体之间的间距
const heightScale = 1; // 高度缩放系数

接下来遍历数据创建柱体并添加到场景中:

// 创建柱体材质
const barMaterial = new THREE.MeshPhongMaterial({ color: 0x4a90e2 });

chartData.forEach((item, index) => {
    // 计算柱体高度
    const barHeight = item.value * heightScale;
    // 创建长方体几何体 参数:宽度、高度、深度
    const geometry = new THREE.BoxGeometry(barWidth, barHeight, barDepth);
    const bar = new THREE.Mesh(geometry, barMaterial);
    // 设置柱体位置 x轴按索引和间距排列 y轴让柱体底部贴地 z轴设为0
    bar.position.x = index * (barWidth + barGap) - (chartData.length - 1) * (barWidth + barGap) / 2;
    bar.position.y = barHeight / 2;
    bar.position.z = 0;
    // 给柱体添加自定义属性 方便后续交互
    bar.userData = { name: item.name, value: item.value };
    scene.add(bar);
});

3. 添加坐标轴辅助

为了让图表更易读,可以添加坐标轴标记:

// 创建坐标轴辅助 参数为坐标轴长度
const axesHelper = new THREE.AxesHelper(6);
scene.add(axesHelper);

4. 渲染循环与交互

启动渲染循环,同时可以添加鼠标交互查看柱体信息:

// 渲染循环
function animate() {
    requestAnimationFrame(animate);
    // 缓慢旋转场景 增强3D观感
    scene.rotation.y += 0.002;
    renderer.render(scene, camera);
}
animate();

// 添加鼠标点击事件 获取点击的柱体信息
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
window.addEventListener('click', (event) => {
    // 计算鼠标在归一化设备坐标中的位置
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    // 更新射线
    raycaster.setFromCamera(mouse, camera);
    // 检测与柱体的交叉
    const intersects = raycaster.intersectObjects(scene.children);
    if (intersects.length > 0) {
        const target = intersects[0].object;
        if (target.userData.name) {
            alert(`当前选中:${target.userData.name},数值:${target.userData.value}`);
        }
    }
});

// 窗口大小变化时调整渲染尺寸
window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
});

效果优化建议

  • 可以给不同柱体设置不同颜色,通过数据值映射颜色深浅
  • 添加柱体的悬浮高亮效果,提升交互体验
  • 若数据量较大,可以使用实例化网格THREE.InstancedMesh提升渲染性能
  • 可以添加图表标题、数据标签等文字元素,使用THREE.CSS2DRenderer实现文字的3D排版

Three.jsJavaScript3D图表WebGL修改时间:2026-06-06 07:37:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。