基于three的晴雨表

基于three的晴雨表(简易制作)

最近学了three和echarts,在可视化图表中看到了一个优秀的案例,用晴雨表反映出多种属性的关联性和差异;市面上大多数晴雨表都是平面,基于D3或者echarts制作,于是我尝试着用three做一个沉浸式的晴雨表

创建晴雨表需要用到组和mesh
   	var barometer = new THREE.Group();
    scene.add(barometer);
    var barometer_data = new Array(20 * 30);

考虑到晴雨表需要在不同的环境下进行缩放和位置的移动,所以建立了一个组,然后这里创建了一个20x30的数组,是想创建一个20*30的方块阵,每个方块通过颜色和大小来表示两种属性

for (let i = 0; i < 20; i++) {
     
      for (let j = 0; j < 30; j++) {
     
        let index = i * 30 + j;
        barometer_data[index] = new THREE.Mesh(
          new THREE.CubeGeometry(1e2, 1e2, 10),
          new THREE.MeshStandardMaterial({
     
            color: 0x000000
          })
        );
        barometer_data[index].position.set(
          j * 100 - 1500,
          i * 100 - 1000,
          0
        );
        barometer.add(barometer_data[index]);
      }
    }

这里我们把方块按2000*3000的大小规则排列,可以得到这样一个效果,当然,这里由于我设置的背景色为白色,所以我把方块的初始颜色设置为黑色

基于three的晴雨表_第1张图片

数据模拟

然后我们可以进行一个模拟,模拟20个城市在30天内的AQI和PM2.5数值,然后通过晴雨表呈现,晴雨表的横纵轴表示日期和城市,颜色反映AQI,方块的大小反映PM2.5

首先我们写两个数据转换的函数
    function AQIColor(AQI, AQI_max = 100) {
     
      let colors = [
        '#0077ff',
        '#00ff55',
        '#ffee00',
        '#ff7700',
        '#ff2200'
      ];
      return colors[Math.ceil((AQI / AQI_max) * 5) - 1];
    }

    function PM25Scale(PM25, PM25_max = 100) {
     
      return PM25 / PM25_max;
    }
然后我们再写一个通过随机数据刷新方块的材质和几何属性的函数
function barometerFresh() {
     
      for (let i = 0; i < 20; i++) {
     
        for (let j = 0; j < 30; j++) {
     
          let index = i * 30 + j;
          let AQI = Math.random() * 99 + 1;
          let PM25 = Math.random() * 99 + 1;
          barometer_data[index].material.color.set(AQIColor(AQI));
          barometer_data[index].scale.set(PM25Scale(PM25), PM25Scale(PM25), 1);
        }
      }
    }

基于three的晴雨表_第2张图片

调用函数后我们可生成如上图的所示的晴雨表,但由于考虑到实际的气象数据,并不会出现如此大的差异(呈现效果并不能反映一定的信息),于是我们把模拟数据范围限定一下,来尽可能还原一个真实的气象情况

模拟真实数据
function barometerFresh() {
     
      for (let i = 0; i < 20; i++) {
     
        for (let j = 0; j < 30; j++) {
     
          let index = i * 30 + j;
          //不平稳
          // let AQI = Math.random() * 99 + 1;
          // let PM25 = Math.random() * 99 + 1;

          //仿真
          let AQI = Math.random() * 40 + 5;
          let PM25 = AQI + 30;
          barometer_data[index].material.color.set(AQIColor(AQI));
          barometer_data[index].scale.set(PM25Scale(PM25), PM25Scale(PM25), 1);
        }
      }
    }

    barometerFresh();

基于three的晴雨表_第3张图片

现在我们基本上可以得到一个呈现效果较好的晴雨表:AQI的值基本随着PM25增大而增大,下次我们再拿一组真实数据来测试,并尝试加入信息提示和交互

你可能感兴趣的:(three.js,可视化,前端)