Skip to content

Instantly share code, notes, and snippets.

@scottlittle
Last active March 18, 2017 16:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scottlittle/c0c40e2b0aa4a364cc4216cc932e93e7 to your computer and use it in GitHub Desktop.
Save scottlittle/c0c40e2b0aa4a364cc4216cc932e93e7 to your computer and use it in GitHub Desktop.
VR 3D bar chart with tooltips with A-Frame and D3
license: mit

View info about a 3D chart with D3! The code may be a bit crude, so feel free to improve and use as desired.

Built with blockbuilder.org

<!DOCTYPE html>
<html>
<head>
<script src="https://aframe.io/releases/0.5.0/aframe.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
</head>
<body>
<a-scene>
<a-entity position="8 2 8" rotation="0 0 0">
<a-entity camera look-controls wasd-controls>
<a-entity cursor="fuse: true; fuseTimeout: 500"
position="0 0 -2"
geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.027"
material="color: black; shader: flat"
</a-entity>
</a-entity>
</a-entity>
<a-entity light="type: point; color: 'white'; intensity: 0.5" position="20 40 20"></a-entity>
<a-entity light="type: point; color: 'white'; intensity: 0.5" position="-20 40 20"></a-entity>
<a-sky color="#c8f8e0"></a-sky>
</a-scene>
<script>
// default alpha for bars
var alpha = 0.6
// fake data
var data = [ 19, 80, 30, 15, 55, 35, 40,
45, 50, 70, 109, 35, 78,
87, 76, 22, 2, 33, 44, 59, 200]
var animals = [ 'Bobcat', 'Dog', 'Cat', 'Boar', 'Cheetah', 'Chimp', 'Dragon',
'Elephant', 'Human', 'Elf', 'Giant', 'Batman', 'Donkey',
'Henry', 'Face', 'Funny', 'Kitty', 'Doggy', 'Joker', 'Alf', 'Earth']
// we scale the height of our bars using d3's linear scale
var hscale = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0, 3])
// we select the scene object just like an svg
var scene = d3.select("a-scene")
// we use d3's enter/update/exit pattern to draw and bind our dom elements
var bars = scene.selectAll("a-box.bar").data(data)
bars.enter().append("a-box").classed("bar", true)
$( ".bar" ).append( "<a-text> </a-text>" );
// we set attributes on our cubes to determine how they are rendered
bars.attr({
position: function(d,i) {
var x = i*.75
var y = hscale(d)/2;
var z = 1
return x + " " + y + " " + z
},
width: function(d) { return 0.5},
depth: function(d) { return 0.5},
height: function(d) { return hscale(d)},
opacity: alpha,
color: 'blue'
})
.on("click", function(d,i) {
console.log("click", i,d)
})
.on("mouseenter", function(d,i) {
// this event gets fired continuously as long as the cursor
// is over the element. we only want trigger our animation the first time
if(this.hovering) return;
console.log("hover", i,d)
this.hovering = true;
d3.select(this).transition().duration(10)
.attr({
metalness: 0.8,
opacity: .9
})
d3.select(this).select("a-text")
.attr({
'color':'hsla(240, 100%, 25%, 0.6)',
'align':'center',
'position':'0 '+ (hscale(d)/2+.5) + ' 0',
'scale':'1 1 1',
'value': animals[i]+', '+d
})
})
.on("mouseleave", function(d,i) {
console.log("leave",i,d)
this.hovering = false;
d3.select(this).transition().duration(500)
.attr({
metalness: 0,
opacity: alpha
})
d3.select(this).select("a-text")
.attr({
'color':'blue',
'align':'center',
'position':'0 '+ (hscale(d)/2+.5) + ' 0',
'scale':'.01 .01 .01',
'value': d
})
})
</script>
<script>
$(".bar").each(function() {
this.components.material.material.alphaTest = 0.5;
this.components.material.material.depthWrite = false;
this.components.material.material.needsUpdate = true;;
});
</script>
<body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment