vis.js network: hierarchical layout issue related to number of nodes - javascript

I'm facing a "strange" problem I'm not able to solve looking at vis.js documentation.
I created a network with a fixed hierarchy defining a specific level for each node.
Total number of nodes 51. This is the result:
If I add another node at the bottom of the network scheme (total 52) the layout changes, the spacial disposition of the nodes totally move trying to fill white space as you can see:
I tried several options without any success.
These are the options I'm using at the moment:
options = {
layout: {
improvedLayout: false,
hierarchical: {
enabled: true,
levelSeparation: 150,
nodeSpacing: 110,
treeSpacing: 200,
blockShifting: false,
edgeMinimization: true,
parentCentralization: true,
direction: "LR",
sortMethod: "directed",
shakeTowards: "roots"
}
},
interaction:{
tooltipDelay: 100
},
edges: {
font: {
size: 0
}
},
nodes: {
shape: 'circle'
},
physics: false
};
I hope you can give me some suggestion.
Thank you!

you can try to add a randonSeed to the layout in the options object.
layout: {
randomSeed: 1,
improvedLayout: false,
hierarchical: {
enabled: true,
levelSeparation: 150,
nodeSpacing: 110,
treeSpacing: 200,
blockShifting: false,
edgeMinimization: true,
parentCentralization: true,
direction: "LR",
sortMethod: "directed",
shakeTowards: "roots"
}
}
you can change the number (randomSeed: 1) until you get the requested layout.
hope it will help.

Related

Hide tooltip when hovering over null-values in chart.js

I am currently using a line-chart with chart.js 3.5.0 and react-chart-js 3.0.4, given two datasets.
The first dataset has data in {x,y}-format with null-values for some y.
When hovering over those null-values, the tooltip jumps to the start of the second dataset. In this case, I would like to hide the tooltip, but approaching the problem with callbacks didn't work.
Has anybody experienced the same issue?
Screenshot
codesandbox
const options = {
interaction: {
intersect: false
},
maintainAspectRatio: true,
animation: false,
plugins: {
tooltip: {
mode: 'nearest',
axis: 'x',
position: 'average',
yAlign: "bottom"
},
},
scales: {
y: {
type: 'linear',
beginAtZero: true,
min: 0,
grace: '20%',
}
},
chartArea: {
backgroundColor: "rgb(240,240,240)"
}
}
You can use mode: 'x' in your tooltip config.
Together with setting pointHitRadius to 0 in both datasets makes it so you dont have duplicate values in your tooltip.
Example: https://codesandbox.io/s/hardcore-brown-1vxcjh?file=/src/components/CChart.jsx

Chartjs-plugin-zoom plugin does not change x axis labels

I am working with the chart.js module in order to plot some data and am using the chartjs-plugin-zoom in order to enable zooming and panning however although the zooming works the labels on the x axis will not change for whatever reason.
I have seen similar questions but they all dealt with time series data and therefore the advice was unhelpful.
Here is the plot zoomed out:
and here is it zoomed in:
The key thing to notice is how the labels on the y axis have changed but the x axis labels have not changed. Here is the relevant config variable of the chart:
const config3 = {
type: 'line',
data: {
labels: [I ran out of chars but this is just a very long list of numbers in this format: 1,2,3,4,5],
datasets: [
{
label: "",
backgroundColor: '#'+Math.floor(Math.random()*16777215).toString(16),
borderColor: '#0071BC',
data: [I ran out of chars but this is just a very long list of numbers in this format: 1,2,3,4,5],
fill: false,
borderWidth: 1,
},
],
},
options: {
responsive: true,
title: {
display: true,
text: 'Peak: -1.2188'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Frequency (Hz)'
},
ticks:{
autoSkip: true,
maxTicksLimit: 20
},
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Amplitude'
}
}],
},
plugins:{
zoom: {
pan: {
enabled: true,
mode: 'xy',
speed: 20,
threshold: 10,
},
zoom: {
enabled: true,
drag: false,
mode: "xy",
speed: 0.1,
// sensitivity: 0.1,
}
}
},
elements: {
point:{
radius: 0
}
}
}
};
If needed I can provide more code but I imagine the mistake is probably contained in the config. I tried changing zoom.mode to be 'x' but that did not work.
In case someone else comes along this I figured out a solution that is pretty unintuitive.
The first problem is the way that labels are dealt with in chart.js and because they are treated as categories not x data the way that I thought they were. Therfore first you must pass your data in as coordinates in this format:
(as shown in this documentation: https://www.chartjs.org/docs/latest/charts/line.html)
data: [{
x: 10,
y: 20
}, {
x: 15,
y: 10
}]
And delete the labels variable.
However this will not work with line charts despite what the documentation says. To get around this you can set: type: 'scatter' and inside the dataset write showLine: true
This will generate a line plot where the x labels are auto generated and zooming will work perfectly.
I also think there was a performance boost which is a nice bonus.

Flot Chart Bar spacing

I am using flotchart JS for showing bar graphs. However, I can't seemed to fix the spacing between bars.
I have enabled panning already. However, sets the width of the bar according to the placeholder. How can set each bar's spacing according to its label?
this is my code:
$.plot("#graph", [ data ], {
series: {
bars: {
show: true,
barWidth: 0.6,
align: "center"
}
},
xaxis: {
mode: "categories",
showTicks: false,
gridLines: false,
panRange: [0,null],
},
yaxis: {
panRange: [0, null],
plotPan: false //pan axis is allowed for plot pan
},
pan: {
interactive: true,
mode: "smart",
active: true
}
});
An alternative solution to your problem could be to rotate the tick labels for example by using the tickrotor plugin:
xaxis: {
mode: "categories",
showTicks: false,
gridLines: false,
panRange: [0,null],
rotateTicks: 90
},
You may need to increase the height of the chart since the labels now take up more space. See this fiddle for a full example.
You can achieve this by limiting the number of bars shown at once by giving a max property for the xaxis:
xaxis: {
mode: "categories",
showTicks: false,
gridLines: false,
panRange: [0,null],
max: 7, // set according to your needs, maybe dynamic depending on chart width
min: 0
},
You then have to use panning to see the other bars. See this fiddle for an example.

control edge rendering of a network in vis.js

I am working on a control flow graph visualizer using vis.js. it's like the example provided by the maintainesr here.
the following image shows the result:
I want control the way edges are drawn: out arrows start from the bottom and in arrows end at the top of the node. is there a way to have such behavior in vis.js? also can I prevent edges from crossing nodes?
this is my options:
var opts = {
autoResize: true,
height: '100%',
width: '100%',
locale: 'en',
edges: {
arrows: { to: {enabled: true}},
smooth: { enabled: true}
},
nodes: {
font: {'face': 'monospace', 'align': 'left'}
},
layout: {
improvedLayout:true,
hierarchical: {
enabled: true,
sortMethod: "directed",
direction: "UD",
nodeSpacing: 200,
levelSeparation: 200,
}
},
physics: {
hierarchicalRepulsion: {
nodeDistance: 300
}
}
};
var network = new vis.Network(this.domRoot.find(".graph-placeholder")[0],
this.defaultCfgOuput, opts);

Stop vis.js physics after nodes load but allow drag-able nodes

I am trying to draw a vis.js network diagram and have vis load and position the nodes. I then want the physics to be disabled so the nodes can be moved by the user. I have tried this but it is not working.
var options = {
nodes: {
borderWidth:4,
size:60,
color: {
border: '#222222',
background: 'grey'
},
font:{color:'black'}
},
edges: {
arrows: {
to: {enabled: false, scaleFactor:1},
middle: {enabled: false, scaleFactor:1},
from: {enabled: false, scaleFactor:1}
},
color: 'black'
},
{ physics: enabled: false; };
Has anyone done this? if so can you provide an example or advice on best way to accomplish this. I have also read the explanation located here, but not being too familiar with java I can't figure the steps out.
Thanks
After some more work and help from the vis.js developer here is the completed code, minus the json data and some options. The trick is to use the "stabilizationIterationsDone" event and disable physics:
// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {
nodes: ...,
edges: ...,
physics: {
forceAtlas2Based: {
gravitationalConstant: -26,
centralGravity: 0.005,
springLength: 230,
springConstant: 0.18,
avoidOverlap: 1.5
},
maxVelocity: 146,
solver: 'forceAtlas2Based',
timestep: 0.35,
stabilization: {
enabled: true,
iterations: 1000,
updateInterval: 25
}
}
};
network = new vis.Network(container, data, options);
network.on("stabilizationIterationsDone", function () {
network.setOptions( { physics: false } );
});
I suppose you first want to let the network stabilize and only then disable physics? In that case you can load the Network with physics and stabilization enabled. Once the nodes are stabilized, the stabilized event is fired. Then you can disable the physics via network.setOptions
I was able to figure this out and the code now looks like this
// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {
nodes: {
borderWidth:1,
size:45,
color: {
border: '#222222',
background: 'grey'
},
font:{color:'black',
size: 11,
face :'arial',
},
},
edges: {
arrows: {
to: {enabled: false, scaleFactor:1},
middle: {enabled: false, scaleFactor:1},
from: {enabled: false, scaleFactor:1}
},
color: {
color:'#848484',
highlight:'#848484',
hover: '#848484',
},
font: {
color: '#343434',
size: 11, // px
face: 'arial',
background: 'none',
strokeWidth: 5, // px
strokeColor: '#ffffff',
align:'vertical'
},
smooth: {
enabled: false, //setting to true enables curved lines
//type: "dynamic",
//roundness: 0.5
},
}
};
network = new vis.Network(container, data, options);
network.setOptions({
physics: {enabled:false}
});
}
I had to move the network.setOptions() as shown in the new code and it is now working as desired.

Categories

Resources