Friday 13 January 2017

Membuat Virtual Reality / VR Visualisasi Data - Three.js



Pada postingan kali ini merupakan source code tambahan dari yang ada diblog :

http://www.storybench.org/how-to-make-a-simple-virtual-reality-data-visualization
https://github.com/rogerkenny/3D-chart-tutorial/archive/master.zip


Download  dan jalankan sourcode zip diatas sebelum  jalankan source code yang ada di postingan ini..

Source code yang sudah ada tambahan kode:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>3D chart!</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
      body {
        margin: 0px;
        overflow: hidden;
      }
      #container {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
      }
    </style>
  </head>
  <body>
    <div id="container"></div>

  <script src="js/third-party/threejs/three.js"></script>
<!--<script src="js/third-party/threejs/StereoEffect.js"></script>
  <script src="js/third-party/threejs/DeviceOrientationControls.js"></script>-->
  <script src="js/third-party/threejs/OrbitControls.js"></script>
  <script src="js/optimer_bold.typeface.js"></script>
  <script src="js/optimer_regular.typeface.js"></script>
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

  <script>
    var camera, scene, renderer;
    var effect, controls;
    var element, container;
    var marginbottom = 4, chartwidth = 50, chartheight = 30; //3D units
    var xscale = d3.scale.linear().range([-chartwidth/2, chartwidth/2]),
        yscale = d3.scale.linear().range([0, chartheight]);


    var clock = new THREE.Clock();

    init();
    animate();

    function init() {
      renderer = new THREE.WebGLRenderer();
      element = renderer.domElement;
      container = document.getElementById('container');
      container.appendChild(element);

      // effect = new THREE.StereoEffect(renderer);

      scene = new THREE.Scene();

      camera = new THREE.PerspectiveCamera(90, 1, 0.001, 700);
      camera.position.set(0, 15, 30);
      scene.add(camera);

      controls = new THREE.OrbitControls(camera, element);
      controls.rotateUp(Math.PI / 4);
      controls.target.set(
        camera.position.x,
        camera.position.y + 0.1,
        camera.position.z - 0.1
      );
      controls.noZoom = true;
      controls.noPan = true;

      function setOrientationControls(e) {
        if (!e.alpha) {
          return;
        }

        controls = new THREE.DeviceOrientationControls(camera, true);
        controls.connect();
        controls.update();

        element.addEventListener('click', fullscreen, false);

        window.removeEventListener('deviceorientation', setOrientationControls, true);
      }
      window.addEventListener('deviceorientation', setOrientationControls, true);


      var light = new THREE.HemisphereLight(0x777777, 0x000000, 0.6);
      scene.add(light);

      var objlight = new THREE.PointLight(0xffffff, 0.7);
      objlight.position.set(0, 50, 70);
      scene.add(objlight);


 var light = new THREE.HemisphereLight(0x777777, 0x000000, 0.6);
      scene.add(light);

      var objlight = new THREE.PointLight(0xffffff, 0.7);
      objlight.position.set(70, 50, 0);
      scene.add(objlight);



      var texture = THREE.ImageUtils.loadTexture(
        'textures/patterns/yellowchecker.png'
      );
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      texture.repeat = new THREE.Vector2(50, 50);
      texture.anisotropy = renderer.getMaxAnisotropy();

      spectexture = THREE.ImageUtils.loadTexture(
        'textures/patterns/blacklinegrid.png'
      );
      spectexture.wrapS = THREE.RepeatWrapping;
      spectexture.wrapT = THREE.RepeatWrapping;
      spectexture.repeat = new THREE.Vector2(50, 50);
      spectexture.anisotropy = renderer.getMaxAnisotropy();

      var material = new THREE.MeshPhongMaterial({
        color: 0xffffff,
        specular: 0xffffff,
        shininess: 5,
        shading: THREE.FlatShading,
        map: texture,
        specularMap: spectexture
      });

      var geometry = new THREE.PlaneGeometry(1000, 1000);

      var mesh = new THREE.Mesh(geometry, material);
      mesh.rotation.x = -Math.PI / 2;
      scene.add(mesh);

      window.addEventListener('resize', resize, false);
      setTimeout(resize, 1);

      /////// START CONTENT HERE ////////

      d3.csv('data3.csv', population, function(data){
        xscale.domain([0, data.length - 1]);
        yscale.domain([0, d3.max(data, function(d){ return d.all; })]);

        var columnwidth = (chartwidth / data.length);
        columnwidth -= columnwidth * 0.1;

        var columnmaterial = new THREE.MeshPhongMaterial({
          color: "#0000ff",
          emissive: "#000000"
        });


        data.forEach(function(d, i, a){
          var colheight = yscale(d.all);
          var columngeo = new THREE.BoxGeometry(1, colheight, 1);
          var columnmesh = new THREE.Mesh(columngeo, columnmaterial);
           columnmesh.rotation.y = Math.PI / 2;
          columnmesh.position.set(xscale(i), colheight/2 + marginbottom,0 ); //Box geometry is positioned at its’ center, so we need to move it up by half the height

          scene.add(columnmesh);
        });

        yscale.ticks(5).forEach(function(t, i, a){
          //Draw label
          var label = createType({text: "" + (t/1000000), size: 1.5});
          var xOffset = ( label.geometry.boundingBox.max.x - label.geometry.boundingBox.min.x );
          label.position.set(-50/2 - xOffset - 2.5, yscale(t) + marginbottom - 0.5, 0);
          scene.add(label);

          //Draw lin
                    var lineGeometry = new THREE.Geometry();
          var vertArray = lineGeometry.vertices;
          vertArray.push( new THREE.Vector3(-chartwidth/2 - 1.5, yscale(t) + marginbottom, 0),
                          new THREE.Vector3(chartwidth/2, yscale(t) + marginbottom, 0) );
          lineGeometry.computeLineDistances();
          var lineMaterial = new THREE.LineBasicMaterial( { color: 0xaaaaaa } );
          var line = new THREE.Line( lineGeometry, lineMaterial );
          scene.add(line);

        });

      });

      function population(d) {
        d.all = +d.all;
        d.male = +d.male;
        d.female = +d.female;
        return d;
      }

      var title = createType({text: "Judul 1 2 3 4",size: 2});
      title.position.set(-chartwidth/2-5, chartheight + 10, -5);
      scene.add(title);

      var xzerolabel = createType({text: "0 years old", size: 1.5});
      xzerolabel.position.set(-chartwidth/2 - 1, 2, 0);
      scene.add(xzerolabel);

      var x100label = createType({text: "100+ years old", size: 1.5});
      var xOffset = ( x100label.geometry.boundingBox.max.x - x100label.geometry.boundingBox.min.x );
      x100label.position.set(chartwidth/2 - xOffset, 2, 0);
      scene.add(x100label);

      var srctext = createType({text: "Sauce: U.S. Census", size: 1});
      var xOffset = 0.5 * ( x100label.geometry.boundingBox.max.x - x100label.geometry.boundingBox.min.x );
      srctext.position.set(0 - xOffset, 1, 0);
      scene.add(srctext);
///
  d3.csv('data3.csv', population, function(data){
        xscale.domain([0, data.length - 1]);
        yscale.domain([0, d3.max(data, function(d){ return d.all; })]);

        var columnwidth = (chartwidth / data.length);
        columnwidth -= columnwidth * 0.1;

        var columnmaterial = new THREE.MeshPhongMaterial({
          color: "#0000ff",
          emissive: "#000000"
        });


        data.forEach(function(d, i, a){
          var colheight = yscale(d.all);
          var columngeo = new THREE.BoxGeometry(1, colheight, 1);
          var columnmesh = new THREE.Mesh(columngeo, columnmaterial);
           columnmesh.rotation.y = Math.PI / 2;
          columnmesh.position.set(xscale(25), colheight/2 + marginbottom,5+i*2 ); //Box geometry is positioned at its’ center, so we need to move it up by half the height

          scene.add(columnmesh);
        });
    yscale.ticks(5).forEach(function(t, i, a){
          //Draw label
          var label = createType({text: "" + (t/1000000), size: 1.5});
          var xOffset = ( label.geometry.boundingBox.max.x - label.geometry.boundingBox.min.x );
          label.position.set(-50/2 - xOffset - 2.5, yscale(t) + marginbottom - 0.5, 0);
          scene.add(label);

          //Draw lin
                    var lineGeometry = new THREE.Geometry();

          var vertArray = lineGeometry.vertices;
          vertArray.push( new THREE.Vector3(32, yscale(t) + marginbottom, -chartwidth/2 - 1.5+30),
                          new THREE.Vector3(32, yscale(t) + marginbottom, chartwidth/2+25) );
          lineGeometry.computeLineDistances();
          var lineMaterial = new THREE.LineBasicMaterial( { color: 0xaaaaaa } );
          var line = new THREE.Line( lineGeometry, lineMaterial );
        //  line.rotation.y = Math.PI / 3.14;
          scene.add(line);

        });

    });

    d3.csv('data3.csv', population, function(data){
        xscale.domain([0, data.length - 1]);
        yscale.domain([0, d3.max(data, function(d){ return d.all; })]);

        var columnwidth = (chartwidth / data.length);
        columnwidth -= columnwidth * 0.1;

        var columnmaterial = new THREE.MeshPhongMaterial({
          color: "#0000ff",
          emissive: "#000000"
        });


        data.forEach(function(d, i, a){
          var colheight = yscale(d.all);
          var columngeo = new THREE.BoxGeometry(1, colheight, 1);
          var columnmesh = new THREE.Mesh(columngeo, columnmaterial);
           columnmesh.rotation.y = Math.PI / 2;
          columnmesh.position.set(xscale(22-i), colheight/2 + marginbottom,60); //Box geometry is positioned at its’ center, so we need to move it up by half the height

          scene.add(columnmesh);
        });
    yscale.ticks(5).forEach(function(t, i, a){
          //Draw label
          var label = createType({text: "" + (t/1000000), size: 1.5});
          var xOffset = ( label.geometry.boundingBox.max.x - label.geometry.boundingBox.min.x );
          label.position.set(-50/2 - xOffset - 2.5, yscale(t) + marginbottom - 0.5, 0);
          scene.add(label);

          //Draw lin
                    var lineGeometry = new THREE.Geometry();
          var vertArray = lineGeometry.vertices;
          vertArray.push( new THREE.Vector3(-chartwidth/2 - 1.5, yscale(t) + marginbottom, 60),
                          new THREE.Vector3(chartwidth/2-0, yscale(t) + marginbottom, 60) );
          lineGeometry.computeLineDistances();
          var lineMaterial = new THREE.LineBasicMaterial( { color: 0xaaaaaa } );
          var line = new THREE.Line( lineGeometry, lineMaterial );
          scene.add(line);

        });

    });
 d3.csv('data3.csv', population, function(data){
        xscale.domain([0, data.length - 1]);
        yscale.domain([0, d3.max(data, function(d){ return d.all; })]);

        var columnwidth = (chartwidth / data.length);
        columnwidth -= columnwidth * 0.1;

        var columnmaterial = new THREE.MeshPhongMaterial({
          color: "#0000ff",
          emissive: "#000000"
        });


        data.forEach(function(d, i, a){
          var colheight = yscale(d.all);
          var columngeo = new THREE.BoxGeometry(1, colheight, 1);
          var columnmesh = new THREE.Mesh(columngeo, columnmaterial);
           columnmesh.rotation.y = Math.PI / 2;
          columnmesh.position.set(xscale(0), colheight/2 + marginbottom,50-i*2 ); //Box geometry is positioned at its’ center, so we need to move it up by half the height

          scene.add(columnmesh);
        });
    yscale.ticks(5).forEach(function(t, i, a){
          //Draw label
          var label = createType({text: "" + (t/1000000), size: 1.5});
          var xOffset = ( label.geometry.boundingBox.max.x - label.geometry.boundingBox.min.x );
          label.position.set(-50/2 - xOffset - 2.5, yscale(t) + marginbottom - 0.5, 0);
          scene.add(label);

          //Draw lin
                    var lineGeometry = new THREE.Geometry();

          var vertArray = lineGeometry.vertices;
          vertArray.push( new THREE.Vector3(-25, yscale(t) + marginbottom, -chartwidth/2 - 1.5+33),
                          new THREE.Vector3(-25, yscale(t) + marginbottom, chartwidth/2+27) );
          lineGeometry.computeLineDistances();
          var lineMaterial = new THREE.LineBasicMaterial( { color: 0xaaaaaa } );
          var line = new THREE.Line( lineGeometry, lineMaterial );
        //  line.rotation.y = Math.PI / 3.14;
          scene.add(line);

        });

    });
}

    function resize() {
      var width = container.offsetWidth;
      var height = container.offsetHeight;

      camera.aspect = width / height;
      camera.updateProjectionMatrix();

      renderer.setSize(width, height);
      // effect.setSize(width, height);
    }

    function update(dt) {
      resize();

      camera.updateProjectionMatrix();

      controls.update(dt);
    }

    function render(dt) {
      renderer.render(scene, camera);
      // effect.render(scene, camera);
    }

    function animate(t) {
      requestAnimationFrame(animate);

      update(clock.getDelta());
      render(clock.getDelta());
    }

    function fullscreen() {
      if (container.requestFullscreen) {
        container.requestFullscreen();
      } else if (container.msRequestFullscreen) {
        container.msRequestFullscreen();
      } else if (container.mozRequestFullScreen) {
        container.mozRequestFullScreen();
      } else if (container.webkitRequestFullscreen) {
        container.webkitRequestFullscreen();
      }
    }

    function createType(options) {
        var height = options.height || 0,
            size = options.size || 3,
            material = new THREE.MeshFaceMaterial( [
              new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading } ), // front
              new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.SmoothShading } ) // side
            ] ),
            text = options.text || "Test";

      var textGeo = new THREE.TextGeometry( text, {

          size: size,
          height: height,
          curveSegments: 4,

          font: "optimer",
          weight: "normal",
          style: "normal",

          bevelEnabled: false,

          material: 0,
          extrudeMaterial: 1

        });

        textGeo.computeBoundingBox();

        var textMesh1 = new THREE.Mesh( textGeo, material );

        return textMesh1;
    }
  </script>
  </body>
</html>


Bila source code tersebut dapat dipelajari  agar mengerti tentang  fungsi-fungsi pada three js misal position, rotate, dan menambah object.

Kurangi data dalam data.csv menjadi:

date,age,all,male,female
"January 1, 2000","0",3803453,1947719,1855734
"January 1, 2000","1",3816646,1951304,1865342
"January 1, 2000","2",3773178,1929817,1843361
"January 1, 2000","3",3840163,1963473,1876690
"January 1, 2000","4",3924534,2009608,1914926
"January 1, 2000","5",3984021,2040493,1943528
"January 1, 2000","6",4024543,2061740,1962803
"January 1, 2000","7",4134443,2117611,2016832
"January 1, 2000","8",4171709,2133163,2038546
"January 1, 2000","9",4264360,2185397,2078963
"January 1, 2000","10",4230386,2168849,2061537
"January 1, 2000","11",4093175,2096683,1996492
"January 1, 2000","12",4049448,2074088,1975360
"January 1, 2000","13",3991142,2043684,1947458
"January 1, 2000","14",4062456,2085078,1977378
"January 1, 2000","15",3993157,2051531,1941626
"January 1, 2000","16",3981264,2052133,1929131
"January 1, 2000","17",4075591,2105486,1970105
"January 1, 2000","18",3892332,1985635,1906697
"January 1, 2000","19",4146489,2093531,2052958
"January 1, 2000","20",3915141,1976777,1938364
"January 1, 2000","21",3712547,1872273,1840274
"January 1, 2000","22",3681044,1856205,1824839



Sekian dan terima kasih



Artikel Terkait javascript

0 komentar:

Post a Comment