问题
I have a D3 scatter chart and I'm trying to add the option to view the chart as circles or as images, based on the value of a variable.
At the moment I can view the chart as either (as long as I comment one of them out)
Here is the code for appending the images:
svg.selectAll(".image")
.data(data)
.enter()
.append("svg:image")
.attr("x", xMap)
.attr("y", yMap)
.attr("width", logosize)
.attr("height", logosize)
.attr('transform', function(d) { return 'translate('+ -d.logosize/2 +',' + -d.logosize/2 + ')'; } )
.attr("xlink:href", function(d) {
return d.brand_image;
})
and the code for appending the dots:
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", xMap)
.attr("cy", yMap)
.style("fill", function(d) {
return color(cValue(d));
})
The variable is var displaytype = "image" // or "dot"
I was trying to do something like:
if (displaytype == "image") { return
//....code for images.....
else { return
//....code for dots.....
}
Any help on trying to figure this out would be much appreciated
Thanks
回答1:
Your approach of using if/else is not wrong. What you need to keep in mind is that dots and images are equivalent representations of what I'll call "points". This means that the selection shouldn't distinguish circles from images: it should just select points. This could be done by using a class selector instead of a tag selector.
In your case, the code is using two different class selectors: .dot
and .image
. Instead of svg.selectAll('.image')
and svg.selectAll('.dot')
, you could use svg.selectAll('.point')
for both of them. Thus:
const enterSelection = svg.selectAll(".point").data(data).enter();
if (displaytype == "image") {
enterSelection
.append("svg:image")
.attr("class", "point")
.attr("x", xMap)
.attr("y", yMap)
.attr("width", logosize)
.attr("height", logosize)
.attr("transform", function (d) {
return "translate(" + -d.logosize / 2 + "," + -d.logosize / 2 + ")";
})
.attr("xlink:href", function (d) {
return d.brand_image;
});
} else {
enterSelection
.append("circle")
.attr("class", "point")
.attr("r", 3.5)
.attr("cx", xMap)
.attr("cy", yMap)
.style("fill", function (d) {
return color(cValue(d));
});
}
来源:https://stackoverflow.com/questions/65849641/d3-conditionally-append-image-or-circle-element-based-on-variable