JavaScript InfoVis: Hide edges to missing nodes - javascript

I am using this RGraph example from the InfoVis toolkit to draw my nodes. This is how my nodes look in JSON:
{"id":"parentId","name":"parent","adjacencies":[{"nodeTo":"missingChildId","nodeFrom":"parentId"}]}
The problem is that missingChildId refers to a non-existing node. Currently InfoVis draws an edge from the parent node to a node which it labels "missingChildId".
I don't want this edge to be drawn.
Similarily the function node.eachAdjacency gives nodes that don't exist in the graph. Is there some sort of filter to sort those missing nodes out?
Thank you.

There seems to be a couple of problems with your json data.
1: If you specify "nodeFrom" and "nodeTo" in adjacencies in your json data then infovis will create those adjacencies. In ideal case you should not have such adjacencies in your json data.
2: Also, nodeTo and nodeFrom in adjacencies points to ids of the nodes you want to refer to and ids are supposed to be unique. From your data it seems like "missingChildId" and "parentId" are not unique. Are you sure those are unique ids?
I think you must make sure that each node has a unique id and use them in adjacencies.
If there is no way you can fix your json for 1st problem then one work around is to hide those nodes with id "missingChildId".
So, after your graph is rendered, you can use following code to hide nodes with id "missingChildId".
rg.graph.eachNode( function(node){
if( node.id == "missingChildId" )
node.setData("alpha",0,"end");
});
rg.graph.animate({
modes: ['node-property:alpha'],
duration: 500
});
Similarly every time you iterate over nodes/adjacencies of graph you will have to filter out all such unwanted nodes by using their id.
You can also set your custom property on nodes which are unwanted.
node.setData("ignore",true);
And then filter them using this property.

Related

is it possible to get handles of all chars in a stage?

I wish to get handles of all the charts in a stage in order to modify background settings.
I noticed there is a stage.forEachChild(function(element) { … }) method that allows you to fire up a function for each stage element.
For example:
stage.forEachChild(function(element) {
alert(element.id());
});
The problem is that "element" type is anychart.graphics.vector.Element; instead I need a anychart.core.Chart object in order to call the background() method. Is there a way to do that?
Unfortunately, is a GraphicsJS entity and it returns its graphic vector elements as children. It doesn't control charts. You can store all chart in an object or array and iterate them, or apply a unique ID to every chart and get access to them at any moment by anychart.getChartById('CHART_ID');. For details, check the sample by the link in a comment below.

D3 V4 Tree Search and Highlight

So, I really love this example from Jake Zieve shown here: https://bl.ocks.org/jjzieve/a743242f46321491a950
Basically, on search for a term, the path to that node is highlighted. I would like to accomplish something similar but with the following caveats:
I would like to stay in D3 v4.
I'm concerned about cases where the path doesn't clear out on next node pick OR what happens when there are two nodes of the same
name (I would ideally like to highlight all paths)
I would like to AVOID using JQuery
Given a set search term (assume you're already getting the string from somewhere) I know I need to make use of the following lines specifically (you can see my stream of consciousness in the comments) but I'm just not quite sure where to start.
// Returns array of link objects between nodes.
var links1 = root.descendants().slice(1); //slice to get rid of company.
console.log(links1); //okay, this one is nice because it gives a depth number, this describes the actual link info, including the value, which I am setting link width on.
var links2 = root.links(); // to get objects with source and target properties. From here, I can pull in the parent name from a selected target, then iterate again back up until I get to source. Problem: what if I have TWO of the same named nodes???
console.log(links2);
Thoughts on this? I'll keep trying on my own, but I keep hitting roadblocks. My code can be found here: https://jsfiddle.net/KateJean/7o3suadx/
[UPDATE]
I was able to add a filter to the links2 to call back a specific entry. See
For example:
var searchTerm = "UX Designer"
var match = links2.filter(el => el.target.data.name === searchTerm); //full entry
console.log(match);
This single entry gives me all associated info, including the full list of all points back up to "COMPANY"
So, I can GET the data. I think the best way to accomplish what I want is to somehow add a class to each of these elements and then style on that "active" class.
Thank you!

Parse nodes in a dijit.tree

I'm struggling with a dijit.Tree and I can't find what I need in the dojo documentation...
I want to change the style of a few elements in my tree, according to some conditions.
I am able to identify the elements through a combination of for loops and if evaluations :
itemList = this.tree.model.store._arrayOfAllItems;
for (var index in itemList) {
item = itemList[index];
if (item.<property> == ...) {
...
//This is where I want to change the style
...
}
...
}
But then, I fail to get the node id to call dojo.addClass(nodeId, newClass).
Am I parsing through the proper list, with the model.store._arrayOfAllItems? Is there a way to parse through the node list instead, and still access the data properties?
Thank you very much for your help!
Edit on 2015-11-23
With Richard's comments, I was able to obtain the result I was looking for. I have added a handler that connects the tree's onOpen event to a method that gets the open node map (from tree._itemNodesMap) and then fetch through the store. For every item in the store, it adjust the css if the id of the item being validated has an associated node in the open node map. It then looks recursively for children.
Thanks Richard for your help!
If you have the id of the node inside the tree, you can use the getNodesByItem function that tree has.
Although if your tree is dynamic and the contents can change, I would suggest writing a function that not only adds to your store but also adds to a class for the node formed in the tree.

Best way to format a JSON for D3 Forced Directed

I'm currently using a Neo4j Graph DB to hold data from a network traffic pcap. I'm able to perform queries, and get a resulting JSON, but I am having a hard time finding an easy way to format the JSON into the node: link: format needed for D3's force directed graph!
Any help would be appreciated, I can't seem to find any links to the JSON formatting portion of creating this D3 graph.
The force layout expects two arrays: An array of objects that are the nodes, which can have whatever attributes, and an array of links, which are objects that need to have a .source and .target attribute that point to the array position of the nodes that they link. Whatever you export should be an array of JSON objects for the nodes and use some kind of hash to translate the id values of source and target to the array position of those objects in that array.
So if you've got:
nodes = [{name:"nodeA"},{name:"nodeB"},name:"nodeC"]
..then a link in the link array between those two would look like this:
links = [{name: "linkA", source: 0, target: 1}, {name: "linkB", source: 2, target: 0}]
Note that it's pointing to the x of nodes[x] of the node object, and not an arbitrary id value. So the first link connects NodeA and NodeB, while the second connects NodeC and NodeA. So when you export your nodes, you need to keep track of their array position for your edges.

How to deal with missing data in d3.js

I've successfully created several plots with d3 by parsing XML files such as this one.
Now I'm wondering how to deal with incomplete datasets. In my particular example, some sub-elements are missing in some elements. In that case I want d3 to discard the element and not display anything. At the moment, I am applying a filter to the dataset before feeding it into d3's data() function.
Is there a smarter of way of doing this on the fly? Ideally I'd just like to return null when setting an attribute and the required sub-element turns out not to exist.
Full disclaimer: I'm just starting to learn d3.js.
This can be obtained by setting the display property on the data joined DOM elements:
elemSelection.style("display", function (d) {
return is_data_NA(d) ? "none" : null;
});
Here is a short mock example: http://jsfiddle.net/rU4XL/
Note that by default, the function which accept value as a function such as .attr, .style, etc., will remove the attribute or content from the selection if the value function returns null. Hence, in this case, the display attribute would be removed from the elements in the elemSelection which have valid data.

Categories