Azad Zain
Azad Zain

Reputation: 153

Using d3.js to Draw a dynamic polygon around selected objects in a group

Given below is my code sample, I have tried using css stroke & outline but both are not meeting my requirements i.e, applying stroke to the 'g' will add stroke to all the elements in it, but it will be all around every elements (image 1). I am looking for a single border that is going around the elements. So I tried using css 'outline' to the 'g' tag which results in a rectangle border, again not around the objects collectively (image 2).

Image 1 (using css 'stroke')

enter image description here

Image 2 (using css 'outline' to the 'g')

enter image description here

Image 3 (This is what I am trying to achieve)

enter image description here

<g class="selected-group" data-id="24907">
   <polygon fill="#F9E794" points="3476.813,1307.591 3476.813,1308.81 3476.813,1357.5 3425.223,1357.5 3425.223,1308.81 3425.223,1307.591" class="selected" data-id="24907"></polygon>
   <polygon fill="#F9E794" points="3425.223,1307.591 3425.223,1308.81 3425.223,1357.5 3425.223,1404.68 3376.153,1404.68 3376.153,1357.5 3376.153,1307.591" class="selected" data-id="974937"></polygon>
</g>

Appreciate any support on this. ThankYou.

Upvotes: 2

Views: 1267

Answers (1)

Will
Will

Reputation: 453

Is this kind of what you're looking for? This example is not a generalized solution. You need to perform a boolean union of the geometry and render that on top of the other polygons.

// assumes clockwise point ordering
var blocks = [
  ['10,10', '230,10', '230,490', '10,490'],
  ['230,10', '490,10', '490,230', '230,230']
];

var selection = blocks[0];
selection.splice(
  selection.indexOf(blocks[1][0]), 1, blocks[1]
);

d3.select('svg')
  .selectAll('.area-box')
  .data(blocks)
  .enter()
  .append('polygon')
  .attr('class', 'area-box')
  .attr('points', function (d) { return d.join(' ') });

d3.select('svg')
  .selectAll('.bounding-box')
  .data([selection])
  .enter()
  .append('polygon')
  .attr('class', 'bounding-box')
  .attr('points', function (d) { return d.join(' ') });
.area-box {
  fill: yellow;
  stroke: darkgray;
  stroke-width: 5px;
}
.bounding-box {
  fill: rgba(0,0,0,0);
}
.bounding-box:hover {
  fill: rgba(0,0,0,0.1);
  stroke: red;
  stroke-width: 5px;
  stroke-dasharray: 10;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.js"></script>
<svg width='500' height='500' viewBox='0 0 1200 1200'></svg>

Upvotes: 3

Related Questions