D3.js

データビジュアライゼーションのためのD3.js徹底入門 Webで魅せるグラフ&チャートの作り方

データビジュアライゼーションのためのD3.js徹底入門 Webで魅せるグラフ&チャートの作り方

第9章 折れ線グラフまで。 この章は書き間違えをしてしまって、それがどこを間違えているのかをステップ実行などで調べたりしたので、とても時間がかかった。 ただ、そのおかげで全然まだまだ理解できていないことが理解できた。 この書籍をとりあえず通しで写経したのち、実践が必要だ。

<!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: 9pt;
      }
      .axis path, .axis line {
        fill: none;
        stroke: black;
      }
      .axis_x line {
        fill: none;
        stroke: black;
      }
      .line { fill: none; stroke: black; }
      /*.itemA { stroke: #000; fill: cyan; }*/
      .itemA { stroke: blue; }
      .itemB { stroke: red; }
      .itemC { stroke: green; }
      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>
          <button type="button" name="button" id="prev">前へ</button>
          <button type="button" name="button" id="next">次へ</button>
        </div>
        <div class="col-sm-4">
        </div>
        <div class="col-sm-4">
        </div>
      </div>
      <script src="sample9.js" charset="utf-8"></script>
    </div>
  </body>
</html>
d3.json("sample9/mydata.json", function(error, data) {
  var dataset = [];
  var svgEle = document.getElementById("myGraph1");
  var svgWidth = parseFloat(window.getComputedStyle(svgEle, null).getPropertyValue("width")) - 60;
  var svgHeight = parseFloat(window.getComputedStyle(svgEle, null).getPropertyValue("height")) - 60;
  var offsetX = 30;
  var offsetY = 20;
  var scale = 2.0;
  var rangeYear = 10;
  // 最大値と最小値
  var year = d3.extent(data, function(d) {
    return d.year;
  });
  var startYear = year[0];
  var currentYear = 2000;
  var margin = svgWidth / (rangeYear - 1);

  pickupData(data, currentYear - startYear);
  drawGraph(dataset, "item1", "itemA", "linear");
  drawGraph(dataset, "item2", "itemB", "basis");
  drawGraph(dataset, "item3", "itemC", "step");
  drawScale();

  function drawGraph(dataset, itemName, cssClassName, type) {
    // var area = d3.svg.area()
    //   .x(function(d, i) {
    //     return offsetX + i * margin;
    //   })
    //   .y0(function(d, i) {
    //     return svgHeight - offsetY;
    //   })
    //   .y1(function(d, i) {
    //     return svgHeight - (d * scale) - offsetY;
    //   })
    //   .interpolate(type);
    var line = d3.svg.line()
      .x(function(d, i) {
        return offsetX + i * margin;
      })
      .y(function(d, i) {
        return svgHeight - (d[itemName] * scale) - offsetY;
      })
      .interpolate(type);

    var lineElements = d3.select("#myGraph1")
      .append("path")
      .attr("class", "line " + cssClassName)
      .attr("d", line(dataset));
      // .attr("d", area(dataset));
  }

  function drawScale() {
    var yScale = d3.scale.linear()
      .domain([0, 100])
      .range([scale * 100, 0]);

    d3.select("#myGraph1")
      .append("g")
      .attr("class", "axis")
      .attr("transform", "translate(" + offsetX + ", " + ((100 - (scale - 1) * 100) + offsetY) + ")")
      .call(
        d3.svg.axis()
          .scale(yScale)
          .orient("left")
      );

    var xScale = d3.time.scale()
      .domain([new Date(currentYear + "/1/1"), new Date((currentYear + rangeYear - 1) + "/1/1")])
      .range([0, svgWidth]);

    d3.select("#myGraph1")
      .append("g")
      .attr("class", "axis")
      .attr("transform", "translate(" + offsetX + ", " + (svgHeight - offsetY) + ")")
      .call(
        d3.svg.axis()
          .scale(xScale)
          .orient("bottom")
          .ticks(10)
          .tickFormat(function(d, i) {
            var fmtFunc = d3.time.format("%Y年%m月");
            return fmtFunc(d);
          })
      )
      .selectAll("text")
      .attr("transform", "rotate(90)")
      .attr("dx", "0.7em")
      .attr("dy", "-0.4em")
      .style("text-anchor", "start");
  }

  function pickupData(data, start) {
    dataset = [];
    for (var i = 0; i < rangeYear; i++) {
      dataset[i] = data[start + i];
    }
    d3.select("#myGraph1").selectAll("*").remove();
  }

  d3.select("#prev").on("click", function() {
    if (currentYear > year[0]) {
      currentYear = currentYear - 1;
    }

    pickupData(data, currentYear - startYear);
    drawGraph(dataset, "item1", "itemA", "linear");
    drawGraph(dataset, "item2", "itemB", "linear");
    drawGraph(dataset, "item3", "itemC", "linear");
    drawScale();
  });

  d3.select("#next").on("click", function() {
    if (currentYear <= year[1] - rangeYear) {
      currentYear = currentYear + 1;
    }

    pickupData(data, currentYear - startYear);
    drawGraph(dataset, "item1", "itemA", "linear");
    drawGraph(dataset, "item2", "itemB", "linear");
    drawGraph(dataset, "item3", "itemC", "linear");
    drawScale();
  });
});

f:id:yossk:20150613101956j:plain