VR Presentation Using d3js in WebVR
In this tutorial, we’ll see how to create VR presentations using d3js and PlaneGeometry
. We’ll can add charts using d3js and we’ll use PlaneGeometry
to load slide images.
VR Presentation using d3js
We’ll first add a bar chart that we created using d3js. D3js reads the csv, and for each of the row, BoxGeometry
is used to create the bar. The height of the column is based on the value from the csv file. yscale.ticks(5)
creates the reference lines that you see on the back of the chart using LineBasicMaterial
. The text is added to the chart using TextGeometry
.
This is part of #DaysInVR series. View All VR Projects. Yesterday, we learnt how to create a world clock in VR using momentjs. Today, we’ll see how to create VR presentation in WebVR.
Join 6000+ Students
Upgrade your programming skills to include Virtual Reality. A premium step-by-step training course to get you building real world Virtual Reality apps and website components. You’ll have access to 40+ WebVR & Unity lessons along with their source code.
Start Learning Now
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
var marginbottom = 0, chartwidth = 100, chartheight = 30; var xscale = d3.scale.linear().range([-50, chartwidth]); var yscale = d3.scale.linear().range([0, chartheight]); d3.csv('data.csv', census, 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: 0x0000ff }); data.forEach(function(d, i, a) { var colheight = yscale(d.all); var columngeo = new THREE.BoxGeometry(columnWidth, colheight, columnWidth); var columnmesh = new THREE.Mesh(columngeo, columnMaterial); columnmesh.position.set(xscale(i), colheight/2 + marginbottom, -100); }); yscale.ticks(5).forEach(function(t, i, a){ //Draw label var height = 0; var size = 1.5; var material = new THREE.MultiMaterial([ new THREE.MeshBasicMaterial( { color: 0xffffff, shading: THREE.FlatShading } ), // front new THREE.MeshBasicMaterial( { color: 0xffffff, shading: THREE.SmoothShading } ) // side ]), text = "" + (t/1000); var fontLoader = new THREE.FontLoader().load('/projects/day10/helvetiker_regular.typeface.json', function(font) { function getTextMesh(text) { var textGeo = new THREE.TextGeometry( text, { size: size, height: height, curveSegments: 4, font: font, weight: "normal", style: "normal", bevelEnabled: false, material: 0, extrudeMaterial: 1 }); textGeo.computeBoundingBox(); return new THREE.Mesh( textGeo, material ); } var label = getTextMesh(text); var xOffset = ( label.geometry.boundingBox.max.x - label.geometry.boundingBox.min.x ); label.position.set(-chartwidth/2 - xOffset - 2.5, yscale(t) + marginbottom - 0.5, -100); sphere.add(label); //Draw line 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 + 50, yscale(t) + marginbottom, 0) ); lineGeometry.computeLineDistances(); var lineMaterial = new THREE.LineBasicMaterial( { color: 0xaaaaaa } ); var line = new THREE.Line( lineGeometry, lineMaterial ); line.position.set(0, 0, -100) sphere.add(line); // add title var title = getTextMesh('US Population by Age, Jan 2000 in Millions'); title.position.set(-chartwidth/2 + 20, -5, -100); sphere.add(title); // add x axis text var xzeroLabel = getTextMesh('0 years old'); xzeroLabel.position.set(-chartwidth/2, -2, -100); sphere.add(xzeroLabel); var x100Label = getTextMesh('100+ years old'); x100Label.position.set(-chartwidth/2 + chartwidth + 30, -2, -100); sphere.add(x100Label); }); }); }); |
Adding images in WebVR
To add images, we’ll use PlaneGeometry
and then load the images as texture.
1 2 3 4 5 6 7 8 9 10 |
var planeGeometry = new THREE.PlaneGeometry(30, 30); var loader = new THREE.TextureLoader(); var population = loader.load('population.png'); var planeMaterial = new THREE.MeshBasicMaterial({ map: population, side: THREE.DoubleSide }); var populationImage = new THREE.Mesh(planeGeometry, planeMaterial); populationImage.rotation.y = - Math.PI / 2; populationImage.position.x = 50; sphere.add(populationImage); |
You might have noticed that the mesh is added to sphere
and not scene
. We’ll be adding all the components to the sphere
mesh.
1 2 3 4 5 6 7 |
var sphereGeometry = new THREE.SphereGeometry(100, 60, 40); var sphereMaterial = new THREE.MeshBasicMaterial(); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); scene.add(sphere); sphere.rotation.y = Math.PI / 2 |
Once we add everything to the sphere mesh, we’ll rotate the sphere every 3 seconds so that that viewer can see the slides without turning his head around all the time.
Its your turn
Use a different geometry than the SphereGeometry
. Load more slides into the scene and see what you can come up with. Don’t forget to share your experiences in the comments below.
Download Source Code
Kickstart VR development by downloading source code for this project. You’ll have instant access to source code and asset files. You can use them in your personal or commercial projects.
Leave a Reply