@tenten0213
Line Chartを描くにはこんな感じです。
// marginの設定 var margin = {top: 20, right: 20, bottom: 30, left: 50}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; // 日付の表示形式の設定 var parseDate = d3.time.format("%d-%b-%y").parse;
// X軸、Y軸の設定 var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left");
// Line要素の生成 var line = d3.svg.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.close); }); // SVG領域の生成 var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// データ取得 d3.tsv("data.tsv", function(error, data) { data.forEach(function(d) { d.date = parseDate(d.date); d.close = +d.close; }); // X軸、Y軸の範囲指定 x.domain(d3.extent(data, function(d) { return d.date; })); y.domain(d3.extent(data, function(d) { return d.close; })); // X軸の描画 svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis);
// Y軸の描画 svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Price ($)"); // Lineの描画 svg.append("path") .datum(data) .attr("class", "line") .attr("d", line); });
ムズカシイ(´・ω・`)
グラフを描くための大体の流れや、コード量を感じ取ってもらえばと思います。
もっと簡単にグラフを書きたい方は、最後にオススメのライブラリを紹介しますのでそちらをご参照ください。
Galleryにあるサンプルは綺麗で参考にはなるのですが、
複雑です。
まずは基礎から見ていきましょう。
$("ul").children(".hoge")
var paragraphs = document.getElementsByTagName("p"); for (var i = 0; i < paragraphs.length; i++) { var paragraph = paragraphs.item(i); paragraph.style.setProperty("color", "white", null); }
d3.selectAll("p").style("color", "white");
楽ちんですね!
Hello! D3.js\(^o^)/
Hello! D3.js\(^o^)/
d3.select('#TEXT1').style('background-color', 'black');
Hello! D3.js\(^o^)/
(๑・ิω・ิ๑)yー~
d3.select('#TEXT2').selectAll('p').style('color', 'red');
⇧に以下のdivタグがあります。
d3.select('#appendAndRemove').append('p').text('キタ━(゚∀゚)━');
d3.select('#appendAndRemove').selectAll('p').node().remove();
リンゴ
オレンジ
バナナ
var fruits = ["Apple", "Orange", "Banana"];
全てのp要素を配列fruitsの内容で上書きします。
リンゴ
オレンジ
バナナ
var fruits = ["Apple", "Orange", "Banana"]; var p = d3.select('#fruits').selectAll('p'); p.data(fruits).text(function(d) {return d;});
リンゴ
オレンジ
バナナ
var fruits = ["Apple", "Orange", "Banana", "strowberry"];
p要素の数より配列fruitsの要素数が多いので、多い分は追加します。
リンゴ
オレンジ
バナナ
var fruits = ["Apple", "Orange", "Banana", "strowberry"]; var p = d3.select('#fruits').selectAll('p'); var update = p.data(fruits); var enter = update.enter(); update.text(function(d) {return d;}); enter.append('p').text(function(d) {return d;});
要素がまだ無い場合
var fruits = ["Apple", "Orange", "Banana"]; var p = d3.select('#empty').selectAll('p'); var enter = p.data(fruits).enter(); enter.append('p').text(function(d) {return d;});
リンゴ
オレンジ
バナナ
イチゴ
var fruits = ["Apple", "Orange", "Banana"];
p要素の数の方が配列fruitsの要素数より多いので、余るp要素を削除する
リンゴ
オレンジ
バナナ
イチゴ
var fruits = ["Apple", "Orange", "Banana"]; var p = d3.select('#fruits').selectAll('p'); var update = p.data(fruits); var exit = update.exit(); update.text(function(d) {return d;}); exit.remove();
お待たせしましたm(__)m
やっと描画のお話です。
SVG要素の生成は以下のように行います。
var svg = d3.select("#graph").append("svg");
以下のように描画するサイズを指定して生成することも出来ます。
var svg = d3.select("#graph").append("svg").attr("width", 200).attr("height", 100);
var data = [ { "x": 100, "y": 50}, { "x": 100, "y": 400}, { "x": 700, "y": 400},{ "x": 100, "y": 50}]; var line = d3.svg.line() .x(function(d) { return d.x; }) .y(function(d) { return d.y; }); svg.append("path") .attr("d", line(data)) .attr("stroke", "#e74c3c") .attr("stroke-width", 2) .attr("fill", "none");
var data = [ 2, 3, 5, 7, 11, 13, 17, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61 ]; d3.select("#bar").selectAll("div") .data(data) .enter() .append("div") .style("display", "inline-block") .style("width", "20px") .style("margin-right", "2px") .style("background-color", "#9b59b6") .style("height", function(d) { var barHeight = d * 5; return barHeight + "px"; });
var svg = d3.select("#circle") .append("svg").attr("width",700).attr("height",400); var circle = svg.append("circle") .attr("cx",300) .attr("cy",200) .attr("r",180) .attr("fill","#28cca3") .attr("stroke","#2efac7") .attr("stroke-width",10);
circle // 円の遷移(transition)を設定する .transition() // どれくらいの時間をかけて行うか .duration(800) // ランダムに移動 .attr("cx", function() { return Math.random() * w; }) .attr("cy", function() { return Math.random() * h; }) // イージング(モーションの加速、減速)のオプション .ease("bounce")
var w = 700; var h = 300; var radiuses = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43]; var color = ["#bdc3c7", "#f39c12", "#2ecc71", "#e74c3c", "#2c3e50", "#3498db", "#8e44ad", "#e67e22", "#1abc9c", "#f1c40f"]; var svg = d3.select("#transition").append("svg") .attr("width", w).attr("height", h);
svg.selectAll("circle") .data(radiuses) .enter() .append("circle") .attr("cx", function(d) { return Math.random() * w; }) .attr("cy", function(d) { return Math.random() * h; }) .attr("fill", function(d, i) { return color[i]; }) // 半径を0に設定しておく(ease以下のattrで上書き) .attr("r", 0) .transition() // 円の生成タイミングをずらす .delay(function(d, i) { return i * 100; }) .duration(1000) .ease("bounce") .attr("r", function(d) { return d; });
svg.selectAll("circle") .data(radiuses).enter().append("circle") .attr("cx", function(d, i) { return 30 + ( i * 100); }) .attr("cy", function(d) { return h / 2; }) .attr("fill", function(d, i) { return color[i]; }) .attr("r", function(d) { return d; }) // マウスオーバー時に円の色を変更 .on("mouseover", function(d) { d3.select(this).attr("fill", "#2c3e50"); }) // マウスアウト時に円の色を元の色に変更 .on("mouseout", function(d, i) { d3.select(this).attr("fill", color2[i]); }) // クリックされた円を削除 .on("click", function(d) { d3.select(this).remove(); });
// linear:スケールの仕方 var xScale = d3.scale.linear() // 表示するデータの範囲を設定 .domain([0, d3.max(data)]) // 表示する領域を設定 .range([0, w]) // キリの良い数字にして表示 .nice(); svg.selectAll("rect") .data(data) .enter() .append("rect") .attr("x", 0) .attr("y", function(d, i) { return i * 30; }) // 表示領域の幅とデータから表示する棒の幅を設定 .attr("width", function(d) { return xScale(d); }) .attr("height", 20) .attr("fill", "#e67e22");
// 軸の両サイドのラベル文字が切れないようにpaddingを設定 var padding = 20; var xAxis = d3.svg.axis() .scale(xScale) // 目盛を出す方向 .orient("bottom"); svgAxis.append("g") .attr("class", "axis") // 軸を高さ-20pxに移動 .attr("transform", "translate(0," + (h-20) + " )") .attr("font-size", "14px") .attr("fill", "none") .attr("stroke", "black") .call(xAxis);
// 均等目盛 var xScale = d3.scale.linear() // 開平目盛 // var xScale = d3.scale.sqrt() .domain([0, d3.max(data)]) .range([padding, w - padding]) .nice();
Galleryにあったように、D3.jsでは複雑なグラフを作成することが出来ます。
D3.jsでは複雑なグラフのレイアウトをあらかじめ提供していますので、紹介します。
それぞれ使い方が異なりますので、APIリファレンスやサンプルから使い方を理解してください。
https://github.com/mbostock/d3/wiki/Bundle-Layout
https://github.com/mbostock/d3/wiki/Chord-Layout
https://github.com/mbostock/d3/wiki/Cluster-Layout
https://github.com/mbostock/d3/wiki/Force-Layout
https://github.com/mbostock/d3/wiki/Histogram-Layout
https://github.com/mbostock/d3/wiki/Pack-Layout
https://github.com/mbostock/d3/wiki/Partition-Layout
https://github.com/mbostock/d3/wiki/Pie-Layout
https://github.com/mbostock/d3/wiki/Stack-Layout
https://github.com/mbostock/d3/wiki/Tree-Layout
https://github.com/mbostock/d3/wiki/Treemap-Layout
// 描画領域の設定 var margin = {top: 20, right: 120, bottom: 80, left: 60}, width = 1000 - margin.left - margin.right, height = 700 - margin.top - margin.bottom; // 利用する色のカテゴリー var color = d3.scale.category10(); // X軸の範囲 var x = d3.time.scale() .range([0, width]); // Y軸の範囲 var y = d3.scale.linear() .range([height, 0]);
// X軸のラベル位置 var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); // Y軸のラベル位置 var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .x(function(d) { return x(d.year); }) .y(function(d) { return y(d.GDP); }); var svg = d3.select("#graph").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("http://example.com/sales/csv", function(error, data) { // ドメイン毎の色の設定 // filterでheaderのkeyが"年"のカラムを取り除く color.domain(d3.keys(data[0]) .filter(function(key) { return key !== "年"; })); data.forEach(function(d) { // Date形式にparse d.year = d3.time.format("%Y").parse(d["年"]); }); var industries = color.domain().map(function(name) { return { name: name, values: data.map(function(d) { return {year: d.year, GDP: +d[name]}; }) }; });
// X軸、Y軸のラベルの範囲を最小、最大値から設定する x.domain(d3.extent(data, function(d) { return d.year; })); y.domain([ d3.min(industries, function(j) { return d3.min(j.values, function(v) { return v.GDP; }); }), d3.max(industries, function(j) { return d3.max(j.values, function(v) { return v.GDP; }); }) ]);
// X, Y軸に単位を追加 svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll("text") .style("text-anchor", "end") .attr("dx", "-.8em") .attr("dy", ".15em") .attr("transform", "rotate(-65)"); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("10億円");
var industry = svg.selectAll(".industry") .data(industries) .enter().append("g") .attr("class", "industry"); // 各業種毎のライン industry.append("path") .attr("class", "line") .attr("d", function(d) { return line(d.values); }) .style("stroke", function(d) { return color(d.name); });
// 各ラインの業種 industry.append("text") .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) .attr("transform", function(d) { return "translate(" + x(d.value.year) + "," + y(d.value.GDP) + ")"; }) .attr("x", 3) .attr("dy", ".35em") .text(function(d) { return d.name; }); });
ナガイ(´・ω・`)
まだアニメーションとかつけてない…
// SVGのサイズなどを設定 var svg = dimple.newSvg("#graph", 1000, 700); var margin = {top: 70, right: 10, bottom: 80, left: 100}, width = 1000 - margin.left - margin.right, height = 700 - margin.top - margin.bottom; // CSV読込 d3.csv("http://example.com/sales/csv", function (data) { // データをdimple.js用に整形 data = $.map($.map(data, function(row) { return $.map(d3.keys(row).filter(function(key) { return key !== "年"; }), function(key) { return {"年": row["年"], "業種": key,"GDP": row[key]};})}), function(n){ return n;})
var myChart = new dimple.chart(svg, data); myChart.setBounds(margin.left, margin.top, width, height); // X軸の設定 var x = myChart.addTimeAxis("x", "年", "%Y", "%Y"); x.showGridlines = true; // Y軸の設定 var y = myChart.addMeasureAxis("y", "GDP"); y.showGridlines = true; // 設定しない場合は"140k"のように表示される(%などを追加したい場合に利用) y.tickFormat = ""; // ラインのプロット myChart.addSeries("業種", dimple.plot.line);
// 凡例の追加 var myLegend = myChart.addLegend(100, 10, 900, 40, "left"); myChart.draw(); // フォントサイズの変更 myLegend.shapes.selectAll(".legendText") .style("font-size", "12px"); // X軸のテキスト(年)を斜めに回転 x.shapes.selectAll("text").attr("transform", function (d) { return d3.select(this).attr("transform") + " translate(25, 40) rotate(-160)"; }); });
// CSV読込 d3.csv("http://example.com/sales/csv", function(data) { nv.addGraph(function() { // X軸、Y軸に設定する項目と、表示範囲、色の設定 var chart = nv.models.lineChart() .x(function(d) { return d["年"]; }) .y(function(d) { return d["GDP"]; }) .yDomain([0,140000]) .color(d3.scale.category10().range());
// データをNVD3用に整形 var keys = d3.keys(data[0]).filter(function(key) { return key !== "年"; }); data = $.map(keys, function(key){ return {"key": key, "values": $.map(data, function(row) { return {"年":parseInt(row["年"]), "GDP":parseInt(row[key])}; })};}) // チャート作成 d3.select('#graph svg') .datum(data) .transition().duration(2000) .call(chart); return chart; }); });