admin管理员组

文章数量:1356509

I create rectangles in my SVG element using this code:

    var rectangles = svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect");

    rectangles.attr("x", function (d) {
            return xScale(getDate(d));
            //return xScale(d.start);
        })
        .attr("y", function (d, i) {
            return (i * 33);
        })
        .attr("height", 30)
        .transition()
        .duration(1000)
        .attr("width", function (d) {
            return d.length;
        })
        .attr("rx", 5)
        .attr("ry", 5)
        .attr("class", "rectangle")
        .attr("onclick", function (d) {
            return "runaction(" + d.start + ")";
        });

How can I create new rectangles on top of the previous ones?

I create rectangles in my SVG element using this code:

    var rectangles = svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect");

    rectangles.attr("x", function (d) {
            return xScale(getDate(d));
            //return xScale(d.start);
        })
        .attr("y", function (d, i) {
            return (i * 33);
        })
        .attr("height", 30)
        .transition()
        .duration(1000)
        .attr("width", function (d) {
            return d.length;
        })
        .attr("rx", 5)
        .attr("ry", 5)
        .attr("class", "rectangle")
        .attr("onclick", function (d) {
            return "runaction(" + d.start + ")";
        });

How can I create new rectangles on top of the previous ones?

Share Improve this question edited Aug 9, 2013 at 20:24 Christopher Chiche 15.4k9 gold badges64 silver badges100 bronze badges asked Aug 9, 2013 at 16:30 BartoszBartosz 4,60211 gold badges45 silver badges70 bronze badges 4
  • 3 sorry, not clear what you want. You mean use the same data list but do something like create another larger or smaller rectangle for each of the ones you created above? – Steve P Commented Aug 9, 2013 at 16:58
  • I create series of rectangles and then want to create another ones on top of the previous to reflect the progress – Bartosz Commented Aug 10, 2013 at 11:37
  • What defines the position of the new rectangles? – Lars Kotthoff Commented Aug 10, 2013 at 14:04
  • Position of new rectangle is the same. Length of it is different and represents percentage of pletion – Bartosz Commented Aug 11, 2013 at 10:51
Add a ment  | 

1 Answer 1

Reset to default 7

This is an answer to this question I got from Scott Murray, author of great introductory tutorials for d3.js http://alignedleft./tutorials/d3/ which helped me a lot with understanding its functionality. I hope he won't mind me putting his answer here for everyone's benefit.

Thank you very much Scott!

And yes, that's absolutely possible. Taking your example, let's say you want to draw one set of circles with the dataset called "giraffeData" bound to them. You would use:

svg.selectAll("circle")
    .data(giraffeData)
    .enter()
    .append("circle");

But then you have a second data set (really just an array of values) called "zebraData". So you could use the same code, but change which data set you reference here:

svg.selectAll("circle")
    .data(zebraData)
    .enter()
    .append("circle");

Of course, this will inadvertently select all the circles you already created and bind the new data to them — which isn't really what you want. So you'll have to help D3 differentiate between the giraffe circles and the zebra circles. You could do that by assigning them classes:

svg.selectAll("circle.giraffe")
    .data(giraffeData)
    .enter()
    .append("circle")
    .attr("class", "giraffe");

svg.selectAll("circle.zebra")
    .data(zebraData)
    .enter()
    .append("circle")
    .attr("class", "zebra");

Or, you could group the circles of each type into a separate SVG 'g' element:

var giraffes = svg.append("g")
                .attr("class", "giraffe");

giraffes.selectAll("circle")
    .data(giraffeData)
    .enter()
    .append("circle");

var zebras = svg.append("g")
                .attr("class", "zebra");

zebras.selectAll("circle")
    .data(zebraData)
    .enter()
    .append("circle");

I'd probably choose the latter, as then your DOM is more cleanly organized, and you don't have to add a class to every circle. You could just know that any circle inside the g with class zebra is a "zebra circle".

本文标签: javascriptd3js create objects on top of each otherStack Overflow