I have a graph of people who interact with each other.
The graph is quite messy since everybody interacts with each other. What I need is:
Display the "main" person in the center
Display only the first level of interactions
When the user clicks on a node toggle its children visibility (without displaying children of children)
I've read about compound nodes, but the thing is that one node (person) can have many parents and it's not supported in Cytoscape.
This is what it should look like. The red circle is the "main" person. The red rectangle is the first level of interactions. The rest should be hidden till the user clicks on a node, which reveals its direct children.
The only idea I got is to manipulate the data I provide for the chart. Right now I have an array of vertices and edges. Edges have source/target. So I probably can handle it in javascript by manipulating these arrays.
But is it possible to somehow simplify the process?
You can use view-utilities extension of cytoscape.js which provides hide/show functionality. See its API that has hide, show and showHiddenNeighbors functions. You can also play with its demo here.
Related
Update: Added a collage of the images I was going to add to get around reputation block
I've been working on a cytoscape implementation that will dynamically display information I'm pulling from my database onto a webpage. The goal is to be an organization chart, displaying nodes in groups, in a directed tree structure. I've been doing a lot of research, and trying out several different layouts and api options to try and meet the use case, but I'm having issues getting it to work the way I'm intending.
Specifically I want to use compound nodes - the parents being the people's ranks. I've learned that a lot of layouts simply haven't been designed with compound nodes in mind, and I've been trying different implementations, including ones that create an initial layout, and then try to run a secondary layout specifically on the descendants of the parents.
Following are the closest of what I've tried and their issues:
Images of graphs: https://i.stack.imgur.com/6hzVS.png
cose-bilkent:
The main issue with this is that it doesn't seem to be meant for directed trees, but rather decides placement on its own. The bigger issue I've had is that I couldn't find a way to spread the nodes out better within their groups. I've tried to use the node padding options included, but they haven't had an affect, which I'm assuming is due to the compound nature.
grid:
Graph is in a perfectly grid like layout of all the nodes, but ignores parent nodes.
This layout was working for me initially, and would have the benefit of being able to easily change the amount of people per column. As I changed the elements though I realized it was a coincidence that it worked initially - it seems like it's totally ignoring the parent nodes, which is understandable if it wasn't designed with them in mind.
grid - descendants:
Graph is of the two sets of descendants layered on top of each other.
What I tried next was using a different layout to determine the initial placing of the parents, and then performing a grid layout on the descendants to make them organized in their groups. I realized then that parents are simply reacting to their child's placement. Also, it appears that calling layouts on sets of nodes separately for grid was completely ignoring anything else that exists on the graph, causing the groups to be put on top of each other.
cola:
It's close, but the way it puts them on the graph is not well structured, causing the placement in the groups to be jumbled up, though they are spaced out enough.
This appears it would work great if I could figure out how to run a proper layout on the parent nodes, forcing the tree structure that works without compound nodes.
Here is more or less what I'd like to see, though the logic for # of nodes per column isn't that important. As long as they're organized neatly:
https://i.stack.imgur.com/irVaK.png
Is there any advice someone could give on how I could go about making this work? I haven't been able to find any layout setups that work quite right, and I don't really know what to do from here. I would also prefer to avoid creating an entirely new layout from scratch. Any help is greatly appreciated.
If you have a proper tree data structure, you shouldn't be using compound nodes for layout. It's not generally possible to satisfy compound parent position restrictions when there are additional constraints on the children. This is because a parent is naturally constrained by its children -- a parent doesn't have its own position or size, it's children define it implicitly.
The best layouts for compound graphs are force-directed (physics simulation) ones like CoSE or Cola.
In your case, you just have a tree. I would use the breadthfirst or Dagre layouts without any compounds. Each level will naturally indicate rank.
For anyone interested, what I've done to solve this is create my own preset layout function that dictates where (children) nodes go on the graph, using their properties to dictate where they go.
It's designed to only display linear compound graphs, in order based on "level" in the hierarchy. It's capable of displaying the children nodes in grid-like sets within their parent nodes (visually - remember parents simply adjust according to their children), in the order of the mentioned linear levels.
You can also specify the values for how many columns in a set, space between nodes, and space between levels. There's obviously lots of room to make the variables more verbose if you'd like to specify "x-space" and "y-space" between nodes, and things like that.
It assumes the following:
-You know ahead of time what level corresponds to each compound group
-You know ahead of time how many nodes are in each compound group
-If you're making this dynamically, that you have a way to dynamically produce the javascript variables necessary for the dictionary, which tracks the total size of each group and how many nodes of each group have been accounted for.
Here's the code. I know it's a niche case, but if you do have a reason to use it, just keep in mind that it's sure to be bug prone, and is definitely inefficient (Javascript isn't my forte...). I've tested certain edge cases that I feel are common in my project, but there could be others that aren't accounted for.
http://jsbin.com/quyipo/edit
(Also upvotes/comments don't hurt either. I'm curious if this could actually help someone...)
I want to display a graph which depicts a timed process. Therefore, it would be desireable to have nodes aligned according to a given timeline.
The time stamps are totally accurate, which is why I chose them to be the keys of my groups. If two nodes have the same time stamp, they get added to the same group.
These groups are aligned by the TreeLayout. Per default they are aligned in the following way:
(Please note that the black boxes depict the groups and their alignment. The red boxes were added for better understanding on which level which group is.
What I would like to have, is a more timelined view of the diagram like so:
I tried setting layerStyle: go.TreeLayout.LayerUniform, and afterwards setting the TreeVertex.level accordingly, but GoJS didn't change its positioning.
Are there any other possibilities to achieve what I want?
Did you assign TreeVertex.level in an override of TreeLayout.assignTreeVertexValues?
You might be interested in the LayeredTreeLayout example classes that are in two different samples: http://gojs.net/temp/swimBands2.html (no Groups) and http://gojs.net/temp/swimBands3.html (with Groups).
I hope the LayeredTreeLayout code in those files isn't too confusing. They are slightly different from each other, due to the absence or presence of Groups, and the corresponding changes in the node data.
I have requirement to list different activities with three states of each one with different colors as a status.Each activity will have many activities and each should draggable to replace it's position. Below image give you clear idea
Is it possible with d3.js??
Yes it's absolutely possible. Are there any more details you need??
A newbie question. As I've explained in a prior post, I'm coming to SVG Land from Flash loaded with ActionScript expectations and misconceptions.
I've built an interactive graphic using D3 and I'm nearly finished except that I want to add a little pop-up box that displays when a user mouses over a state. Right now it appears as a static object labeled "West Virginia" on the left side of the stage:
http://www.50laboratories.com/miscellany/demographicclout2.html
The pop-up is a group with its own distinct ID. I need to be able to set its x and y location depending on the state being hovered over, but so far can't figure out how. It seems to me that I should be able to address a group in my JavaScript as I would a named movie clip in Flash, but visiting API references like this one, https://github.com/mbostock/d3/wiki/API-Reference, I see no references to methods and properties of group objects. Thanks in advance for your help.
Unlike actionscript, svg elements are dom nodes and manipulating them involves either setting their attributes or style properties. You could manipulate these by calling certain attribute/style setters of the dom nodes, but since you're using d3, you set those attributes/styles using d3's setters.
The way to position a element with d3 is to
1. select it, by the id you assigned it
2. set its transform attribute to translate([some-x], [some-y])
d3.select("#statepopup").attr("transform", "translate(50,100)");
P.S.
The transform attribute is also how you can scale and rotate the group.
I am working on some graph visualizations, and I am using the JavaScript library graph Dracula. Now, with this library, when I want to move a node I have to click the node I want to move and move it on the desired place (with drag and drop). But, what I want to do is to select more nodes and move all of them. I can't figure out how to do this, since I am not so experienced in JavaScript programming. So, my question is:
How can I select multiple nodes with rectangle selection and move
them?
How can I select multiple nodes with, say, Ctrl + left click and select more nodes and then move them?
By the looks of things, almost all of Dracula's graph rendering is really managed by RaphaelJS.
In which case, things may be quite a bit easier for you. It seems other people have asked how to move elements in RaphaelJS.