I was wondering if anyone could help with this:
I have a simple d3 force diagram (here). I was wondering if I programmatically can get a node (fixed node C1) and shift it to a different position with transition animation like in the follwoing example:
var mySquare=svg.append("rect")
.attr("x",60)
.attr("y",60)
.attr("width",60)
.attr("height",60);
mySquare
.transition()
.attr("x",320);
So in a nutshell - once a diagram completes I would like to pick a node (C1) and give different x and y using a transition animation.
Related
How do I prevent nodes in a graph from stacking on each other? I want there to be a minimum distance between nodes and if someone was to drag a node over another the graph throws an error to the user. I saw this solution and tried it but it doesnt work Prevent node overlap in JGraphX
I'll appreciate any ideas.
For rearranging your diagram automatically with some distance between them you can try to use something like this:
let layout = new mxHierarchicalLayout(this.graph, mxConstants.DIRECTION_WEST);
layout.intraCellSpacing = 50; //horizontal
layout.interRankCellSpacing = 200; //vertical
layout.execute(this.parent);
The mxHierarchicalLayout method will automatically rearrange your current nodes. The other two settings will give spacing between them ( horizontally and vertically )
Also, run this before rendering the screen or if you want to change after the display has already rendered, just this.graph.refresh() if needed
The stackoverflow community has a great solution for moving nodes in a sankey chart along the x axis (link here).
However, I noticed one cannot manually change the position of sink nodes (i.e. those nodes auto-assigned to the far-right). Because I am incorporating time into the sankey graph, I need to have certain sink nodes fixed at manually specified x positions.
Here is a JSFiddle example that needs this capability. Specifically, I need node "6": "Departed (6 mo.)" to be fixed to the x position '1'.
"nodes":[
...
{"node":6,"name":"Departed (6 mo.)","xPos":1}, // <-- need to move to position x=1; manual override not taking effect
...
Per the above-mentioned solution, I have updated computeNodeBreadths() within d3.sankey() and have included "xPos":1 within the node of interest; but the change is not taking effect.
Does anyone have a recommended update to the above-mentioned solution that allows one to manually adjust sink node x positions?
After some research, the answer is to comment out the line moveSinksRight(x) within the d3.sankey() method computeNodeBreadths(). Credit goes to Greg Ross: https://stackoverflow.com/a/21540569/4245462
I am trying to implement a radial force layout in D3.js , I saw a similar example but i am stuck on how to initiate the node positions in the layout.
http://bl.ocks.org/vlandham/5087480
Thanks in Advance
Initialising a position is just done by setting the cx and cy positions. The most logical place is where the radius is currently being set i.e.
.attr("r", 10)
.attr("cx", 5) //added
.attr("cy", 5) //added
Of course, you can do something more exotic if you are using the bound data to initialise position.
This will only set the starting point though - the force layout will then take over and position elements. The advantage is that you can potentially reduce some of the initial node movement if you get it right.
I'm using this example as a base D3.js Drag and Drop, Zoomable, Panning, Collapsible Tree with auto-sizing.
What I need is a tree where all the leaf nodes are the same distance from the root.
It should look something like the Cluster Dendrogram.
I would use the Cluster Dendrogram but it lacks the zooming, panning and collapsibilty options (I've cut out node dragging). Also the difference between the two examples is that one uses tree layout whereas the other cluster layout.
All your help and suggestions would be much appreciated.
It likely won't be easy to implement because the tree layout likes it's depth but you could do something like this.
nodes.forEach(function(d) {if(!d.children){
d.depth = 3; //3 should be replaced with whatever your lowest depth is
//you could write a function to find it too. let me know if you need that
}})
nodes.forEach(function (d) {d.y = d.depth * 300;});
this will accomplish part of what you are talking about but there is nothing to prevent the nodes from overlapping here. This post: Avoid overlapping of nodes in tree layout in d3.js about node spacing could potentially help
I'm relatively new to d3 and am attempting to augment a radar diagram such that it rotates on click and the next axis points directly upwards.
The example in which I am working from is found here.
Problem
Currently, when the svg is clicked, I rotate the entire svg by a specified angle based on the number of axis there are in the graph. Since I am rotating the entire svg the labels that are appended to each axis will rotate also (as shown in the following image).
The text is currently unreadable and I want to achieve a solution which is more similar to the following image:
I would like each label to stay with their respective axis and also stay upright after the svg has been rotated, but I am finding it hard to achieve this.
JSFIDDLE
This JSFIDDLE is the stripped down code of the current implementation (I left out the numerous failed attempts) and the following code, which would be in the 'rotateOnClick' function is the closest I have came to a solution so far (I haven't used the index i variable so far but my intention was to swap the position of labels with each other when clicked).
g.selectAll(".legend")
.transition()
.duration(cfg.rotateDuration)
.attr("transform", function(d, i){
if (i<total) i++;
else i = 0;
return "rotate("+newAngle*-1+", "+(cfg.w/2)+",0 )"
})]
.ease(cfg.easeFunction);
I need to manipulate each label individually and stay aligned with its respective axis and also for it to work with a dynamic number of axis.
I greatly appreciate any help and insight.