D3 ver.4でレスポンシブなチャートを描画するサンプル。
「Open」のリンクをクリックしてwindowサイズを変更して試してみてください。
Built with blockbuilder.org
license: mit |
D3 ver.4でレスポンシブなチャートを描画するサンプル。
「Open」のリンクをクリックしてwindowサイズを変更して試してみてください。
Built with blockbuilder.org
date | value | |
---|---|---|
2016/1/1 | 1000 | |
2016/1/15 | 1300 | |
2016/1/31 | 1700 | |
2016/2/1 | 2000 | |
2016/2/2 | 1800 | |
2016/2/3 | 2100 | |
2016/3/1 | 1900 | |
2016/3/10 | 1600 | |
2016/3/20 | 2100 | |
2016/3/30 | 2000 |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"/> | |
<title>D3 v4 - Responsive Chart Example</title> | |
<style> | |
html,body,#graph { | |
width: 100%; | |
height: 100%; | |
} | |
.valueLine{ | |
fill:none; | |
stroke:blue; | |
} | |
.tick line { | |
stroke-dasharray: 2 2 ; | |
stroke: #ccc; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="graph"></div> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.1.1/d3.min.js"></script> | |
<script> | |
!(function(){ | |
"use strict" | |
var width,height | |
var chartWidth, chartHeight | |
var margin | |
var svg = d3.select("#graph").append("svg") | |
var axisLayer = svg.append("g").classed("axisLayer", true) | |
var chartLayer = svg.append("g").classed("chartLayer", true) | |
var xScale = d3.scaleTime() | |
var yScale = d3.scaleLinear() | |
d3.csv("data.csv", cast, main) | |
//データの方変換 | |
function cast(d) { | |
d.date = new Date(d.date) //dateオブジェクトに変換 | |
d.value = +d.value | |
return d | |
} | |
//初期処理 | |
function main(data) { | |
update(data) | |
setReSizeEvent(data) | |
} | |
//チャートを再描画する | |
function update(data) { | |
setSize(data) | |
drawAxis() | |
drawChart(data) | |
} | |
//リサイズ時のレスポンシブ処理 | |
function setReSizeEvent(data) { | |
var resizeTimer; | |
var interval = Math.floor(1000 / 60 * 10); | |
window.addEventListener('resize', function (event) { | |
//リサイズ中に何回もupdate関数が呼ばれてしまうのを防ぐために | |
//タイマーの設置・削除を繰り返して、リサイズが終わるまで、update関数が実行されないようにしている。 | |
if (resizeTimer !== false) { | |
clearTimeout(resizeTimer); | |
} | |
resizeTimer = setTimeout(function () { | |
update(data) | |
}, interval); | |
}); | |
} | |
//各種サイズを取得し、チャートのサイズを決定する | |
function setSize(data) { | |
//親要素のサイズを取得 | |
width = document.querySelector("#graph").clientWidth | |
height = document.querySelector("#graph").clientHeight | |
//チャート描画レイヤーのマージン | |
margin = {top:40, left:60, bottom:40, right:60 } | |
//axisエリアを除いたチャート(line)を描画する範囲を設定する | |
chartWidth = width - (margin.left+margin.right) | |
chartHeight = height - (margin.top+margin.bottom) | |
//svgにおや要素のサイズを適用 | |
svg.attr("width", width).attr("height", height) | |
//axis用のレイヤーはsvgと同等に設定している | |
axisLayer.attr("width", width).attr("height", height) | |
//チャート描画エリアのサイズを適用 | |
chartLayer | |
.attr("width", chartWidth) | |
.attr("height", chartHeight) | |
.attr("transform", "translate("+[margin.left, margin.top]+")") | |
//スケールのレンジをチャートサイズに合うように設定 | |
xScale.domain([new Date("2016/1/1"), new Date("2016/4/1")]).range([0, chartWidth]) | |
yScale.domain([500, d3.max(data, function(d){ return d.value})]).range([chartHeight, 0]) | |
} | |
//チャートを描画 | |
function drawChart(data) { | |
var t = d3.transition() | |
.duration(1000) | |
.ease(d3.easeLinear) | |
.on("start", function(d){ console.log("transiton start") }) | |
.on("end", function(d){ console.log("transiton end") }) | |
var lineGen = d3.line() | |
.x(function(d) { return xScale(d.date) }) | |
.y(function(d) { return yScale(d.value) }) | |
.curve(d3.curveStep) | |
var selectedLineElm = chartLayer.selectAll(".valueLine") | |
.data([data]) | |
var newLineElm = selectedLineElm.enter().append("path") | |
.attr("class", "valueLine") | |
selectedLineElm.merge(newLineElm) | |
.attr("d", lineGen) | |
} | |
function drawAxis(){ | |
/* axisエレメントにダミーのデータを束縛することで、 | |
* エレメントが無い場合(初回)はエレメントを追加し、アトリビュートを更新する | |
* すでにsvg上にaxisのエレメントが存在する場合はアトリビュートの更新のみが行われる | |
*/ | |
var yAxis = d3.axisLeft(yScale) | |
.tickSizeInner(-chartWidth) | |
var selectedYAxisElm = axisLayer.selectAll(".y") | |
.data(["dummy"]) | |
var newYAxisElm = selectedYAxisElm.enter().append("g") | |
.attr("class", "axis y") | |
selectedYAxisElm.merge(newYAxisElm) | |
.attr("transform", "translate("+[margin.left, margin.top]+")") | |
.call(yAxis); | |
var xAxis = d3.axisBottom(xScale) | |
var selectedXAxisElm = axisLayer.selectAll(".x") | |
.data(["dummy"]) | |
var newXAxisElm = selectedXAxisElm.enter().append("g") | |
.attr("class", "axis x") | |
selectedXAxisElm.merge(newXAxisElm) | |
.attr("transform", "translate("+[margin.left, chartHeight+margin.top]+")") | |
.call(xAxis); | |
} | |
}()); | |
</script> | |
</body> | |
</html> |