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

Commit

Permalink
Added option hierarchical.layout.userControlsFreeAxis
Browse files Browse the repository at this point in the history
  • Loading branch information
softwareCobbler committed Nov 4, 2018
1 parent 01b3fc6 commit 1788c67
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
17 changes: 16 additions & 1 deletion docs/network/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ <h3>Options</h3>
edgeMinimization: true,
parentCentralization: true,
direction: 'UD', // UD, DU, LR, RL
sortMethod: 'hubsize' // hubsize, directed
sortMethod: 'hubsize', // hubsize, directed
userControlsFreeAxis: false
}
}
}
Expand Down Expand Up @@ -103,6 +104,20 @@ <h3>Options</h3>
<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>
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>
Directed adheres to the to and from data of the edges. A --> B so B is a level lower than A.</td></tr>
<tr parent="hierarchical" class="hidden">
<td class="indent">hierarchical.userControlsFreeAxis</td>
<td>Boolean</td>
<td><code>false</code></td>
<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>
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,
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>
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>)
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,
then later call <code>Network.storePositions()</code> and have the hierarchical layout engine respect the retreived values.<br><br>
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,
it will be returned to its default position.<br><br>
This option is useful with physics disabled.</td>
</tr>
</table>

</div>
Expand Down
36 changes: 35 additions & 1 deletion lib/network/modules/LayoutEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -743,11 +743,18 @@ class LayoutEngine {
this._determineLevelsCustomCallback();
}
}


//
// to be iterated over later, in the userControlsFreeAxis option section
// we iterate over nodeIds once to call ensureLevel, so we might as well
// capture them now
//
let nodeIds = [];

// fallback for cases where there are nodes but no edges
for (let nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) {
nodeIds.push(nodeId);
this.hierarchical.ensureLevel(nodeId);
}
}
Expand All @@ -765,6 +772,33 @@ class LayoutEngine {

// shift to center so gravity does not have to do much
this._shiftToCenter();

//
// if option hierarchical.userControlsFreeAxis is set (to true)
// we will attempt to set each node's free axis position based on Dataset value
// if the node's free axis position is undefined, we skip it and keep the original LayoutEngine-generated value
//
// the free axis in direction DU/UD is x
// the free axis in direction LR/RL is y
//
if (this.options.hierarchical.userControlsFreeAxis) {
let direction = this.options.hierarchical.direction;
let dataSet = this.body.data.nodes.getDataSet();
let freeAxis = "";
if (direction === "UD" || direction === "DU") {
freeAxis = "x";
}
else { // direction === "LR" || direction == "RL", any other values are caught as errors earlier in the program
freeAxis = "y";
}
for (let nodeId of nodeIds) {
let targetPosition = dataSet._data[nodeId][freeAxis];
if (targetPosition !== undefined) {

This comment has been minimized.

Copy link
@softwareCobbler

softwareCobbler Nov 7, 2018

Author

should this be a loose non-equality check (!=)? To allow the expression to return true for both undefined and null values...

this.body.nodes[nodeId][freeAxis] = targetPosition;
}
}
}

}
}
}
Expand Down
4 changes: 3 additions & 1 deletion lib/network/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ let allOptions = {
parentCentralization: { boolean: bool },
direction: { string: ['UD', 'DU', 'LR', 'RL'] }, // UD, DU, LR, RL
sortMethod: { string: ['hubsize', 'directed'] }, // hubsize, directed
userControlsFreeAxis: { boolean: bool },
__type__: { object, boolean: bool }
},
__type__: { object }
Expand Down Expand Up @@ -553,7 +554,8 @@ let configureOptions = {
edgeMinimization: true,
parentCentralization: true,
direction: ['UD', 'DU', 'LR', 'RL'], // UD, DU, LR, RL
sortMethod: ['hubsize', 'directed'] // hubsize, directed
sortMethod: ['hubsize', 'directed'], // hubsize, directed
userControlsFreeAxis: false
}
},
interaction: {
Expand Down

0 comments on commit 1788c67

Please sign in to comment.