1.搭建3d坐标轴
利用BufferGeometry创建出平面,分别作为左侧,下侧,后侧的平面坐标轴,
class GridHelper extends THREE.LineSegments {
constructor(
// 传入平面坐标轴的x,y
sizeX = 1,
sizeY = 1,
// 边缘颜色
color1,
color2
)
// 坐标轴单位为1
const step = 1
// 最大长度的一半
const halfSizeX = sizeX / 2
const halfSizeY = sizeY / 2
// 坐标数组
const vertices = []
// 颜色数组
const colors = []
// 声明颜色索引
let j = 0
// 每条线的两个对应的顶点坐标的Z坐标(Y坐标)不变,X轴单调递增step,创建坐标轴平面的竖线
for(let i = 0, k = -halfSizeX; i < sizeX; i++, k +=step){
// x坐标的最小值为-halfSizeX,中间为0
// z坐标都为 -halfSizeY,-halfSizeY
vertices.push(k,0,-halfSizeY, k,0,-halfSizeY)
// 边缘线条颜色为color1,中间的线条为color2
const color = i == 0 || i == sizeX ? color2 : color1
// push进数组
color.toArray(colors, j)
j+=3
color.toArray(colors, j)
j+=3
}
// 每条线对应的两个x坐标不变,z坐标(y坐标)单调递增step,创建坐标轴平面的横线
for(let i = 0,k = -halfSizeY; i < sizeY; i++,k+=step){
vertices.push(-halfSizeX,0,k,halfSizeX,0,k)
const color = i == 0 || i == sizeY ? color2 : color1;
color.toArray(colors, j);
j += 3;
color.toArray(colors, j);
j += 3;
}
// 利用顶点数组与颜色数组创建出坐标轴平面
const geometry = new THREE.BufferGeometry()
geometry.setAttribute(
'position',
new THREE.Float32BufferAttribute(vertices, 3)
)
geometry.setAttribute(
'color',
new THREE.Float32BufferAttribute(colors,3)
)
const material = new THREE.LineBasicMaterial({
vertexColors : true,
toneMapped : false
})
this.type = "GridHelper";
}
2.创建圆柱条形图
class Bar3d(){
constructor(data,color){
this.color = color || new THREE.Color(Math.random() * 0xffffff)
this.material = new THREE.MeshStandardMaterial({
color: this.color,
transparent : true,
opacity : 0.8
})
// 创建mesh统一管理
this.mesh = new THREE.Group();
// 遍历数据创建几何体
data.forEach((item,index)=>{
// 传入上下圆的半径,和高度也就是该项数据的值
let cylinderGeometry = new THREE.CylinderGeometry(0.5,0.5,item.value)
let cylinder = new THREE.Mesh(cylinderGeometry, material);
// 位置 x坐标:-3 -1 1 3 y坐标: item.value / 2 ,往上提一半
cylinder.position.set(-3 + index * 2, item.value / 2, 0);
this.mesh.add(cylinder);
})
// 添加字体精灵
// 位置跟对应的圆柱体一样,只是往下挪了0.5
let textPosition = new THREE.Vector3(-3 + index * 2, item.value + 0.5, 0);
// 生成精灵图
let spriteText = new SpriteText(item.name, textPosition);
this.mesh.add(spriteText.mesh);
}
}