Skip to content
This repository has been archived by the owner on Jul 29, 2019. It is now read-only.

Order by id, label nodes #1927

Open
salonso6 opened this issue Jun 28, 2016 · 20 comments
Open

Order by id, label nodes #1927

salonso6 opened this issue Jun 28, 2016 · 20 comments

Comments

@salonso6
Copy link

salonso6 commented Jun 28, 2016

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.

hierarchical:{
  enabled: true,
  levelSeparation: 150,
  direction: 'LR',
  sortMethod: 'directed'
}
@mojoaxel
Copy link
Member

I'm closing this issue due to inactivity.
If this issue is still relevant please feel free to reopen.

@mmcnl
Copy link

mmcnl commented Jun 22, 2017

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'
      }

@wimrijnders
Copy link
Contributor

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:

download 1

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.

@mmcnl
Copy link

mmcnl commented Jun 22, 2017

image
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?

@mmcnl
Copy link

mmcnl commented Jun 22, 2017

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'
      }

@wimrijnders
Copy link
Contributor

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.

@mmcnl
Copy link

mmcnl commented Jun 22, 2017

Oh, that's too bad. Is it possible to define a function to sort nodes based on a custom value added in their data?

@wimrijnders
Copy link
Contributor

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.

@mmcnl
Copy link

mmcnl commented Jun 22, 2017

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

@wimrijnders
Copy link
Contributor

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?

@wimrijnders
Copy link
Contributor

wimrijnders commented Jun 22, 2017

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.

@mmcnl
Copy link

mmcnl commented Jun 22, 2017

OK, here's a try: http://jsfiddle.net/ffq8ch6d/1/ . The nodes were passed in the order of their labels.
image

@mmcnl
Copy link

mmcnl commented Jun 22, 2017

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.

@wimrijnders
Copy link
Contributor

wimrijnders commented Jun 22, 2017

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.

@wimrijnders
Copy link
Contributor

wimrijnders commented Jun 22, 2017

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.

@mmcnl
Copy link

mmcnl commented Jun 22, 2017

@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!

@mmcnl
Copy link

mmcnl commented Jul 20, 2017

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:
image

@wimrijnders
Copy link
Contributor

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).

@mmcnl
Copy link

mmcnl commented Nov 8, 2017

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:
image
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.
image
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.

@mmcnl
Copy link

mmcnl commented Nov 17, 2017

@wimrijnders, I wonder if you might have a moment to weigh in on my previous question? #1927 (comment) Thanks very much!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants