I want to render polygon shapes in d3.js – but on the edge of each polygon provide a trash icon so the polygon itself can be removed.
Then keep a track of remaining polygons.
- how do you append circles/trash icons to the edge of polygon boundaries – near the top of the shape?
- how do you make/render trash icons – a png image or another svg shape that gets attached
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
$(document).ready(function() {
var vis = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 667);
var scaleX = d3.scale.linear()
.domain([-30, 30])
.range([0, 600]);
var scaleY = d3.scale.linear()
.domain([0, 50])
.range([500, 0]);
var data = [{
"code": "BR23",
"points": "405,100.5625,331,108.5625,300,120.5625,290,141.5625,283,158.5625,278,171.5625,289,209.5625,304,231.5625,332,255.5625,351,264.5625,383,268.5625,400,266.5625,440,266.5625,462,266.5625,510,257.5625,522,230.5625,530,210.5625,534,183.5625,524,163.5625,512,148.5625,490,134.5625,462,124.5625"
},
{
"code": "FR23",
"points": "702,164.5625,594,250.5625,689,324.5625,749,261.5625,770,206.5625"
}
];
vis.selectAll("polygon")
.data(data)
.enter().append("polygon")
.attr("points", function(d, i) {
return d.points
})
.attr("fill", "transparent")
.attr("stroke", "red")
.attr("stroke-width", 2)
.style("stroke-dasharray", ("15, 15")) // <== This line here!!
.on("click", function(d, i) {
console.log("d", d);
d3.select(this).style("fill", "blue");
});
vis.append('circle')
.attr('cx', 110)
.attr('cy', 110)
.attr('r', 20)
.attr('stroke', 'black')
.attr('fill', '#69a3b2')
.on("click", function(d, i) {
console.log("d", d);
});
});
</script>
do you need to work out boundaries of the shapes?
How to align points on the outer edges of polygon for thicker border in svg?
2
Answers
Remove the first two scripts and use document.querySelectorAll, then it works.
Approach 1: Get polygon bounding box
As already mentioned, you need to calculate the bounding box coordinates for each polygon in your data set.
It’s probably more convenient to add these coordinates directly to your data array – so you can use this data within your D3 function chain for positioning.
Here’s a simple helper function:
It loops through all polygon points and calculates the bounding box according to x and y extrema.
The centroid coordinates would be:
If your polygons are already appended to the DOM, you could also use
getBBox()
.Create trash button icon
I’d recommend to design an icon in an editor like inkscape including a background circle. This way you don’t need to append multiple elements (imho, selecting parent nodes in d3 can be a bit "unintuitive" …).
Example
Approach 2: get topmost point on polygon outline
Similar to the first approach, we’re updating the initial data object.
This time we’re searching the top most point on the polygon’s outline.
We get this point by comparing the y values of each polygon vertice.