【D3.js】Axis(軸)を可変させる2種類の方法。
D3で作成した軸の値を変更してアップデートする方法です。
基本的には、スケールのドメインを変更してAxisオブジェクトに渡してアップデートするだけです。
サンプル1
axis要素を追加する初期化処理と、アップデート処理を分離したオーソドックスな方法。 initAxisの前にupdateAxisが実行されると当然ながらエラーになる。 Axisを複数表示しなくてはならないケースなどでは、init/updateのセットを複数管理しなくてはならないため複雑化しやすい。
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 |
var width = 900 var height = 235 var margin = {top:50, left:50, bottom:50, right:50 } var svg = d3.select("#example1") var xScale = d3.scaleLinear() var yScale = d3.scaleLinear() var xAxisCall = d3.axisBottom() var yAxisCall = d3.axisLeft() setScale1() initAxis() //axisの初期化 setInterval(toggle( function(){ setScale2() updateAxis() //axisをアップデート }, function(){ setScale1() updateAxis() //axisをアップデート }), 2000) function setScale1(){ xScale.domain([0, 1000]).range([0, width-(margin.top+margin.bottom)]) yScale.domain([0, 1000]).range([height-(margin.top+margin.bottom), 0]) xAxisCall.scale(xScale) yAxisCall.scale(yScale) } function setScale2(){ xScale.domain([0, 100]).range([0, width-(margin.top+margin.bottom)]) yScale.domain([0, 100]).range([height-(margin.top+margin.bottom), 0]) xAxisCall.scale(xScale) yAxisCall.scale(yScale) } //axisを描画するsvg要素を追加する function initAxis() { svg.append("g") .attr("class", "x axis") .attr("transform", "translate("+[margin.left, height-margin.top]+")") .call(xAxisCall) svg.append("g") .attr("class", "y axis") .attr("transform", "translate("+[margin.left, margin.top]+")") .call(yAxisCall) } //axisをアップデートする function updateAxis(){ var t = d3.transition() .duration(500) svg.select(".x") .transition(t) .call(xAxisCall) svg.select(".y") .transition(t) .call(yAxisCall) } |
サンプル2
初期化とアップデートの処理をD3のデータドリブン機能を利用してまとめた例。 drawAxisは、Axisが存在しない場合は要素を追加してアップデート、すでに要素が存在している場合はアップデートのみを行うため、初期化とアップデートを個別に考えなくてよい。
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 |
var width = 900 var height = 235 var margin = {top:50, left:50, bottom:50, right:50 } var svg = d3.select("#example2") var xScale = d3.scaleLinear() var yScale = d3.scaleLinear() var xAxisCall = d3.axisBottom() var yAxisCall = d3.axisLeft() setScale1() drawAxis() setInterval(toggle( function(){ setScale2() drawAxis() }, function(){ setScale1() drawAxis() }), 2000) function setScale1(){ xScale.domain([0, 1000]).range([0, width-(margin.top+margin.bottom)]) yScale.domain([0, 1000]).range([height-(margin.top+margin.bottom), 0]) xAxisCall.scale(xScale) yAxisCall.scale(yScale) } function setScale2(){ xScale.domain([0, 100]).range([0, width-(margin.top+margin.bottom)]) yScale.domain([0, 100]).range([height-(margin.top+margin.bottom), 0]) xAxisCall.scale(xScale) yAxisCall.scale(yScale) } function drawAxis(){ var t = d3.transition() .duration(500) var x = svg.selectAll(".x") .data(["dummy"]) var newX = x.enter().append("g") .attr("class", "x axis") .attr("transform", "translate("+[margin.left, height-margin.top]+")") x.merge(newX).transition(t).call(xAxisCall) var y = svg.selectAll(".y") .data(["dummy"]) var newY = y.enter().append("g") .attr("class", "y axis") .attr("transform", "translate("+[margin.left, margin.top]+")") y.merge(newY).transition(t).call(yAxisCall) } |