Create a gist now

Instantly share code, notes, and snippets.

@shimizu /.block
Last active Sep 27, 2016

D3 ver.4 - Axis Update Example
license: mit

axisのアップデート方法2種

example1

axis要素を追加する初期化処理と、アップデート処理を分離したオーソドックスな方法。 initAxisの前にupdateAxisが実行されると当然ながらエラーになる。 Axisを複数表示しなくてはならないケースなどでは、init/updateのセットを複数管理しなくてはならないため複雑化しやすい。

example2

初期化とアップデートの処理をD3のデータドリブン機能を利用してまとめた例。 drawAxisは、Axisが存在しない場合は要素を追加してアップデート、すでに要素が存在している場合はアップデートのみを行うため、初期化とアップデートを個別に考えなくてよい。

Built with blockbuilder.org

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>D3 ver.4 - Axis Update Example</title>
<style>
html, body {
position:fixed;
top:0;right:0;bottom:0;left:0;
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
}
svg {
width: 100%;
height:50%;
}
</style>
</head>
<body>
<svg id="example1"></svg>
<svg id="example2"></svg>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.1.1/d3.min.js"></script>
<script>
var width = document.querySelector("svg").clientWidth
var height = document.querySelector("svg").clientHeight
var margin = {top:50, left:50, bottom:50, right:50 }
axisUpdateExample1()
axisUpdateExample2()
function axisUpdateExample1() {
var svg = d3.select("#example1")
var xScale = d3.scaleLinear()
var yScale = d3.scaleLinear()
var xAxisCall = d3.axisBottom()
var yAxisCall = d3.axisLeft()
setScale1()
initAxis()
setInterval(toggle(
function(){
setScale2()
updateAxis()
},
function(){
setScale1()
updateAxis()
}), 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 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)
}
function updateAxis(){
var t = d3.transition()
.duration(500)
svg.select(".x")
.transition(t)
.call(xAxisCall)
svg.select(".y")
.transition(t)
.call(yAxisCall)
}
}
function axisUpdateExample2() {
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)
}
}
function toggle(){
var fn = arguments;
var l = arguments.length;
var i = 0;
return function(){
if(l <= i) i=0;
fn[i++]();
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment