Force directed layout - javascript

when i use THIS algorithm to calculate force directed layout of graph where from 1 node is 10 or more edges, calculation failed.
I guess it's because calculated position is so much large and it's represented as "NaN".
Input data:
var g = new Graph("canvas", 960, 700 );
g.createVertex("a");
g.createVertex("a1");
g.createVertex("a2");
g.createVertex("a3");
g.createVertex("a4");
g.createVertex("a5");
g.createVertex("a6");
g.createVertex("a7");
g.createVertex("a8");
g.createVertex("a9");
g.createVertex("a10");
g.createVertex("a11");
g.createVertex("a12");
g.createVertex("a13");
g.createVertex("a14");
g.createVertex("a15");
g.createVertex("a16");
g.createEdge("a","a1");
g.createEdge("a","a2");
g.createEdge("a","a3");
g.createEdge("a","a4");
g.createEdge("a","a5");
g.createEdge("a","a6");
g.createEdge("a","a7");
g.createEdge("a","a8");
g.createEdge("a","a9");
g.createEdge("a","a10");
g.createEdge("a","a11");
g.createEdge("a","a12");
g.createEdge("a","a13");
g.createEdge("a","a14");
g.createEdge("a","a15");
g.createEdge("a","a16");
g.go();
When i use this data, sometimes is graph rendered without problems, but mostly it breaks.
Can someone help me to fix it?
Thank you.

In the link you provided, the third example has something like:
g.repulsion = g.repulsion / 8;
g.spring_length = 1;
This apparently makes it more compact. Since, you want to spread out the graph, you should probably multiply like this:
g.repulsion = g.repulsion * 10;
Try different numbers to see if it works. In future, I would suggest to use something with better documentation like D3.js.

Related

Convert existing d3 live stream line graph to use seconds elapsed instead of time

Still relatively new to D3, and the functionality that I'm looking for is a live streaming line graph, with new data coming in real time. I've come across an example online that is EXACTLY what I'd like to implement, with one minor issue. As it streams, the x axis shows the clock time, which looks great, but My needs require it to be shown as time elapsed instead.
Here's the code for this:
https://bl.ocks.org/boeric/3b57a788a4b96e1af211
I've been trying to adapt this script to work, but all I've done is break it, it seems that time is pretty well integrated into this example. Is it worth converting this, or am I better off implementing my own solution? I can, but it may lack some of the bells and whistles that come in this example.
The closest solution so far is that I've changed the chart scales from this:
var x = d3.time.scale().range([0, width]);
to
var x = d3v3.scale.linear().range([0, width]);
Now I'm getting something more similar to a timestamp at each tick, which isn't ideal. I can't seem to find anyone else on the internet that as done something as simple as this, strange as that may sound.
As you already know Bo Ericsson’s Block 3b57a788a4b96e1af211 use his realTimeChart.js
You should try to adapt line 139,
var xAxis = d3.svg.axis().orient("bottom");
to
var xAxis = d3.svg.axis().orient("bottom").tickFormat(function(d) {
var dif = new Date() - d;
var seconds = Math.round(dif / 1000);
return seconds;
});
axis.tickFormat([format]) will do your thing.

Make two instances of d3.forceCollide() play nice together

I want two instances of d3.forceCollide(). In one, every node is pushed away from one another to prevent overlap. In the second, only a subset of nodes are pushed away from one another, with a much bigger radius.
To accomplish the second force, I tweak the initialize method to filter the incoming nodes, like so:
function selective(force,filter){
var init = force.initialize;
force.initialize = function(_){return init(_.filter(filter));};
return force;
}
var dpi = 90; // approximate pixels per inch in SVG
var size = dpi * (1/4); // quarter-inch unit size
var universally_applied =
d3.forceCollide()
.radius(size)
.strength(1);
var selectively_applied =
selective(
d3.forceCollide(),
function(d){return d.id === color;}
)
.radius(size*5)
.strength(1);
}
Now, this ALMOST works. I created a fiddle to see it in action: https://jsfiddle.net/jarrowwx/0dax43ue/38/ - every colored circle is supposed to repel every other circle of the same color, from a distance. Every other color, it just bumps into and pushes it out of the way.
If I do not change the order in which things are defined, then the selectively applied force is ONLY applied to the first color (red). If I shuffle the data array before applying forces, it is difficult to define exactly what happens, but the force is applied to some circles and not most of the others, even among the same color.
Any ideas what is going on here, or how to fix it?
The D3 team decided that this behavior was a bug (Isolating forces to a subset of nodes? #72), and fixed it. The fix was included in version 1.0.4 of d3-force, which is available as part of the full D3 build as of version 4.4.0.
The problem is resolved using the solution suggested by "Partial forces on nodes in D3.js", and the code works as intended now.

NVD3 - configuring ticks on axis

I have a nvd3 line chart which displays a time series and can't get the ticks on the x axis right.
For longer time spans, it works as expected. But for shorter time spans (here: 12/31/05 to 01/01/06), the same date is displayed for multiple ticks:
Please have a look at the code for this chart on JSFiddle
I want the chart to only display ticks at data points, and not in between. Is that possible with a line chart? From my understanding, it is possible with d3, but I can't figure out if this functionality is exposed by nvd3.
I've tried explicitly setting the number of ticks with chart.xAxis.ticks() without success. The only thing that has any effect is explicitly setting the tick values with chart.xAxis.tickValues([...]), but I would prefer not having to calculate them myself.
The way to solve this in general is with custom multi-scale time formats. Note that this example itself will not work with NVD3 because it uses an older version of D3, the examples below will though.
The problem in your case is that the ticks aren't "clean" divisions of time and if you apply a multi-scale format, you get something like this. It always shows the more fine-grained format because anything else would involve a loss of precision.
You can however use a simple heuristic to show the date instead of the time if the hour is less than 3, which works reasonably well in your case. See here for an example. The proper way to do this would be to make your ticks clean divisions.
Which brings us to your actual question. There's no other way than to explicitly set .tickValues() for what you want to do, but you can compute the x positions in your data quite easily:
var xvalues = [],
tmp = data.map(function(e) {
return e.values.map(function(d) { return d[0]; });
});
xvalues.concat.apply(xvalues, tmp);
The code is not the prettiest because it's a nested structure, but fairly straightforward. Using this, you can set your tick values explicitly, full example here.

Protovis JQuery Change Histogram Xticks

I'm toying with the Protovis Histogram example and I was wondering if it was possible to change the values of the x-ticks while keeping the histogram the same. Right now the x axis varies from 0 - 5 but what if I wanted to keep the whole histogram the same but just change the x-axis ticks to vary from 10 - 15? Is that possible?
I think the change should be somewhere in the following code:
vis.add(pv.Rule)
.data(x.ticks())
.left(x)
.bottom(-5)
.height(5)
.anchor("bottom").add(pv.Label)
.text(x.tickFormat);
but I'm not really sure what the code is doing. Any help greatly appreciated. Thanks!
hi Michael in that link at bottom of the page you could see the code
var experiment = {
trials: 10000, // number of trials
variables: 5 // number of random variables
};
experiment.values = pv.range(experiment.trials).map(function() {
return pv.sum(pv.range(experiment.variables), Math.random);
});
just try to change the variables parameter to 10 or your required value. it should work..

Making line charts y-axis work?

I'm implementing this charting solution and I'm a little stuck. If I have to line charts in the same graph, as in the first example in the link, but there seems to be a problem with the y-axis. It doesn't show the right ratio between the first and second line chart. See the two images below:
Does anybody have an idea of how to solve this?!
Thanx!
P
I think I understand your problem: the scale of each of the lines on the graph are independent, and the raphael line graph js file is looping through the table data and setting each line's max according to its max value. My recommendation to anyone thinking of using raphaeljs for graphing purposes is to use Graphael instead.
If you REALLY want to fix it, change line 366 of the raphael_linechart in the example files to
max = this.max,
Then add a function that gets the data, and changes the this.max variable to the max value of all the data:
changeMaxValue: function(id) {
var table = helpers.loadTableData(id);
var max = Math.max.apply(Math, table.data);
if(max > this.max) {
this.max = max;
}
},
Pass the id of each table data piece before you actually graph the lines. I didn't test this, so you will have to work out the kinks.

Categories