Open salonso6 opened 8 years ago
I'm closing this issue due to inactivity. If this issue is still relevant please feel free to reopen.
Hi @mojoaxel and @wimrijnders , I believe I have the same question. I'm using hierarchical layout with the following settings and would love it if the LR order of my nodes followed the order that they are given in the dataset. Is that possible? Ideally I wouldn't want to specify a x
coordinate for each node because I don't care about the exact x
-value, only the L-R ordering on each level of the graph. Also, I saw in the comments mention about setting the x/y coordinates, but couldn't find an example of how to do that using vis.DataSet(nodes);
.
hierarchical: {
direction: 'UD',
levelSeparation: 120,
nodeSpacing: 200,
sortMethod: 'directed'
}
I'm trying to understand the question.....what I think you mean, is that network flips around the order of the nodes when building up the network, right?
I've been trying to hack a quick example of networks not following the dataset order, without success. I can show the converse though. I think this is what you want:
So, given that the node id's are the order in the dataset, the second level is strictly numbered. After that, the ordering breaks down because of the defined edges. But the ordering is maintained as much as possible.
Is this correct?
So a changed ordering is the network
module trying to optimize (for space) the layout of a network. You do have some control over this; try disabling the following options (also read up on them in the docs):
layout.hierarchical.blockShifting
layout.hierarchical.edgeMinimization
The resulting layout will be less efficient in terms of space used, but it will probably be more like you want it.
Thanks for the quick reply @wimrijnders ! What I'd like is to be able to sort nodes on a particular level. For example in the screenshot, despite sending an array sorted in order of the numbers in the labels (biggest to smallest), the network renders in some other order (that I'm not understanding). So specifically, I'd like to ensure that the last level is ordered [3998] [563] [87] [0] [0]. Is that possible?
I tried setting the options you mentioned, but it didn't seem to make any difference.
hierarchical: {
direction: 'UD',
levelSeparation: 120,
nodeSpacing: 200,
blockShifting: false,
edgeMinimization: false,
sortMethod: 'directed'
}
OK. So my immediate reaction was 'Hold on, let me check the code...'
Then I realized that that meant the answer is 'No'. There is no out of the box support for sorting per level.
But I'll check the code anyway.
Oh, that's too bad. Is it possible to define a function to sort nodes based on a custom value added in their data?
I tried setting the options you mentioned, but it didn't seem to make any difference.
Yeah, now that I understand the question a bit better, I realize that my suggestion is moot. What happens then, is that the order of definition in the DataSet
is maintained, which is not what you want. You want an explicit sort on a given field of the DataSet
items.
As I do have full control of the order of the dataset, I was sending in the array with its values sorted, so I was hoping that they would be put into levels in the same order, eg:
1
2 3
4 5 6 7
And this didn't happen? The nodes don't get rendered in the order you enforced?
I think a simple example is in order if you want to pursue this further. Would you mind setting up a jsfiddle
or suchlike?
Is it possible to define a function to sort nodes based on a custom value added in their data?
Yes, in a roundabout way. Following code is untested, but it illustrates the process:
var data = new vis.DataSet(input_data);
var sorted_data = data.get({
order: function(a, b) {
// Your glorious sort routine here
}
});
var data2 = new vis.DataSet(sorted_data);
var network = new vis.Network(container, data2, options);
... but TBH, network
will still probably mangle the order in the way it sees fit. So actually, this is useless and I regard the above as an exercise to warm up my fingers for today's coding.
Edit: It did give me an idea, though, on adding sorting to DataView
. So it wasn't completely pointless.
OK, here's a try: http://jsfiddle.net/ffq8ch6d/1/ . The nodes were passed in the order of their labels.
Also, I realize what I really want is for ordering among sibling nodes. So in the above, my ideal would be:
x
162276 1162
57301 13173 325 498 326 26
I realize this is probably out of scope but it would be amazing if it could be accomplished.
Oh my, the turnaround time is awesome here. It motivates me to check the code.
I realize what I really want is for ordering among sibling nodes
Yes, that is finally clear to me now.
Interim note: It appears that the key method here is _setPositionForHierarchy()
in lib/network/modules/LayoutEngine.js
. This should somehow be manipulated for sorting purposes, and _condenseHierarchy()
should not run - that shuffles up the network.
I'll let it rest for now; my evil pointy haired boss, which is me, is getting impatient.
Update: Have to ask, is this something you want RSN? Because it's not something I can offer a workaround for. You'll have to wait for its release (one month at the very least). In the meantime you might use an interim build of vis.js
with a fix for this.
@wimrijnders I am trying to demo a prototype of my project soon (in the next 2 weeks), so I might investigate a monkeypatched version of vis.js
and I'll keep my eyes out for a new release. Also, if there's a dev version of the code, I'm happy to use that if that would be available sooner than an official release. Once again, thanks so much for all of the gracious support with this!
Hi @wimrijnders , I'm looking into this issue again and was curious if there's been any movement in the dev channels on this. Thanks again for the help with this question.
Update: I've just realized that it appears that it seems possibly to reliably control the within-level node ordering by simply changing the order of the edges. For example, in this fiddle http://jsfiddle.net/ffq8ch6d/1/ changing the last two edges from:
{
"from": 2915,
"to": 2916
},
{
"from": 2915,
"to": 2917
}
to this:
{
"from": 2915,
"to": 2917
},
{
"from": 2915,
"to": 2916
},
reliably swaps the position of these nodes:
I'm looking into this issue again and was curious if there's been any movement in the dev channels on this.
Alas, no. I've been squashing bugs lately and haven't come around to handling stuff I regard as 'feature-requests'. Sorry.
it seems possibly to reliably control the within-level node ordering by simply changing the order of the edges
Genius thought! Of course, the strict handling on order also applies to edges. I should have been able to think of that myself (which is what makes it genius).
Hello again @wimrijnders, I've run into a case where the edge-ordering trick falls down: when there is even one node with more than one parent edge (i.e. it's not strictly hierarchical), it seems the edge-ordering is abandoned and the network reverts to sorting based on the ids of the nodes. I've made a jsfiddle to illustrate: For example, here the nodes are grouped by the ordering of the edges. http://jsfiddle.net/qz4s5724/2/ This is ideal for me, as I can easily control the insertion order of edges: However in this next example, http://jsfiddle.net/qz4s5724/3/ by simply adding one additional edge , the ordering is scrambled and it seems the network reverts to sorting based on the ids of the nodes. Is this what's actually taking place? This is not ideal for my application because I don't have control over the ids and nodes can add parents (and become a graph not a tree) at any time.
Do you have any ideas for workarounds? Or could I make a feature request to add an "order" field that would override the sorting at a given level of the hierarchy?
Thanks much for any ideas.
@wimrijnders, I wonder if you might have a moment to weigh in on my previous question? https://github.com/almende/vis/issues/1927#issuecomment-342757779 Thanks very much!
Hi,
I´m using the version 4.15.0 I want to know if you can sort the nodes by id, label or other attribute which are at the same level. I can send my example.