使用嵌套数据D3.js进行转换

时间:2017-07-05 20:59:54

标签: d3.js

我最近开始学习D3.js,我正在努力使用以下数据在散点图中创建转换:

var data = [
    {"year" : "2004", "x":100, "y":300, "size": 2, "type": "A"},
    {"year" : "2005", "x":200, "y":200, "size": 2, "type": "A"},
    {"year" : "2006", "x":300, "y":100, "size": 2, "type": "A"},
    {"year" : "2004", "x":150, "y":250, "size": 2.382450, "type": "B"},
    {"year" : "2005", "x":150, "y":250, "size": 3.078548, "type": "B"},
    {"year" : "2006", "x":150, "y":250, "size": 4.265410, "type": "B"}];

在散点图中有2个点(类型A和B),它们按年份改变位置(x& y)和大小。我创建了fiddle,我尝试嵌套数据并绘制点,但是使用transition()函数的下一步是令人困惑的。更具体地说,我仍在声明整个数据,但为了使转换工作,我只需要部分数据。

1 个答案:

答案 0 :(得分:2)

理解你想要的东西的关键在于:

  

有2个点,它们按年度更改位置(x& y)和大小

因此,这显然是XY problem。您的问题不是“如何使用嵌套数据进行转换”。您的问题是“如何按年过渡”

我提出的解决方案首先涉及删除嵌套数组。你不需要那个。

相反,在数据中获取所有年份......

var years = [...new Set(data.map(function(d) {
  return d.year
}))];

...,按年过滤数据......

var dataStart = data.filter(function(d) {
  return d.year === years[0]
});

......并且循环多年。在这里,我正在使用d3.interval()

var counter = 1;
var timer = d3.interval(transition, 1500);

function transition() {

  var newData = data.filter(function(d) {
    return d.year === years[counter]
  });

  svg.selectAll("circle").data(newData)
    .transition()
    .duration(1000)
    .attr("cx", function(d) {
      console.log(d)
      return d.x;
    })
    .attr("cy", function(d) {
      return d.y;
    })
    .attr("r", function(d) {
      return d.size * 10;
    });
  counter += 1;
  if (counter === 3) {
    timer.stop()
  }
}

以下是演示:

var data = [{
      "year": "2004",
      "x": 100,
      "y": 100,
      "size": 2,
      "type": "A"
    }, {
      "year": "2005",
      "x": 200,
      "y": 180,
      "size": 2,
      "type": "A"
    }, {
      "year": "2006",
      "x": 300,
      "y": 50,
      "size": 2,
      "type": "A"
    }, {
      "year": "2004",
      "x": 150,
      "y": 150,
      "size": 2.382450,
      "type": "B"
    }, {
      "year": "2005",
      "x": 150,
      "y": 50,
      "size": 3.078548,
      "type": "B"
    }, {
      "year": "2006",
      "x": 150,
      "y": 100,
      "size": 4.265410,
      "type": "B"
    }];

    var width = 400,
      height = 200;

    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height);

    var years = [...new Set(data.map(function(d) {
      return d.year
    }))];

    var dataStart = data.filter(function(d) {
      return d.year === years[0]
    });

    var cell = svg.selectAll("circle")
      .data(dataStart);

    cell.enter()
      .append("circle")
      .attr("cx", function(d) {
        return d.x;
      })
      .attr("cy", function(d) {
        return d.y;
      })
      .attr("r", function(d) {
        return d.size * 10;
      });

    var counter = 1;
    var timer = d3.interval(transition, 1500);

    function transition() {

      var newData = data.filter(function(d) {
        return d.year === years[counter]
      });

      svg.selectAll("circle").data(newData)
        .transition()
        .duration(1000)
        .attr("cx", function(d) {
          return d.x;
        })
        .attr("cy", function(d) {
          return d.y;
        })
        .attr("r", function(d) {
          return d.size * 10;
        });
      counter += 1;
      if (counter === 3) {
        timer.stop()
      }
    }
<script src="https://d3js.org/d3.v4.min.js"></script>