d3 bubble force layout with anchored centre node - d3.js

I've been trying to implement a d3 bubble force layout (someone else's existing example here: http://jsfiddle.net/andycooper/PcjUR/1/) but with one added requirement...
I want the bubbles to collect around a centre node which will 1) be the largest node, and 2) shouldn't move. In order to achieve that, I'm hoping to simply create a new svg circle (i.e. avoid adding to the data set in the variable "nodes") that I can then somehow reference in the following method to prevent collisions with it....
function collide(alpha) {
...
}
Sorry for such an open-ended question, but does anyone know if this is possible? (or hopefully has been attempted somewhere before?) So far the only d3 bubble force layouts I've seen have shown ALL nodes with movement bound by force.
Really appreciate any advice!

Related

Transition Between Curve Types Using D3.js

I'd like to transition between curve types using D3.js.
Take a look at this block. The data stay the same but the curve type changes. I was expecting the paths to maintain their approximate positions on the plane -- the data stay the same, after all -- but they don't. The paths appear to be redrawn, although I don't understand why with basis to linear the paths seem to be redrawn from left to right whilst with linear to basis the paths seem to be redrawn from right to left.
I've read Mike Bostock's post on Path Transitions, but I think this is a slightly different problem. There, the data change but the curve type remains the same. Here, the data stay the same but the curve type changes.
Thanks in advance for any help!
To understand why you have such a strange transition, let's compare the d attribute of the paths using a curveBasis and a curveLinear.
First, a curveBasis:
d="M0,101.2061594964L45.48756294826797,89.52282837400001C90.97512589653594,77.83949725160001,181.95025179307189,54.47283500680002,271.46268884480395,84.08731623460001C360.975125896536,113.70179746240001,449.0248741034641,196.2974221628,538.5373111551961,222.09899531679994C628.0497482069281,247.90056847079998,719.0248741034642,216.90809007840002,764.512437051732,201.4118508822L810,185.915611686"
Now a curveLinear (same data):
d="M0,101.2061594964L272.92537768960784,31.10617276200003L537.0746223103922,278.89304686319997L810,185.915611686"
As you can see, the path is way simpler with curveLinear. So, the strange transition is the expected behaviour.
A possible solution is using a path interpolation, as proposed in this code from Mike Bostock.
Here is your bl.ocks with a path interpolation: http://blockbuilder.org/anonymous/02125b1fb145a979e53f369c4976a772
PS: If you want to avoid that strange transition when you load the page (all paths coming from the top left corner), draw them the first time using a regular attr method.

D3js text too small

I made a simple tree structure and displayed it using D3.js. When nodes become too many, it's impossible to see any text.
Fig1 Fig2
I could make an image out of the svg, then render it instead of displaying the tree by d3js and finally using a magnifier to zoom in. I don't know if it can actually work; is there a better and working way to do it?
Well first of all I would recomend placing your lable below the nodes rather than to the right as that will win you some space back but that won't really solve your problem.
I would recomend either making your tree colapse by node
or defining the space between the nodes as a function of how many children there are. For this, you will need to recursively count the children in your tree. You can see how to do that in an answer I gave here
There are likely other solutions but those are the two that jump out at me as the best.

Algorithm for items placement

I have a "complex" problem where I have a bunch of tooltips (orange) on top of elements (black) that can be randomly placed on screen. The tooltips are a big square with a triangle in the middle of one of it's 4 sides pointing though the element direction. By default, the triangle will be in the middle of the element, but can be moved as long as it stay close to it, so we can't easily understand it refer to this element and not another one.
The problem is, the tooltip must NOT overlap each other, and can't be out of screen.
Image of my tooltip problem
I thought about first placing every tooltips to their default position (triangle pointing down), and then check if they are out of screen or overlap another one, and if so, try another position. But using this technique (which is probably the simplest one), I do not guarantee the best placement since once a tooltip has been placed, I will not replace him if another one can't fit anywhere otherwise it become too complex.
Does someone have any tips/idea how to deal with this type of problem?
Thanks!!
This looks like an instance of the map labelling problem. Wikipedia has an article about it.
You could place all the tooltips using some sort of physical simulation of repulsive electrical charges, similar to what is done in some algorithms for drawing graphs. You could model each tooltip as an object attached with a soft spring to its black box, while simulating a strong repulsive force between all the tooltips and between a tooltip and the edge of the image. You calculate all the forces and move the tooltips iteratively, until all positions converge. You could play with making the force scale as inverse square, inverse cube, etc to find nice results.
This might be a bit of work to implement, but should probably give decent results for simple cases. It is probably impossible to guarantee that a good solution always exists, since if you add too many tooltips, your image will be full.

d3 edges overlap node

I created a network in D3.js that updates links (both remove and add) as you move the slider back and forth.
However the edges overlap the nodes (as in edges are drawn ontop of the nodes...)
I think https://github.com/agfk/knowledge-maps/issues/1 looks at the issue but I'm not quite sure what it means.
I might have something to do with the order that the lines are drawn as opposed to the nodes but I don't know how to fix that. Svgs also don't come with z-indexes so I can manipulate it through css.
Any help would be appreciated! Thanks!
This link discusses how to determine the order in which elements are drawn. In your case, perhaps you want to draw the edges first and then the nodes:
https://groups.google.com/forum/?fromgroups=#!topic/d3-js/JCXKef_GRCQ

d3.js forced directed graph effects on enter

I use d3.js exactly as shown here but with different data value.
When the graph is first shown all elements are scattered and for around a second rapidly move towards their position. This looks nice in the sample, but for my data it does not look so nice. Any way to turn it off so that nodes start in their designated place? Any way to customize this entry visualization?
You can loop through the nodes array and set the .x/.y and .px/.py values to an initial position that you want the nodes in, and by doing so will limit the amount they need to move in their initial layout. If you turn off the force-directed algorithm (the tick() function) then you can apply standard .transtion().duration(500).attr("transform", xx) behavior to the nodes and links to make them animate in a manner you prefer before or after running the force-directed algorithm, but make sure you set the .x/.y and .px/.py attributes to their final position, otherwise they will be reset as soon as you .tick()

Resources