Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
D3 v4 - Responsive Chart Example
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment