当更新的数据包含其他部分

时间:2017-06-23 12:15:20

标签: javascript d3.js svg

我最近在D3.js上工作了很多,而且我越用它,我就越觉得我做错了什么!

目前,我正在尝试制作一个饼图,允许客户端按下按钮并在显示的信息之间切换。它的设置如下:

var width = 600,
    height = 675;

var outerRadius = 300,
    innerRadius = outerRadius / 3,
    color = d3.scale.category10();

var pie = d3.layout.pie()
    .value(function (d) { return d.value; });

var pieData = pie(dataDefault);

var arc = d3.svg.arc()
    .innerRadius(innerRadius);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + outerRadius + "," + (outerRadius + 50) + ")");

svg.append("text")
    .attr("x", 0)
    .attr("y", -(outerRadius + 10))
    .style("text-anchor", "middle")
    .text("Distrubution of Default Usage");

svg.selectAll("a")
    .data(pieData)
  .enter().append("a")
    .attr("href", function (d, i) { return "" + dataDefault[i].label + "Stats.cshtml"; })
    .append("path")
    .each(function (d) { d.outerRadius = outerRadius - 20; })
    .attr("d", arc)
    .attr("fill", function (d, i) { return color(i); })
    .on("mouseover", arcTween(outerRadius, 0))
    .on("mouseout", arcTween(outerRadius - 20, 150))
        .append("title")
        .text(function (d) { return d.value + " hits"; });

注意某些功能可能很有用,点击切片链接到包含更多信息和特定数据的页面。并且它们会在切片略微增长的情况下产生悬停效果。

数据默认启动,然后按钮将其切换为" dataBrowser。"

dataBrowser = [{ "label": "Edge", "value": 15 },
        { "label": "Chrome", "value": 65 },
        { "label": "Safari", "value": 30 },
        { "label": "Firefox", "value": 40 },
        { "label": "Other", "value": 40 }];

dataDefualt = [{ "label": "", "value": 25 },
        { "label": "", "value": 25 },
        { "label": "", "value": 25 },
        { "label": "", "value": 25 }];

我将新数据传递给pie函数,并将其传递给svg。

    var newData = pie(dataBrowser);
    var newColor = d3.scale.category20c();
    svg.selectAll("a")
         .data(newData)
         .attr("href", "#")
         .select("path")
         .each(function (d) { d.outerRadius = outerRadius - 20; })
         .transition()
         .attr("d", arc)
         .attr("fill", function (d, i) { return newColor(i); })
         .attr("title", function (d) { return d.value; });

(标题的更新不起作用,所以只是忽略它) 这会成功更新每个饼图的大小,但不会为新信息添加新的饼图。如何从我的svg中添加(并随后删除)作品?

提前致谢!

1 个答案:

答案 0 :(得分:2)

如果你想创建一个新元素,你需要追加,最好是在“输入”选择中:

var newSlices = svg.selectAll("a")
    .data(newData);

newSlices.enter()
    .append("a")
    .attr("href", "#")
    .append("path")

newSlices.attr("href", "#")
    .select("path")
    .each(function(d) {
        d.outerRadius = outerRadius - 20;
    })
    .attr("d", arc)
    .attr("fill", function(d, i) {
        return newColor(i);
    })
    .attr("title", function(d) {
        return d.value;
    });

请注意上述代码段依赖于D3 v2和D3 v3的“输入”选项的魔术行为,已在D3 v4.x中删除。在这个新版本中,还必须设置“输入”选择的属性(或使用merge())。

以下是您的工作代码,其中包含一个用于调用更新的按钮:

var width = 300,
  height = 300;

var dataDefault = [{
  "label": "",
  "value": 25
}, {
  "label": "",
  "value": 25
}, {
  "label": "",
  "value": 25
}, {
  "label": "",
  "value": 25
}];

var outerRadius = 100,
  innerRadius = outerRadius / 3,
  color = d3.scale.category10();

var pie = d3.layout.pie()
  .value(function(d) {
    return d.value;
  });

var pieData = pie(dataDefault);

var arc = d3.svg.arc()
  .innerRadius(innerRadius);

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + outerRadius + "," + (outerRadius + 50) + ")");

svg.append("text")
  .attr("x", 0)
  .attr("y", -(outerRadius + 10))
  .style("text-anchor", "middle")
  .text("Distrubution of Default Usage");

svg.selectAll("a")
  .data(pieData)
  .enter()
  .append("a")
  .attr("href", function(d, i) {
    return "" + dataDefault[i].label + "Stats.cshtml";
  })
  .append("path")
  .each(function(d) {
    d.outerRadius = outerRadius - 20;
  })
  .attr("d", arc)
  .attr("fill", function(d, i) {
    return color(i);
  });

d3.select("button").on("click", function() {
  var dataBrowser = [{
    "label": "Edge",
    "value": 15
  }, {
    "label": "Chrome",
    "value": 65
  }, {
    "label": "Safari",
    "value": 30
  }, {
    "label": "Firefox",
    "value": 40
  }, {
    "label": "Other",
    "value": 40
  }];

  var newData = pie(dataBrowser);
  var newColor = d3.scale.category20();
  var newSlices = svg.selectAll("a")
    .data(newData);

  newSlices.enter()
    .append("a")
    .attr("href", "#")
    .append("path")

  newSlices.attr("href", "#")
    .select("path")
    .each(function(d) {
      d.outerRadius = outerRadius - 20;
    })
    .attr("d", arc)
    .attr("fill", function(d, i) {
      return newColor(i);
    })
    .attr("title", function(d) {
      return d.value;
    });
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<button>Click</button>
<br>