D3.js > D3-3Dで軸を描画する方法
更新日
2019-10-22
広告
D3.jsで3次元グラフを書くときに、軸を描画する方法を紹介します。
(まずはこちらの記事をご覧ください)
ちなみに、アングルが0(全く回転させない)状態だと、2次元(x軸とy軸)を直角に見る視点になります。 このとき、z軸は奥行きとなります。プラスだと奥で、マイナスだと手前です。
ソースコードは以下です。 頭で考えると複雑なので、変数の値を修正して、グラフがどう変化するかを確かめていくと、どの変数がどういう意味を持つのかが視覚的に理解しやすいと思います。
var origin = [400, 200], axisOrigin = [400, 200], alpha = 0.3, beta = 3, data = [], max = 4, min = -max, rad = Math.PI/180; var xLine = [], yLine = [], zLine = []; var scale = 30; var svg = d3.select('svg'); var color = d3.scaleOrdinal(d3.schemeCategory10); var rn = function(min, max){ return Math.round(d3.randomUniform(min, max + 1)()); }; // line data d3.range(-4, 2, 2).forEach(function(i){ var o = [ [ 3, 0 , i], [ 2, rn(min, max), i], [ 1, rn(min, max), i], [ 0, rn(min, max), i], [-1, rn(min, max), i], [-2, rn(min, max), i], [-3, 0 , i] ]; data.push(o); }); var _3d = d3._3d() .scale(scale) .origin(origin) .shape('LINE_STRIP') .rotateX(alpha) .rotateY(beta); var data3D = _3d(data); processLineData(data); function processLineData(data){ var linesStrip = svg.selectAll('path').data(data); linesStrip .enter() .append('path') .merge(linesStrip) .attr('fill', 'none') .attr('stroke', function(d, i){ return color(i); }) .attr('stroke-width', 2) .sort(function(a, b){ return b[0].rotated.z - a[0].rotated.z; }) .attr('d', _3d.draw); linesStrip.exit().remove(); }; // x軸を表すオブジェクト生成 var xScale3d = d3._3d() .shape('LINE_STRIP') .origin(axisOrigin) .rotateX(alpha) .rotateY(beta) .scale(scale); // x軸のデータを作成(-5から5までのx軸) d3.range(-5, 5, 1).forEach(function(d){ xLine.push([d, 0, 0]); }); var xScaleData = xScale3d([xLine]); processXScaleData(xScaleData); // x軸の描画 function processXScaleData(data){ var xScale = svg.selectAll('path.xScale').data(data); xScale .enter() .append('path') .attr('class', '_3d xScale') .merge(xScale) .attr('stroke', 'blue') .attr('stroke-width', .5) .attr('d', xScale3d.draw); xScale.exit().remove(); }; // y axis var yScale3d = d3._3d() .shape('LINE_STRIP') .origin(origin) .rotateX(alpha) .rotateY(beta) .scale(scale); d3.range(-10, 10, 1).forEach(function(d){ yLine.push([0, d, 0]); }); var yScaleData = yScale3d([yLine]); processYScaleData(yScaleData); function processYScaleData(data){ var yScale = svg.selectAll('path.yScale').data(data); yScale .enter() .append('path') .attr('class', '_3d yScale') .merge(yScale) .attr('stroke', 'red') .attr('stroke-width', .5) .attr('d', yScale3d.draw); yScale.exit().remove(); }; // z axis var zScale3d = d3._3d() .shape('LINE_STRIP') .origin(origin) .rotateX(alpha) .rotateY(beta) .scale(scale); d3.range(-5, 10, 1).forEach(function(d){ zLine.push([0, 0, d]); }); var zScaleData = zScale3d([zLine]); processZScaleData(zScaleData); function processZScaleData(data){ var zScale = svg.selectAll('path.zScale').data(data); zScale .enter() .append('path') .attr('class', '_3d zScale') .merge(zScale) .attr('stroke', 'green') .attr('stroke-width', .5) .attr('d', zScale3d.draw); zScale.exit().remove(); };
広告
お問い合わせは sweng.tips@gmail.com まで。