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

Commit 1788c67

Browse files
Added option hierarchical.layout.userControlsFreeAxis
1 parent 01b3fc6 commit 1788c67

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

docs/network/layout.html

+16-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ <h3>Options</h3>
6666
edgeMinimization: true,
6767
parentCentralization: true,
6868
direction: 'UD', // UD, DU, LR, RL
69-
sortMethod: 'hubsize' // hubsize, directed
69+
sortMethod: 'hubsize', // hubsize, directed
70+
userControlsFreeAxis: false
7071
}
7172
}
7273
}
@@ -103,6 +104,20 @@ <h3>Options</h3>
103104
<tr parent="hierarchical" class="hidden"><td class="indent">hierarchical.sortMethod</td><td>String</td><td><code>'hubsize'</code></td> <td>The algorithm used to ascertain the levels of the nodes based on the data. The possible options are: <code>hubsize, directed</code>. <br><br>
104105
Hubsize takes the nodes with the most edges and puts them at the top. From that the rest of the hierarchy is evaluated. <br><br>
105106
Directed adheres to the to and from data of the edges. A --> B so B is a level lower than A.</td></tr>
107+
<tr parent="hierarchical" class="hidden">
108+
<td class="indent">hierarchical.userControlsFreeAxis</td>
109+
<td>Boolean</td>
110+
<td><code>false</code></td>
111+
<td>Whether or not the value specified by a node's <code>Dataset</code> <code>x</code> or <code>y</code> values will affect a node's layout along its "free" axis.<br><br>
112+
If the hierarchical layout <code>direction</code> is either <code>"DU"</code> or <code>"UD"</code>, vis.js will layout the node using the Node's <code>x</code> property,
113+
or if <code>direction</code>is either <code>"LR"</code> or <code>"RL"</code>, vis.js will use the node's <code>y</code> property.<br><br>
114+
If the property vis wants to use (e.g., the <code>x</code> or <code>y</code> property on the node within the target <code>Dataset</code>)
115+
is undefined, the default behavior is invoked, as though this option were set to <code>false</code>. This provides the ability to initally utilize Vis's default layout,
116+
then later call <code>Network.storePositions()</code> and have the hierarchical layout engine respect the retreived values.<br><br>
117+
This option is helpful because updating a hierarchically layed-out graph will trigger a redraw, and without this option, if a node has been moved along its free axis,
118+
it will be returned to its default position.<br><br>
119+
This option is useful with physics disabled.</td>
120+
</tr>
106121
</table>
107122

108123
</div>

lib/network/modules/LayoutEngine.js

+35-1
Original file line numberDiff line numberDiff line change
@@ -743,11 +743,18 @@ class LayoutEngine {
743743
this._determineLevelsCustomCallback();
744744
}
745745
}
746-
746+
747+
//
748+
// to be iterated over later, in the userControlsFreeAxis option section
749+
// we iterate over nodeIds once to call ensureLevel, so we might as well
750+
// capture them now
751+
//
752+
let nodeIds = [];
747753

748754
// fallback for cases where there are nodes but no edges
749755
for (let nodeId in this.body.nodes) {
750756
if (this.body.nodes.hasOwnProperty(nodeId)) {
757+
nodeIds.push(nodeId);
751758
this.hierarchical.ensureLevel(nodeId);
752759
}
753760
}
@@ -765,6 +772,33 @@ class LayoutEngine {
765772

766773
// shift to center so gravity does not have to do much
767774
this._shiftToCenter();
775+
776+
//
777+
// if option hierarchical.userControlsFreeAxis is set (to true)
778+
// we will attempt to set each node's free axis position based on Dataset value
779+
// if the node's free axis position is undefined, we skip it and keep the original LayoutEngine-generated value
780+
//
781+
// the free axis in direction DU/UD is x
782+
// the free axis in direction LR/RL is y
783+
//
784+
if (this.options.hierarchical.userControlsFreeAxis) {
785+
let direction = this.options.hierarchical.direction;
786+
let dataSet = this.body.data.nodes.getDataSet();
787+
let freeAxis = "";
788+
if (direction === "UD" || direction === "DU") {
789+
freeAxis = "x";
790+
}
791+
else { // direction === "LR" || direction == "RL", any other values are caught as errors earlier in the program
792+
freeAxis = "y";
793+
}
794+
for (let nodeId of nodeIds) {
795+
let targetPosition = dataSet._data[nodeId][freeAxis];
796+
if (targetPosition !== undefined) {
797+
this.body.nodes[nodeId][freeAxis] = targetPosition;
798+
}
799+
}
800+
}
801+
768802
}
769803
}
770804
}

lib/network/options.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ let allOptions = {
183183
parentCentralization: { boolean: bool },
184184
direction: { string: ['UD', 'DU', 'LR', 'RL'] }, // UD, DU, LR, RL
185185
sortMethod: { string: ['hubsize', 'directed'] }, // hubsize, directed
186+
userControlsFreeAxis: { boolean: bool },
186187
__type__: { object, boolean: bool }
187188
},
188189
__type__: { object }
@@ -553,7 +554,8 @@ let configureOptions = {
553554
edgeMinimization: true,
554555
parentCentralization: true,
555556
direction: ['UD', 'DU', 'LR', 'RL'], // UD, DU, LR, RL
556-
sortMethod: ['hubsize', 'directed'] // hubsize, directed
557+
sortMethod: ['hubsize', 'directed'], // hubsize, directed
558+
userControlsFreeAxis: false
557559
}
558560
},
559561
interaction: {

0 commit comments

Comments
 (0)