Scatter (svg) 그래프 그리기, Transition
[다운로드]
http://d3js.org/download/ (d3.js)
http://jquery.com/ (jquery.js)
[index.html]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3 Test</title>
<script type="text/javascript" src="../javascripts/lib/d3.js"></script>
<link rel="stylesheet" href="../stylesheets/style.css">
</head>
<body>
<button class="btn adddata">add data</button>
<button class="btn removedata">remove data</button>
<br><br>
<div id="demo"></div>
<br><br>
<script src="../javascripts/lib/jquery.min.js"></script>
<script type="text/javascript">
JSONData = [
{ "id": 3, "created_at": "Sun May 05 2013", "amount": 12000},
{ "id": 1, "created_at": "Mon May 13 2013", "amount": 2000},
{ "id": 2, "created_at": "Thu Jun 06 2013", "amount": 17000},
{ "id": 4, "created_at": "Thu May 09 2013", "amount": 15000},
{ "id": 5, "created_at": "Mon Jul 01 2013", "amount": 16000}
];
(function() {
var data = JSONData.slice();
//var format = d3.timeFormat("%a %b %d %Y"); //d3 v3.5
var parseTime = d3.timeParse("%a %b %d %Y"); //d3 v4.0
var amountFn = function(d) { return d.amount };
//var dateFn = function(d) { return format.parse(d.created_at) }; //d3. v3.5
var dateFn = function(d) { return parseTime(d.created_at) }; //d3 v4.0
var x = d3.scaleTime() //시간 단위로 들어오는 인자를 scale로 변환한 값 반환
.range([10, 280]) //범위 10~280내에 어느 위치인지 비율적 값으로
.domain(d3.extent(data, dateFn)); //domain은 데이터셋의 처음과 끝을 지정 range가 고정되어 있기 때문에 데이터값이 바뀔때마다 domain도 바뀌어야한다
var y = d3.scaleLinear() //상수 값 단위로 들어오는 인자를 scale()로 변환한 값 반환
.range([180, 10]) //범위 180~10내에 어느 위치인지 비율적 값으로 -> svg의 y축은 반대이다
.domain(d3.extent(data, amountFn)); //extend는 domain의 argument로써 d3.min(data, amountFn), d3.max(data, amountFn)을 지칭함
var svg = d3.select("#demo").append("svg:svg")
.attr("width", 300)
.attr("height", 200);
var refreshGraph = function () {
x.domain(d3.extent(data, dateFn)); //x축 domain 재설정
y.domain(d3.extent(data, amountFn)); //y축 domain 재설정
var circles = svg.selectAll("circle").data(data);
circles.transition() //기존에 있던 데이터는 4로 줄이고 domain을 바꾸는 transition을 넣음
.attr("r", 4)
.attr("cx", function(d) { return x(dateFn(d)) })
.attr("cy", function(d) { return y(amountFn(d)) });
circles.enter() //enter는 데이터 바인딩 역할 circle을 생성하여 append함. refresh 시 새로운 데이터(아직 바인딩이 안된)에 대해서만 영향을 줌
.append("svg:circle")
.attr("r", 16)
.attr("cx", function(d) { return x(dateFn(d)) })
.attr("cy", function(d) { return y(amountFn(d)) })
.style("stroke","#79A32B")
.style("stroke-width","2px")
.style("fill","transparent")
.transition()
.attr("r",4);
circles.exit() //exit는 refresh 시 사라진 데이터에 대한 처리. 데이터를 가지고 있을 지 실제로 삭제할지
.transition()
.attr("r",10)
.transition()
.attr("r",0)
.remove()
};
d3.selectAll(".adddata")
.on("click", function() {
var start = d3.min(data, dateFn);
var end = d3.max(data, dateFn);
var time = start.getTime() + Math.random() * (end.getTime() - start.getTime());
var date = new Date(time);
obj = {
'id': Math.floor(Math.random() * 70),
'amount': Math.floor(1000 + Math.random() * 20001),
'created_at': date.toDateString()
};
data.push(obj);
refreshGraph();
});
d3.selectAll(".removedata")
.on("click", function() {
data.splice(Math.floor(Math.random()*data.length),1);
refreshGraph();
});
refreshGraph()
})();
</script>
</body>
</html>
'Development > D3js' 카테고리의 다른 글
Interactive General Update Pattern (0) | 2017.09.04 |
---|---|
D3.js에서 svg 사용하기 (0) | 2017.04.24 |
D3.js 개요 및 핵심 정리 (0) | 2017.04.24 |
D3.js 바 그래프 그리기(svg), 데이터 수정 (0) | 2017.04.12 |
D3.js 바 그래프 그리기(div), 데이터 수정 (0) | 2017.04.12 |