如何根据数据添加具有D3 append()函数的可变数量的节点

时间:2014-02-06 12:10:11

标签: javascript svg d3.js

为了说明这个问题,让我们采用以下简单的数据示例,其中有一个要显示的对象列表。每个对象由一个形状和一个变量行列表组成

var data = [
    {
        "shape": "circle",
        "x": 10,
        "y": 20,
        "lines": [
            {x1: "-10", y1: "-10", x2: "10", y2: "10"}
        ]
    },
    {
        "shape": "rect",
        "x": 30,
        "y": 20,
        "lines": [
            {x1: "-10", y1: "-10", x2: "10", y2: "10"}
        ]
    },
    {
        "shape": "circle",
        "x": 50,
        "y": 20,
        "lines": [
            {x1: "-10", y1: "-10", x2: "10", y2: "10"},
            {x1: "-10", y1: "10", x2: "10", y2: "-10"}
        ]
    },
    {
        "shape": "rect",
        "x": 70,
        "y": 20,
        "lines": [
            {x1: "-10", y1: "-10", x2: "10", y2: "10"},
            {x1: "-10", y1: "10", x2: "10", y2: "-10"}
        ]
    }
];

我知道我可以使用filter()函数来区分形状,这样我就可以创建这样的形状:

var shapes = svg.selectAll(".shape")
        .data(data)
        .enter()
        .append("g")
        .attr("transform", function (d) {
            return "translate(" + d.x + "," + d.y + ")";
        });

var circles = shapes.filter(function (d) {
    return d.shape == "circle"
})
        .append("circle")
        .attr("r", 10);

var rect = shapes.filter(function (d) {
    return d.shape == "rect"
})
        .append("rect")
        .attr("transform", "translate(-5, -5)")
        .attr("width", 10)
        .attr("height", 10);

我的问题是根据数据附加可变数量的行。

我看到我怎么能只发生这样的第一行:

shapes.append("line")
        .attr("stroke", "red")
        .attr("x1", function (d) {
            return d.lines[0].x1
        })
        .attr("y1", function (d) {
            return d.lines[0].y1
        })
        .attr("x2", function (d) {
            return d.lines[0].x2
        })
        .attr("y2", function (d) {
            return d.lines[0].y2
        })

但如果行数可变,我不知道怎么做。

实现这个目标的正确方法是什么?

我在这里创建了一个小例子:http://jsfiddle.net/Lm8XB/1/

1 个答案:

答案 0 :(得分:0)

正确的方法是使用nested selection。也就是说,将行数据再次绑定到line元素,引用先前绑定的数据:

shapes.selectAll("line").data(function(d) { return d.lines; })
      .enter().append("line")

然后,您可以在设置参数时直接引用坐标:

.attr("x1", function (d) {
            return d.x1
        })
        .attr("y1", function (d) {
            return d.y1
        })
        .attr("x2", function (d) {
            return d.x2
        })
        .attr("y2", function (d) {
            return d.y2
        })

完整示例here