1

I noticed this fantastic example of D3's cluster layout. Instead of having a bounding box; is it possible to force cluster them into a polygon? http://codepen.io/zslabs/pen/MKaRNJ is an example of the polygon shape, but I'm looking for the added benefit of collision detection as well as a performant way of mapping the data. Thanks so much!

Update

https://github.com/d3/d3-shape looks like an interesting library about creating these shapes, I still have not seen an example of plotting and spreading within a defined polygon.

.
Zach
  • 1,185
  • 3
  • 24
  • 60
  • Collision detection is pretty complex and not often useful in data visualisation, so D3 doesn't have a builtin for it. Maybe you should look into using [Box2D](http://box2d.org/)'s—there's [a JavaScript port via emscripten](https://github.com/kripken/box2d.js/). – Anko - inactive in protest Jan 08 '16 at 16:44
  • For fairly simple cases like constraining nodes in a rhombus or something, I'm sure you could figure out the vectors yourself. If you want arbitrary concave dodecahedrons or something though, that's going to be some pain. How much do you want this feature? :D – Anko - inactive in protest Jan 08 '16 at 16:46
  • Hey @Anko thanks for the reply. I think I may be a little too literal with collision detection term; more or less just plotting them within a shape as the D3 example shows. The one I mentioned is a great foundation; but the part that I've had trouble finding is bounding the points randomly within a polygon not simple rectangle and also to spread - not cluster the points. Is this still fundamentally off of D3's capabilities? – Zach Jan 08 '16 at 18:10
  • Here's a similar question about circle packing into a [rectangle](http://stackoverflow.com/questions/13339615/packing-different-sized-circles-into-rectangle-d3-js). – Mark Jan 09 '16 at 15:15
  • Thanks @Mark I'll look into those a bit more. One of my problems (that those seem to also relate to) will be the "amount" of data; potentially 300-400 plot points; so I"ll certainly want to see what the best way around that is. – Zach Jan 11 '16 at 14:33

1 Answers1

3

I was also looking for the same thing and I found this similar thread: Force chart d3.js inside a triangle.

The most voted answer has a method to detect collisions inside a triangle and also propose a generalized version to make it work with a polygon. You can see it in this demo.

One thing that the answer does not mention and that might be useful to you is to compute the center of your different polygons in order to make the different force layouts centered inside those polygons and I would suggest to use polygonCentroid for that.

var polygon = require('d3-polygon');
var polygon_data = [ [0,0], [10, 0], [10, 10], [0, 10]]; // a small box 
var centroid = polygon.polygonCentroid(polygon_data); // [5, 5]

I would definitely love to see this polygon constraint as a feature in d3 but it may be too specific :/

Update:

Just a small correction: the proprosed solution takes account of the polygon's centroid contrary to what I said. My bad.

Update 2:

I've created a block with an implementation for the polygon collision detection: http://bl.ocks.org/pbellon/4b875d2ab7019c0029b636523b34e074.

It uses the collision detection mentionned in the SO's answer I linked & I used it to create a "force" like forceCollide on d3.v4.

It's not perfect but I had a lot of trouble to tweak the way nodes can be repelled from the polygon's border... If anyone has suggestions I would be happy to hear them!

Community
  • 1
  • 1
PierreB
  • 489
  • 3
  • 14