# Can edge length be controlled in a force-directed graph?

I'm building a graph using sdfp/gvmap using the basic command workflow in the one gvmap gallery item.  My dataset has about 6K nodes.
I've built clusters of nodes by connecting them to a single node with invisible edges.  In the graph this produces country-like formations.   Inside these clusters, there are many hundreds of connected edges.
If I graph just these clusters, they are evenly spaced in the output image.
Between these clusters, I also have edges to show inter-dependent relationships between them.  When I produce a graph with the inter-cluster edges, they all pull into the center of the output image.  At a crude level, I can understand why this happens with sdfp.
What I'd like to do is have more space between the clusters.  That is, I'd like the inter-cluster edges to not influence the spring calculations as much or at all.  Ideally, I could control how much these clusters pull on each other, but I'd be fine if these edges had no effect.
I experimented with a few different edge, node and graph attributes in the hope I could find a way to pull this off, but have had no luck.
Is there a way to control the force calculations on an edge-by-edge basis?

Thanks.

### Can edge length be controlled

Currently there is no way to control the force on an edge by edge basis. However,  It sounds like you already know how to cluster your graph? In that case, you could just assign clusters yourself, then feed to sfdp then gvmap. gvmap will obey your cluster assignment. E.g., if you have a graph

strict graph {
1--2
3--4}

By default you will get 2 clusters thus 2 countries. But if you instead give

strict graph {
1--2 [cluster=1]
3--4 [cluster=1]
}

Then you will get only one country. If you still prefer your approach (of adding invisible edges), you can annotate the artificial edges as, say, type = "artificial", then first cluster using "cluster" function, then strip out the artificial edges before feeding to sfdp, as

cluster foo.gv | gvpr -c 'E{if (\$.type=="artificial") delete(\$G, \$);}' | sfdp -Goverlap=prism|  gvmap | neato -Tps -n2 > foo.ps

If you want even more controls in edge length, then specify [len=...] and use neato
cluster foo.gv | gvpr -c 'E{if (\$.type=="artificial") delete(\$G, \$);}' | neato -Goverlap=prism|  gvmap | neato -Tps -n2 > foo.ps> bar.gv
You could even modify the edge length based on the cluster membership of the end nodes. Although neato on a graph of 6000 nodes can be memory and time demanding.
We are working on new algorithms that behaves like neato but runs more like sfdp speed/memory wise, but it will take sometime.

### Can edge length be controlled

We have been looking into having some support for variable edge lengths, but this is tricky in a multiscale-type algorithm like sfdp. This is possible in fdp and neato, but these will probably not be fast enough for you.

If you really are satisfied if you can turn off certain edges and can easily identify them, why not remove them and then put them back later? You can use gvpr scripts to do this.

### Can edge length be controlled

Hmm.  How slow are we talking if I use fdp?  I'm not opposed to waiting around if the problem is still tractable with that tool.  I'm open to try it if you can tell me what I'd use there.
Your comment about gvpr is interesting.  I never considered that methodology.  I may be able to do something like that manually because my dataset actually is generated from an external tool and has all the inter-cluster edges in one big group.  Technically I should be able to exclude that block, run sfdp, then add the block to the generated output, then put it through gvmap.
Thanks a lot for the help!