D3.js
データビジュアライゼーションのためのD3.js徹底入門 Webで魅せるグラフ&チャートの作り方
- 作者: 古籏一浩
- 出版社/メーカー: SBクリエイティブ株式会社
- 発売日: 2014/07/01
- メディア: Kindle版
- この商品を含むブログを見る
第10章 散布図まで。 縦軸横軸、目盛り線が難しい。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>SVG</title> <link href="../node_modules/bootstrap/dist/css/bootstrap-theme.min.css" rel="stylesheet"> <link href="../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="../node_modules/octicons/octicons/octicons.css" rel="stylesheet"> <!--[if lt IE 9]> <script src="https://cdn.jsdelivr.net/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://cdn.jsdelivr.net/respond/1.4.2/respond.min.js"></script> <![endif]--> <style media="screen"> .axis text { font-family: sans-serif; font-size: 11px; } .axis path, .axis line { fill: none; stroke: black; } .grid { stroke: gray; stroke-dasharray: 4, 2; shape-rendering: crispEdges; } .mark { fill: red; stroke: black; } .tip { position: absolute; top: 0px; left: 0px; z-index: 9999; visibility: hidden; border: 1px solid black; background-color: yellow; width: 80px; height: 16px; overflow: hidden; text-align: center; font-size: 9pt; font-family: Tahoma, Optima, Helverica; color: black; } svg { width: 380px; height: 300px; border: 1px solid; } </style> </head> <body> <script src="../node_modules/jquery/dist/jquery.min.js" charset="utf-8"></script> <script src="../node_modules/bootstrap/dist/js/bootstrap.min.js" charset="utf-8"></script> <script src="../node_modules/d3/d3.min.js" charset="utf-8"></script> <div class="container"> <h1>散布図を表示</h1> <div class="row"> <div class="col-sm-4"> <svg id="myGraph1"></svg> </div> <div class="col-sm-4"> </div> <div class="col-sm-4"> </div> </div> <script src="sample10.js" charset="utf-8"></script> </div> </body> </html>
d3.csv("sample10/mydata.csv", function(error, data) { var svgEle = document.getElementById("myGraph1"); var svgWidth = parseFloat(window.getComputedStyle(svgEle, null).getPropertyValue("width")); var svgHeight = parseFloat(window.getComputedStyle(svgEle, null).getPropertyValue("height")); var offsetX = 30; var offsetY = 20; var xScale; var yScale; var xAxisWidth = svgWidth - 40; var yAxisHeight = svgHeight - 20; var svg = d3.select("#myGraph1"); // var dataset = [ // [30, 40], [120, 115], [125, 90], [150, 160], [300, 190], // [60, 40], [140, 145], [165, 110], [200, 170], [250, 190] // ]; var dataset = []; data.forEach(function(d, I) { dataset.push([d.total / 100, d.bug * 1, d.time * 1]); }); // 目盛りとグリッドを先に表示 xScale などに関数セットするためにも drawScale(); var circleElements = svg.selectAll("circle") .data(dataset); circleElements.enter() .append("circle") .attr("class", "mark") .attr("cx", svgWidth / 2 + offsetX) .attr("cy", svgHeight / 2 - offsetY) .attr("r", 100) .attr("opacity", 0) .transition() .duration(2000) .ease("bounce") .attr("cx", function(d, i) { return xScale(d[0]) + offsetX; }) .attr("cy", function(d, i) { return yScale(d[1]); }) .attr("r", 5) .attr("opacity", 1.0); function updateData(data) { var result = data.map(function(d, i) { var x = Math.random() * svgWidth; var y = Math.random() * svgHeight; return [x, y]; }); return result; } function updateGraph() { circleElements.data(dataset) .transition() .attr("cx", function(d, i) { return d[0] - offsetX; }) .attr("cy", function(d, i) { return svgHeight - d[1] - offsetY; }); } function drawScale() { var maxX = d3.max(dataset, function(d, i) { return d[0]; }); var maxY = d3.max(dataset, function(d, i) { return d[1]; }); yScale = d3.scale.linear() .domain([0, maxY]) .range([yAxisHeight, 0]); svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + offsetX + ", " + (svgHeight - yAxisHeight - offsetY) + ")") .call( d3.svg.axis() .scale(yScale) .orient("left") ); xScale = d3.scale.linear() .domain([0, maxX]) .range([0, xAxisWidth]); svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + offsetX + ", " + (svgHeight - offsetY) + ")") .call( d3.svg.axis() .scale(xScale) .orient("bottom") ); var grid = svg.append("g"); var rangeX = d3.range(50, maxX, 50); var rangeY = d3.range(20, maxY, 20); grid.selectAll("line.y") .data(rangeY) .enter() .append("line") .attr("class", "grid") .attr("x1", offsetX) .attr("y1", function(d, i) { return svgHeight - yScale(d) - offsetY; }) .attr("x2", maxX + offsetX) .attr("y2", function(d, i) { return svgHeight - yScale(d) - offsetY; }); grid.selectAll("line.x") .data(rangeX) .enter() .append("line") .attr("class", "grid") .attr("x1", function(d, i) { return xScale(d) + offsetX; }) .attr("y1", svgHeight - offsetY) .attr("x2", function(d, i) { return xScale(d) + offsetX; }) .attr("y2", svgHeight - offsetY - yAxisHeight); } // ツールチップ var tooltip = d3.select("body") .append("div") .attr("class", "tip"); circleElements.on("mouseover", function(d) { var x = parseInt(xScale(d[0])); var y = parseInt(yScale(d[1])); var data = d3.select(this).datum(); var t = parseInt(data[2]); // var dx = parseInt(data[0]); // var dy = parseInt(data[1]); tooltip.style("left", offsetX + x + "px") .style("top", offsetY + 30 + y + "px") .style("visibility", "visible") // .text(dx + ", " + dy); .text(t + "時間"); }) .on("mouseout", function() { tooltip.style("visibility", "hidden"); }); }); // setInterval(function() { // dataset = updateData(dataset); // updateGraph(); // }, 4000);