Reputation: 91
My app is supposed to append different elements to the SVG depending on the data type. My code more or less looks like this:
var elements = svg.selectAll(".elements")
.data(someData)
.enter().append("g");
var circles = elements.filter(function (d,i) {
return d.type == "category1"
})
.append("circle")
var rectangles = smallCircles.filter(function (d,i) {
return d.type == "category2"
})
.append("rect")
So, if the data.type = "catgory1", the programme should append a circle, if it is equal to "category2", it should append a rectangle. The problem I'm having is that I'm setting their position on the SVG based on their individual indices ("i" in function(d,i)). However, in order to do so I need the sequence of indices to be consistent among those two element types. Is there a better way to do it than just use a external variable that would ++ everytime a new element gets appended?
Upvotes: 2
Views: 381
Reputation: 108517
Couple ways you could do this.
First, You could use a .each
and encapsulate the appending logic:
var elements = svg.selectAll(".elements")
.data([
{
type: "category1"
},{
type: "category2"
}
])
.enter().append("g");
elements.each(function(d,i){
// i is index on everything
var self = d3.select(this);
switch(d.type) {
case "category1":
self.append("circle");
break;
case "category2":
self.append("rect");
break;
default:
break;
}
});
Or, second, a better way to do this would be to make your elements part of your data:
var data = [
{
type: "category1"
},{
type: "category2"
}
];
data.forEach(function(d){
switch(d.type) {
case "category1":
d.elem = "circle"
break;
case "category2":
d.elem = "rect"
break;
default:
break;
}
});
var svg = d3.select('body').append('svg');
var elements = svg.selectAll(".elements")
.data(data)
.enter().append("g");
elements.append(function(d){
return document.createElement(d.elem);
});
Upvotes: 3