简体   繁体   中英

Processing a multidimensional data array with d3.js

Currently I am learning some "D3.js" and attempting to get my head around the way data is processed and selected.

I'm stuck on the following task I've created for myself.

Ideally, I want something that is functionally equivalent to:

    <svg>
        <circle r=​"20.5" cx=​"100" cy=​"200">​</circle>​
        <circle r=​"20.5" cx=​"300" cy=​"10">​</circle>​
    </svg>

What I have currently (with my logic) is:

    var matrix = [ [{ "x": 100, "y": 200 }], [{ "x": 300, "y": 10 }]];

    var result = d3.select("body").append("svg")  // Append SVG to end of Body
       .data(matrix) // select this data
       .selectAll("g") //g is a svg grouping tag
       .data(function (d) { return d; }) //Unwrap the first part of the array
       .enter() // Grab all the data that is new to the selection in each array
       .selectAll("g") 
       .data(function (d) { return d;}) // foreach each item inside the 1D array
       .enter() // For all the data that doesn't exist already in the SVG
       .append("circle") // Append Circle to the DOM with the following attributes
       .attr("r", 20.5)
       .attr("cx", function (d) { return d.x; })
       .attr("cy", function (d) { return d.y; });
    };

Weirdly enough the following :

 var result = d3.select("body").append("svg")
        .data(matrix)
        .selectAll("g")         
        .enter()            
        .append("circle")
        .attr("r", 20.5)
        .attr("cx", function (d) { return d.x; })
        .attr("cy", function (d) { return d.y; });
    };

Seems somehow able to get the first item in the array but doesn't iterate correctly. I'm not quite sure how it's entering the array.

D3 seems to be quite a big step away from the programming paradigms I'm used to, and more difficult to debug so it would be awesome if someone could explain where I'm going wrong.

Oh, and while the example is quite useless and I could flatten it using the merge command - for the purposes of fully understanding D3 manipulation. I'd like to draw the couple of circles without the merge :)

Thanks!

Seeing you mention that you're new to d3 I'll make a few comments on the basics.

The first is that we're trying to place some svg elements on the DOM, so first we have to have a svg canvas to work on. Typically its set up early in the code and looks something like this:

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

Note that it would be best to define variables for height and width (but I'm being lazy).

So now you have your canvas lets look at how d3 iterates. d3 iterates over an array, so you don't have to have an array within an array for your example as in:

 var matrix = [ { "x": 100, "y": 200 }], [{ "x": 300, "y": 10 }];

Now you're second block of code is almost there, with just a bit of rearrangement. The first thing we need to do is t create placeholders for the circles in your svg canvas using svg.selectAll("circle") . Next we introduce the data to the empty placeholders using data(matrix) and this is bound using 'enter()`. Now all we have to do is append the circles and give them some attributes which is all the rest of the code does

svg.selectAll("circle")
     .data(matrix)
     .enter()
     .append("circle")
     .attr("r", 20.5)
     .attr("cx", function (d) {
         return d.x;
     })
     .attr("cy", function (d) {
         return d.y;
     });

You can see this all put together in this fiddle with some minor changes.

If you want to get to know d3 I'd really recommend get Scott Murray book on d3 it's an excellent introduction

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM