In a force layout, I'd like to slow down the animation when two distant nodes are linked.
For example: if I have 2 nodes that are 400px apart and a link is established between them (after the inital tick has completely cooled down), I'd like to link to start at 400px and then animate down towards say 100 (or as standard link distance is set).
You can set the linkStrength to a lower value to make the linking less abrupt. Like so:
force.linkStrength(0.1);
linkStrength is a value between 0 and 1.
https://github.com/mbostock/d3/wiki/Force-Layout#linkStrength
Related
I'm showing network throughput and disk io's in a graph.
But when there is no activity. 0 get's reported.
The balloon shows me 0 but the line is not being drawn.
it looks like the grid is on top but if I turn the grid off the line still isn't there.
if I make line-thickness 2, I can see it but then the line changes thickness between 0 value and non 0 value. from 1px to 2 px.
i can't find anything in the documentation about this.
Any clue?
Unfortunately this is a limitation with the library as it doesn't draw lines outside of the plot area so the line will be clipped at the edges as you've noticed. Setting the lineThickness to a larger number like you already did along with setting the valueAxis' zeroGridAlpha property to zero will improve it slightly, but your best bet is setting a small negative minimum in your valueAxis so that the zero line is clearly visible. You can combine this with setting showFirstLabel to false to hide the first negative value in your axis.
Demo
I have a force network graph (in a Drupal site) which does what I want it to (thanks to many members of stackoverflow) but it ends up about 400px from the top and left margins of the content area.(see http://trsg.tcan.ca/stronger-together-network)
Which parameters control this?
The force layout is designed to distribute items in the available space. When you create a force layout, you set the size of the available area, and the nodes are attracted to the center of the area.
You can either set a smaller area for the network chart or lower the attraction between the nodes and the center, by setting the charge attribute of the force to a greater value. The default value is -30, try with -10 or -5.
Assigning the layout to Body instead of a DIV solved the problem. (In most other scripts I had to use a DIV and using Body caused problems.)
The number of nodes in my d3 graph is too large. So I built a zoom mechanism in that graph. Now the problem is, I just cannot display text for each nodes since they will overlap each other. However when I zoom in to the nodes, the space is enough to display texts.
So how do I show texts when the space is enough to show all of them without overlapping?
I have had this same problem in the past. Unfortunately optimal label placement is not an easy problem. To mitigate overlap effects one option is to use a restricted force layout for label placement. You can also try using callouts to allow the labels to move farther away from the nodes.
In the past I have implemented a sort of greedy collision detection based algorithm that goes something like:
sort the labels in decreasing priority
for each label in the list // so most important first
if the label does not overlap any placed labels
place the label and add it to my collision data structure (e.g. quad tree)
else
hide the label
Obviously this will have some non-optimal cases and it can be slow if you have a lot of animations going on. But when you have the option to zoom in to see more label and if your absolute number of labels is not too high then it works quite well. There are also a number of obvious ways to speed it up like restricting testing to only labels within the view (but then you need to update on pan).
You may find some helpful suggestions here including an implementation of collision detection.
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.
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()