7

我一直在玩弄圆包样品。但是,尝试从一组新的 JSON 数据更新事物并在之后刷新它时遇到了很多麻烦。

我的代码只是圆形包示例的修改版本:

var diameter = 960,
    format = d3.format(",d");

var pack = d3.layout.pack()
    .size([diameter - 4, diameter - 4])
    .value(function(d) { return d.size; });

var svg = d3.select("body").append("svg")
    .attr("width", diameter)
    .attr("height", diameter)
    .append("g")
    .attr("transform", "translate(2,2)");

var node;

d3.json("data1.json", function(error, root) {

    node = svg.datum(root).selectAll(".node")
      .data(pack.nodes);

    node.enter().append("g")
      .classed("node", true)
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

    node.append("title")
      .text(function(d) { return d.name; });

    node.append("circle")
            .attr("r", 0)
        .on("click", refresh)
            .transition()
            .duration(2000)
        .attr("r", function(d) { return d.r; });

    node.append("text")
      .attr("dy", ".3em")
      .style("text-anchor", "middle")
      .text(function(d) { return d.name });

    node.exit()
        .remove();
});

d3.select(self.frameElement).style("height", diameter + "px");

这按预期工作。但是,我想做刷新功能,从新的 JSON 数据更新图表并刷新。我已经尝试了下面的代码,但它只是添加了新元素而不是更改旧元素 - 并且也不会删除旧元素(node.exit.remove() 显然永远不会运行)。我想知道它是否与使用“数据”而不是“数据”有关,以及在这方面是否实际上进行了数据连接:

var refresh = function() {

    d3.json("data2.json", function(error, root2) {

        node = svg.datum(root2).selectAll(".node")
            .data(pack.nodes);

        node.append("title")
            .text(function(d) { return d.name; });

        node.append("circle")
            .attr("r", 0)
            .transition()
            .duration(2000)
            .attr("r", function(d) { return d.r; });

        node.append("text")
            .attr("dy", ".3em")
            .style("text-anchor", "middle")
            .text(function(d) { return d.name });
    });
}

我很难弄清楚数据实际上是如何绑定到包的以及如何更新它。我可能再次错过了一些简单的东西,但任何帮助将不胜感激,因为我很难找到说明这一点的样本。如果有人可以在这里帮助我,我将来会很乐意为其他人制作一个。:)

作为记录,我使用的数据是这样的:

{
    "name": "Names",
    "children": [
        { "name": "John", "size": 100 },
        { "name": "Peter", "size": 200 },
        { "name": "Arnold", "size": 300 },
        { "name": "Rasmus", "size": 400 }
    ]
}

{
    "name": "Names",
    "children": [
        { "name": "John", "size": 1000 },
        { "name": "Rasmus", "size": 200 },
        { "name": "Benjamin", "size": 300 },
        { "name": "James", "size": 400 }
    ]
}
4

1 回答 1

7

我很难理解这些包是如何工作的。显然,您只需向他们发送一个数据集,他们就会返回一个可用于绑定的新数据集。比我想象的要简单得多。该解决方案有效,我认为大多数人应该能够从这里继续前进:

var diameter = 960,
    format = d3.format(",d");

var pack = d3.layout.pack()
    .size([diameter - 4, diameter - 4])
    .value(function(d) { return d.size; });

var svg = d3.select("body").append("svg")
    .attr("width", diameter)
    .attr("height", diameter)
  .append("g")
    .attr("transform", "translate(2,2)");

var node;
var currentJson;
var currentUrl = "data1.json";

var getNewData = function() {

    if(currentUrl == "data1.json") {
        currentUrl = "data2.json";
    }
    else {
        currentUrl = "data1.json";
    }

    d3.json(currentUrl, function(error, data) {
        currentJson = data;
        refresh();
    });
}

var refresh = function() {

    node = svg.selectAll(".node")
                    .data(pack.nodes(currentJson));

    node.enter().append("g")
            .classed("node", true)
            .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
        .append("circle")
            .attr("r", 0)
            .on("click", getNewData)
            .transition()
            .duration(2000)
            .attr("r", function(d) { return d.r; });

    node.transition()
        .duration(2000)
        .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

    node.select("circle")
        .transition()
        .duration(2000)
        .attr("r", function(d) { return d.r; });
}

d3.select(self.frameElement).style("height", diameter + "px");

getNewData();
于 2013-09-14T08:27:16.157 回答