使用D3.js创建符号生成器

时间:2016-01-08 14:30:22

标签: d3.js

我使用函数d3.svg.symbol()在折线图上绘制符号。

我写了code,但没有任何反应。

生成符号的部分是:

svg.selectAll("path")
.data(donnees)
.enter().append("path")
.attr("transform", function(d) { return "translate(" + xScale(d.xValue) + "," + yScale(d.yValue) + ")"; })
.attr("d", d3.svg.symbol());

1 个答案:

答案 0 :(得分:2)

首先,让我们谈谈您的数据。您有一个带有键和值结构的对象。你通过迭代你的对象给出了d3可以使用的东西:

for (var i in donnees) {
  svg.append("path")
  ...

虽然这有效,但我们可以做得更好。假设我们尝试:

var data = d3.entries(donnees);

返回:

[Object             ,Object         ,Object]
   key: "Cbio"       key: "Cres"
   value: Array[10]  value: Array[10]

现在我们谈论的是d3真正喜欢的一些数据。因此,我们可以重写你的线条图。

首先,为每一行创建一个组:

var lineGroup = svg.selectAll(".line")
  .data(data)
  .enter()
  .append("g")
  .attr("class", "line");

现在,所有的线路:

lineGroup
  .append("path")
  .attr("d", function(d){
    return line(d.value);
  })
  .attr("fill", "none")
  .attr("stroke", function(d,i){
    return colors(i);
  })
  .attr("stroke-width", 1);

最后,让我们做一些符号:

var types = ["circle","cross","diamond"];
lineGroup
  .selectAll("symbol")
  .data(function(d){
    return d.value; //<-- this is a subselection, and allows you to build a symbol for each datapoint of your line
  })
  .enter()
  .append("path")
  .attr("transform", function(d) { 
    return "translate(" + xScale(d.xValue) + "," + yScale(d.yValue) + ")"; 
  })
  .attr("d", function(d,i,j){ //<-- the j here is the parent selection, each lineGroup
    return d3.svg.symbol()
      .type(types[j])(d); //<-- fancy up our symbols
  })
  .attr("fill", function(d,i,j){
    return colors(j);
  });

完整代码:

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  <style>
    .axis path,
    .axis line {
      fill: none;
      stroke: #000;
      shape-rendering: crispEdges;
    }
    
    .axis text {
      font-family: sans-serif;
      font-size: 11px;
    }
  </style>
</head>

<body>
  <script>
    var w = 500,
      h = 400,
      padding = 30;

    var donnees = {
      "Cbio": [{
        "xValue": 1,
        "yValue": 21
      }, {
        "xValue": 20,
        "yValue": 150
      }, {
        "xValue": 40,
        "yValue": 200
      }, {
        "xValue": 60,
        "yValue": 150
      }, {
        "xValue": 80,
        "yValue": 125
      }, {
        "xValue": 100,
        "yValue": 100
      }, {
        "xValue": 120,
        "yValue": 90
      }, {
        "xValue": 140,
        "yValue": 80
      }, {
        "xValue": 160,
        "yValue": 80
      }, {
        "xValue": 180,
        "yValue": 40
      }],
      "Cres": [{
        "xValue": 1,
        "yValue": 350
      }, {
        "xValue": 20,
        "yValue": 30
      }, {
        "xValue": 40,
        "yValue": 20
      }, {
        "xValue": 60,
        "yValue": 30
      }, {
        "xValue": 80,
        "yValue": 30
      }, {
        "xValue": 100,
        "yValue": 30
      }, {
        "xValue": 120,
        "yValue": 20
      }, {
        "xValue": 140,
        "yValue": 30
      }, {
        "xValue": 160,
        "yValue": 30
      }, {
        "xValue": 180,
        "yValue": 30
      }],
      "tsol84": [{
        "xValue": 1,
        "yValue": 10
      }, {
        "xValue": 20,
        "yValue": 15
      }, {
        "xValue": 40,
        "yValue": 20
      }, {
        "xValue": 60,
        "yValue": 25
      }, {
        "xValue": 80,
        "yValue": 30
      }, {
        "xValue": 100,
        "yValue": 25
      }, {
        "xValue": 120,
        "yValue": 25
      }, {
        "xValue": 140,
        "yValue": 25
      }, {
        "xValue": 160,
        "yValue": 30
      }, {
        "xValue": 180,
        "yValue": 25
      }]
    };

    var svg = d3.select("body")
      .append("svg")
      .attr("width", w)
      .attr("height", h);
    
    var data  = d3.entries(donnees);

    var xScale = d3.scale.linear()
      .domain([0, 
        d3.max(d3.max(data, function(d) {
          return d.value;
        }), function(d){
          return d.xValue;
        })
      ])
      .range([padding, w - padding]);
    var yScale = d3.scale.linear()
      .domain([0, d3.max(d3.max(data, function(d) {
          return d.value;
        }), function(d){
          return d.yValue;
        })
      ])
      .range([h - padding, padding]);
    var xAxis = d3.svg.axis()
      .scale(xScale)
      .orient('bottom');
    var yAxis = d3.svg.axis()
      .scale(yScale)
      .orient('left');
    svg.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(0," + (h - padding) + ")")
      .call(xAxis);
    svg.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(" + padding + ",0)")
      .call(yAxis);

    var line = d3.svg.line()
      .x(function(d) {
        return xScale(d.xValue)
      })
      .y(function(d) {
        return yScale(d.yValue)
      });
      
    var colors = d3.scale.category20();

    var lineGroup = svg.selectAll(".line")
      .data(data)
      .enter()
      .append("g")
      .attr("class", "line");
      
    lineGroup
      .append("path")
      .attr("d", function(d){
        return line(d.value);
      })
      .attr("fill", "none")
      .attr("stroke", function(d,i){
        return colors(i);
      })
      .attr("stroke-width", 1);
      
    var types = ["circle","cross","diamond"];
    lineGroup
      .selectAll("symbol")
      .data(function(d){
        return d.value;
      })
      .enter()
      .append("path")
      .attr("transform", function(d) { 
        return "translate(" + xScale(d.xValue) + "," + yScale(d.yValue) + ")"; 
      })
      .attr("d", function(d,i,j){
        return d3.svg.symbol()
          .type(types[j])(d);
      })
      .attr("fill", function(d,i,j){
        return colors(j);
      });
      
  </script>
</body>

</html>