I need to be able to draw links between the circles in a circle pack layout, like {source: i, target: j}. I've seen some questions about how to combine this layout with the force layout that made me think It could be a way to achieve this but I haven't had any luck on that path, also what I need is something completely static. Thank you in advance for any suggestions.
I finally could draw lines between nodes by appending them to the svg and calculating each line position based on the radius of the nodes that each line were to connect, but the problem was that the pack layout that I'm using is zoomable, so when I tried to zoom by clicking the lines neither translate nor re-sized (of course, since there was no code performing such things), so I tried to implement a translation function for the lines so they would move along with the zoom, then I saw that it would take some serious geometry to achieve this, so since I'm a lazy programmer and not at all experienced with d3 I tried to come with something more simple... at last I decided to represent the links between the nodes with a different approach (without lines), I used the "mouseover" event so when the pointer is over a node it will highlight (changed circle stroke attribute color and width) the nodes connected to it. This way I achieved my goal and the view looks a lot cleaner without all the lines crossing over it (they were a lot). I know that some may think that this does not answer the original question, and I'm sure that this can be achieved by someone with more experience (and time and patience) using lines and implementing the right calculation, but in my case this solution solves my problem and maybe it could be of help to others.
Related
First off, i've seen questions like this posted several times, but they are all based on SVG, classes and CSS. I'm aiming at solving this using canvas because my final force layout will use 1000+ nodes and svg just doesn't cut it. Also, I have a background in programming but am total n00b to d3. So maybe i'm just missing something obvious.
Here's my current code:
http://bl.ocks.org/gonzam88/3ff2f33975ca8258f4aa9484be4255ce
I guess on mouseover I have to loop all links and check if either source or target matched the current node, but after many attempts i'm not too sure how to achieve this, and how to change specific links properties (when not using SVG).
I feel i'm close but not just there :)
Thanks for reading and hope my english is ok!
UPDATE 1
I've managed to detect links related to hovered node, but when I try to change its stroke it changes every stroke in my graph.
check:
http://blockbuilder.org/gonzam88/9d48b4346fadb6b719a9ce9efb98a899
In this example I only want each group to change to blue line. But both 'groups' are being changed.
Links are drawn on line 140 and my color function is on line 57. How do set stroke color to specific links?
I'm trying to display a large number of images on a d3 display using T-SNE. The x and y coordinates are pre-calculated, the location on the svg area is adjusted using using translate/zoom.
At the moment they all display using the precalculated coordinates.
and they remain in place as zooming/panning.
I'm looking to use collision detection (like this example) to adjust the images locations slightly so that they don't overlap, but as much as possible maintain the rough global structure.
Here's my attempt so far
https://gist.github.com/GerHarte/329af8ee5ffd8a1f87c5
With this it loads as in the image above, but as soon as I pan or zoom, all the points expand out hugely to a completely different location on the canvas and look like this, they don't seem to overlap, but they're extremely far apart.
Is there something wrong in my code or is there a better way to approach this?
Update:
I followed Lar's answer here, with the slight addition of setting the raw data points to where Lar's code settles since the points are translated when zooming or panning. The results look great (see below), but for a larger number of points (5000+) it seems to crash before converging on a final result.
Are there any suggestions to improve the efficiency with this approach? Going to try the Multi-Foci Forced Directed approach.
Good morning,
just starting with the awesome d3js library ...
I want to show only a portion of a graph with the force directed layout. The idea is to have one node declared as the "center" and show all nodes within a distance of two (for example) from this center node, the neighbors of the center node and the neighbors of the neighbors. If the user clicks on one of the displayed nodes it becomes the "new" center node and a different "subgraph" is displayed. I wonder if there is an example around implementing this kind of subgraph layout and if some kind of a "node-distance" algorithm is already implemented in d3js.
Thanks a lot
martin
UPDATE:
Just found the example Modifying a Force Layout which illuminates how to add and remove nodes and edges from a force directed layout.
I just uploaded a "proof of concept level" of an interactive force directed subgraph.
http://justdharma.com/d3/sub-graph/
In this example I use backbonejs under the hood. Being the first time I implement something with backbonejs, I for sure use it in a very crude manner. While this example might illuminate one way how an interactive sub-graph can be achieved it is for sure not a template how to do it - as said just a proof of concept hack ...
This isn't implemented in D3, and I'm not aware of any examples. What you would have to do is the following:
Set the fixed attribute of the new center node to true to prevent the force layout from changing its position.
Set the px and py attributes of that same node to the center position.
For each node in your force layout, compute the shortest path to the new center node.
Depending on the length of the path in each case, either remove the node or keep it.
The trickiest part here is the computation of the path from each node to the new center, but even this is a pretty standard algorithmic problem. Another thing to keep in mind is that you need to modify the data structures that contain the nodes and links of the force layout in place, i.e. you can't set new nodes and links for the force layout and expect everything to work smoothly.
http://raphaeljs.com/polar-clock.html
I'd like to create this without using SVC or Canvas. Can anyone point me in the direction of examples doing something similar with css?
Thanks!
Well, SVG certainly seems to be the correct solution to this (or canvas, but I would prefer SVG). And the Raphael script will even work in old versions of IE as it switches to VML in IE6/7/8, so if you're trying to avoid SVG/Canvas because of that then you don't need to worry.
But you're asking how to do it without them, so I'll see what I can do...
There are a number of people who have demonstrated drawing some quite complex shapes using pure CSS. See http://css-tricks.com/examples/ShapesOfCSS/ for example.
With pure CSS/HTML, the only realistic way to draw curves is using the border-radius style. A circle as per the example in the question could be achieved using a square element with border-radius, and a thick border.
Drawing concentric circles as per the question would involve numerous elements layered on top of each other, each styled similarly, but at different sizes.
Now the tricky bit. To turn them from circles into arcs is going to be harder. The only sensible way I can think of to do it would be to layer some more elements on top of the circles coloured the same as the background, to obscure part of the circle. We would need to use CSS transform to rotate them so that the angle of the cut-off was correct.
So it could be done.
Animating it (certainly as nicely as in the example) would be another order of magnitude more difficult, and I wouldn't want to even start thinking about it. Just give me the SVN any day.
I am trying to create a pie chart and am customizing the example here: http://raphaeljs.com/pie.html
I need to draw lines from the labels to the slices but IE is giving me trouble and I'm not sure what to do about overlapping lines and labels.
Has anyone done this before?
this maybe useful to you:
Overlapping issues can usually be solved by using:
a) ".toFront()" on the raphael element, that should appear in foreground
b) ".getBBox()" at your label and use its parameters to figure out the starting point.
those functions can be looked up in the raphaeljs reference.
.getBBox() should be a good way to start, when you try to connect elements. you can easily figure out its meassurements and use those values (x,y,width,height) to calculate the entry point of your path
that makes it easier to avoid any overlapping at all. but keep in mind the end SVG elements are directly placed within the dom and therefor are meant to work in layers.
overlapping / partially hiding elements often offer you a great animation potential and are not really a bad thing to work with.