Select specified nodes and edges in vis.js - javascript

I created a small network with less than 100 nodes and I wish to select some specified nodes and edges like:
desiredNodes=[nodeId1,nodeId2...], desiredEdges=[edgeId1,edgeId2...].
The default network.selectEdges() and network.selectNodes() both have unselectAll built in and I could not figure out how to disable unselectAll.
I have tried
mySelection = {nodes: desiredNodes,
highlightEdges: false,
edges: desiredEdges};
network.setSelection(mySelection);
But in this case, all edges connected to desiredNodes are selected and the result is exactly like network.selectNodes(desiredNodes,true).
Is there a way to solve it?

According to the documentation, setSelection takes an optional second argument where you can supply configuration options like highlightEdges.
mySelection = {
nodes: desiredNodes,
edges: desiredEdges
};
myOptions = {
highlightEdges: false
};
network.setSelection(mySelection, myOptions);
The other available configuration option happens to be unselectAll, so you could try disabling that in the options object too.

Related

How to gather nodes based on group in VisJS?

I'm pretty new to VisJS and attempting to visualize computer usage data. Over the past 2 months, I've collected data on how long I spend in each application on my computer in a chronological pattern. I want to create a VisJS network where each node is time spent in an application, the nodes are grouped by application, and the edges connect each node to the application I was using prior and the application I used next.
I've formatted all of my data, created a network from it, but the network always shows up in a ring. I want the different nodes to be arranged by their group - all of the "Chrome" nodes are by other "Chrome" nodes, etc.
Here's the code I'm using:
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes, //about 9,000 nodes
edges: edges //about 9,000 edges
};
var options = {nodes: {
shape: 'dot',
scaling: {
min: 0,
max: 1
}
},layout: {improvedLayout: false}, physics:{enabled: true},edges: {
color:{inherit:true},
width: 0.15,
smooth: {
type: 'continuous'
}
},};
var network = new vis.Network(container, data, options);
Pretty basic, but the actual result is a mess because I have over 9,000 individual nodes. The actual result looks like this:
https://i.ibb.co/gm6d1R7/Screen-Shot-2019-04-08-at-11-23-03-AM.png
I want it to look more like the VisJS example here:
http://visjs.org/examples/network/edgeStyles/smoothWorldCup.html
The thing is, as far as I can tell, I'm using the same options as this visualization - they've just gone in and manually placed each node with coordinates, which I really can't do with 9,000 nodes. Is there a way to do this automatically without placing each node individually?

Realtime data and Openlayers 3: Batch moving features

I have a hashtable I am trying to use in an vector layer so this is what I made:
var make = [], remove = [];
for (var key in data) {
var val = data[key];
if (featureCache[key]) {
if (val._ts > featureCache[key]._ts) {
var geom = featureCache[key].getGeometry();
The problem starts here. From what I have found out so far I have two options:
geom.setCoordinates(latlng([val.Latitude, val.Longitude]));
geom.flatCoordinates = latlng([val.Latitude, val.Longitude]);
However the first one bubbles up and makes the map render, this is a problem because I have over 1500 features and I plan on using more.
The second line gives me assertion failed, and I dont know how to debug it.
featureCache[key]._ts = val._ts;
}
} else {
make.push(featureCache[key] =
new ol.Feature({
geometry: new ol.geom.Point(latlng([val.Latitude,val.Longitude]))
})
);
featureCache[key]._ts = val._ts;
}
}
source.addFeatures(make);
This needs to be run every other second or so because I want the data to be as realtime as possible.
And if this is a really stupid way do do it, I would like to know that too.
I am not sure how you could do it with the new API, but you could try this:
clone an old geometry and update it, do this for each
add the clone to a collection that OL is not aware of (avoids the map render / updates)
once that collection is ready, remove the old collection from OL and set the new (batch)
Doing this for several thousand items should work pretty fast on 'modern' browsers as you set it only once. The key point is to avoid triggering updates while you update each entry.
Maybe there are ways to avoid the bubbling/events to allow for batch updates (no triggering of map render for each change) ?

Javascript Infovis change individual node color

In this case i'm using JIT Hypertree. I am going to differentiate a node's color from the other's so that every node on the tree have their own color. Is there anyway to change the individual color so it would be different from other node?
I just managed to change the color of all nodes, but not individual.
Node: {
dim: 9,
color: "#009933"
},
You have to set the overridable property to true there on Node.
Node: {
dim: 9,
overridable: true
},
Then, after loading data and before drawing, iterate over the nodes and use setData to set the individual colors. Here's an example that uses random colors, but you could also plug colors into your JSON data and pull it from there:
ht.graph.eachNode(function(node) {
node.setData('color', "hsl("+Math.random()*360+",100%,50%)");
});
Now, shameless plug: I wrote a library to generate colors based on, say, IDs. So if you don't want to handpick colors and you want the colors to have a persistent relation to the data, it would help. Here's the example of using that.
ht.graph.eachNode(function(node) {
node.setData('color', $.fn.autumn.getColor(node.id));
});

Adding functionality to mapbox.js

I'm trying to rewrite grid_control.js in MapBox to allow for several tooltips from gridControl to appear together at the same time in the same box.
The gridControl is activated thus:
var gridLayer = L.mapbox.gridLayer('example-map.sdfagg22gd');
var tileLayer = L.mapbox.tileLayer('example-map.sdfagg22gd')
map.addLayer(tileLayer);
map.addLayer(gridLayer);
map.addControl(L.mapbox.gridControl(gridLayer));
Instead of rewriting the source code, however, I'd like to extend the GridControl class, and make the code more compatible with future mapbox.js versions.
var GridControl = L.Control.extend({
options: {
pinnable: true,
follow: false,
sanitizer: require('sanitize-caja'),
touchTeaser: true,
location: true
},
How should I do that, and is it advisable?
Also, any ideas on how to allow for several tooltips at the same time? Will I need a counter for active tooltips and redo all actions based on that? Any pointers would be greatly appreciated.
From what I understand, the possibility for concurrent tooltips is possible, as two separate boxes with tooltip content will appear with {follow : false} option. But how to get this into a mouse-centric moving tooltip (which is activated by {follow: true})?
Simply:
// get gridControl object and pass it for modification
var gridControl = L.mapbox.gridControl(gridLayer, {follow:true});
// modify the prototype
gridControl.__proto__._onPopupClose = function() {
this._currentContent = null;
this._lastContent = null;
this._pinned = false;
};

What is the 'Hello, World' for the Javascript InfoVis Toolkit?

I am doing research in graph theory and need to visualize graphs in real time.
(That is, if the graph data changes, its representation changes with it.)
InfoVis seems to meet that goal, but I am struggling to put together a simple 'Hello, World' page that just displays a graph on-screen with clickable nodes (where clicking causes the node to change color).
I have a working installation of JIT (the given examples work),
I just need a minimal example of InfoVis to get started,
and it is proving difficult to piece one together from the documentation.
Fiddle example.
This isn't exactly minimal, but you can probably remove some more stuff to make it so. I took code from the graph manipulation example, and removed some superfluous CSS and JS.
To get the nodes to change color, I added this line to the "onClick" function:
node.data["$color"] = "#FF0000";
The minimal elements seem to be:
a JSON data structure
instantiate the $jit.ForceDirected object, and call loadJSON
There's also a bunch of boilerplate code for cross-browser compatibility (checking for canvas support, etc).
The pared-down JSON structure looks like this:
// define three nodes
var json = [
{ // first node
// node identifier
id: "graphnode1",
// node label
name: "A graph node (#1)"
// the node's color, shape, and size
data: {
$color: "#FFFFFF",
$type: "circle",
$dim: 10
},
// this node is adjacent to nodes 2 and 3
adjacencies: [
"graphnode2",
{
nodeTo: "graphnode2",
// make the connector blue
data: {
"$color": "#0000FF"
}
},
"graphnode3",
{
nodeTo: "graphnode3",
}
]
},
// second node
{
id: "graphnode2",
name: "Another graph node (#2)"
},
// third node
{
id: "graphnode3",
name: "Another graph node (#3)"
}
];
Here's the outline of the initial code:
var json = {
// structure here
};
var fd = new $jit.ForceDirected({
// create canvas in "infovis" DOM element
injectInto: 'infovis',
// many other options here
});
fd.loadJSON(json);

Categories