I wanted to troll the datavis community by making a 3D pie chart from d3.svg.arc using the new d3.shape stuff. Unfortunately the THREE.js shape context isn't similar enough to the canvas API to just work.
I used this tutorial to get my THREE extruding situation setup. I found transformSVGPath in this old gist but I'm not sure the original source.
In the end the paths generated by the arc function aren't parsed properly if you use innerRadius and the whole thing stopped being fun anyway. Oh well.
Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="svg2three.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
svg { position: absolute; width: 100%; height: 100%; }
#canvas { position:absolute; width: 100%; height: 100%; }
</style>
</head>
<body>
<svg></svg>
<div id="canvas"></div>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
var arcs = [
{"startAngle": 6.0164006661729340, "endAngle": 6.1497929866762595},
{"startAngle": 6.1497929866762595, "endAngle": 6.2831853071795850},
{"startAngle": 5.7696160251662825, "endAngle": 6.0164006661729340},
{"startAngle": 5.4094390636563060, "endAngle": 5.7696160251662825},
{"startAngle": 4.8224774611396780, "endAngle": 5.4094390636563060},
{"startAngle": 3.8953388971130725, "endAngle": 4.8224774611396780},
{"startAngle": 2.4012387305698390, "endAngle": 3.8953388971130725},
{"startAngle": 0.0000000000000000, "endAngle": 2.4012387305698392}
];
var width = window.innerWidth;
var height = window.innerHeight;
var outerRadius = 90;
var innerRadius = 0;
var step = 0;
var scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render and set the size
var webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color("#fff", 1.0));
webGLRenderer.setSize(window.innerWidth, window.innerHeight);
webGLRenderer.shadowMap.enabled = true;
var options = {
amount: 1, //0, 20
bevelThickness: 5, //0, 10
bevelSize: 0, //0,10
bevelSegments: 15, //0,30
bevelEnabled: true,
curveSegments: 15, //1,30
steps: 3, //1,5
};
var shapes = [];
//var shape = createMesh(new THREE.ShapeGeometry(drawShape(), options));
arcs.forEach(function(d) {
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
.padAngle(0.05)
var path = arc(d)
var threeArc = transformSVGPath(path)
var shape = createMesh(new THREE.ExtrudeGeometry(threeArc, options));
//var shape = createMesh(new THREE.ShapeGeometry(threeArc, options));
shapes.push(shape);
scene.add(shape);
})
// position and point the camera to the center of the scene
camera.position.x = 250;
camera.position.y = 100;
camera.position.z = 100;
camera.lookAt(new THREE.Vector3(20, 15, 0));
// add the output of the renderer to the html element
document.getElementById("canvas").appendChild(webGLRenderer.domElement);
function render() {
step += 0.01;
shapes.forEach(function(shape) {
shape.rotation.x = step;
})
// render using requestAnimationFrame
requestAnimationFrame(render);
webGLRenderer.render(scene, camera);
}
render();
function createMesh(geom) {
geom.applyMatrix(new THREE.Matrix4().makeTranslation(-20, 0, 0));
// assign two materials
var meshMaterial = new THREE.MeshNormalMaterial({
// shading: THREE.FlatShading,
transparent: true,
opacity: 0.7
});
//var meshMaterial = new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } );
// meshMaterial.side = THREE.DoubleSide;
var wireFrameMat = new THREE.MeshBasicMaterial();
wireFrameMat.wireframe = true;
// create a multimaterial
var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial]);
return mesh;
}
})
</script>
</body>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js
https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js