diff options
Diffstat (limited to 'webgl')
-rw-r--r-- | webgl/index.html | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/webgl/index.html b/webgl/index.html new file mode 100644 index 0000000..875b3d8 --- /dev/null +++ b/webgl/index.html @@ -0,0 +1,177 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="https://d3js.org/d3.v4.min.js"></script> +<script src="https://unpkg.com/d3-3d/build/d3-3d.min.js"></script> +<body> +<svg width="960" height="500"></svg> +<style type="text/css"> + button { + position: absolute; + right: 10px; + top: 10px; + } +</style> +<button>update</button> +<script> + var origin = [480, 300], j = 10, scale = 20, scatter = [], yLine = [], xGrid = [], beta = 0, alpha = 0, key = function(d){ return d.id; }, startAngle = Math.PI/4; + var svg = d3.select('svg').call(d3.drag().on('drag', dragged).on('start', dragStart).on('end', dragEnd)).append('g'); + var color = d3.scaleOrdinal(d3.schemeCategory20); + var mx, my, mouseX, mouseY; + + var grid3d = d3._3d() + .shape('GRID', 20) + .origin(origin) + .rotateY( startAngle) + .rotateX(-startAngle) + .scale(scale); + + var point3d = d3._3d() + .x(function(d){ return d.x; }) + .y(function(d){ return d.y; }) + .z(function(d){ return d.z; }) + .origin(origin) + .rotateY( startAngle) + .rotateX(-startAngle) + .scale(scale); + + var yScale3d = d3._3d() + .shape('LINE_STRIP') + .origin(origin) + .rotateY( startAngle) + .rotateX(-startAngle) + .scale(scale); + + function processData(data, tt){ + + /* ----------- GRID ----------- */ + + var xGrid = svg.selectAll('path.grid').data(data[0], key); + + xGrid + .enter() + .append('path') + .attr('class', '_3d grid') + .merge(xGrid) + .attr('stroke', 'black') + .attr('stroke-width', 0.3) + .attr('fill', function(d){ return d.ccw ? 'lightgrey' : '#717171'; }) + .attr('fill-opacity', 0.9) + .attr('d', grid3d.draw); + + xGrid.exit().remove(); + + /* ----------- POINTS ----------- */ + + var points = svg.selectAll('circle').data(data[1], key); + + points + .enter() + .append('circle') + .attr('class', '_3d') + .attr('opacity', 0) + .attr('cx', posPointX) + .attr('cy', posPointY) + .merge(points) + .transition().duration(tt) + .attr('r', 3) + .attr('stroke', function(d){ return d3.color(color(d.id)).darker(3); }) + .attr('fill', function(d){ return color(d.id); }) + .attr('opacity', 1) + .attr('cx', posPointX) + .attr('cy', posPointY); + + points.exit().remove(); + + /* ----------- y-Scale ----------- */ + + var yScale = svg.selectAll('path.yScale').data(data[2]); + + yScale + .enter() + .append('path') + .attr('class', '_3d yScale') + .merge(yScale) + .attr('stroke', 'black') + .attr('stroke-width', .5) + .attr('d', yScale3d.draw); + + yScale.exit().remove(); + + /* ----------- y-Scale Text ----------- */ + + var yText = svg.selectAll('text.yText').data(data[2][0]); + + yText + .enter() + .append('text') + .attr('class', '_3d yText') + .attr('dx', '.3em') + .merge(yText) + .each(function(d){ + d.centroid = {x: d.rotated.x, y: d.rotated.y, z: d.rotated.z}; + }) + .attr('x', function(d){ return d.projected.x; }) + .attr('y', function(d){ return d.projected.y; }) + .text(function(d){ return d[1] <= 0 ? d[1] : ''; }); + + yText.exit().remove(); + + d3.selectAll('._3d').sort(d3._3d().sort); + } + + function posPointX(d){ + return d.projected.x; + } + + function posPointY(d){ + return d.projected.y; + } + + function init(){ + var count = 0; + xGrid = [], scatter = [], yLine = []; + for(var z = -j; z < j; z++){ + for(var x = -j; x < j; x++){ + xGrid.push([x, 1, z]); + scatter.push({x: x, y: d3.randomUniform(0, -10)(), z: z, id: 'point_' + count++}); + } + } + + d3.range(-1, 11, 1).forEach(function(d){ yLine.push([-j, -d, -j]); }); + + var data = [ + grid3d(xGrid), + point3d(scatter), + yScale3d([yLine]) + ]; + processData(data, 1000); + } + + function dragStart(){ + mx = d3.event.x; + my = d3.event.y; + } + + function dragged(){ + mouseX = mouseX || 0; + mouseY = mouseY || 0; + beta = (d3.event.x - mx + mouseX) * Math.PI / 230 ; + alpha = (d3.event.y - my + mouseY) * Math.PI / 230 * (-1); + var data = [ + grid3d.rotateY(beta + startAngle).rotateX(alpha - startAngle)(xGrid), + point3d.rotateY(beta + startAngle).rotateX(alpha - startAngle)(scatter), + yScale3d.rotateY(beta + startAngle).rotateX(alpha - startAngle)([yLine]), + ]; + processData(data, 0); + } + + function dragEnd(){ + mouseX = d3.event.x - mx + mouseX; + mouseY = d3.event.y - my + mouseY; + } + + d3.selectAll('button').on('click', init); + + init(); +</script> +</body> |