Skip to content

Commit

Permalink
feat(edges): make self reference position configurable (#230)
Browse files Browse the repository at this point in the history
* no message

* selfReference property

* no message

* no message

* no message

* no message

* no message

* changed side property to angle

* lint fixes

* unit test fix

* comments and small changes

* formatting

* no message

* no message

* no message

* no message

* no message

* no message

* no message

* no message

* no message

* no message

* no message

* test html

* no message

* no message

* no message

* no message

* no message

* no message

* no message
  • Loading branch information
piratuks authored and Thomaash committed Jan 21, 2020
1 parent a00f8f7 commit 323e3a7
Show file tree
Hide file tree
Showing 11 changed files with 300 additions and 65 deletions.
25 changes: 25 additions & 0 deletions docs-kr/network/edges.html
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ <h3>옵션</h3>
},
selectionWidth: 1,
selfReferenceSize:20,
selfReference:{
size: 20,
angle: Math.PI / 4
},
shadow:{
enabled: false,
color: 'rgba(0,0,0,0.5)',
Expand Down Expand Up @@ -886,6 +890,27 @@ <h3>옵션</h3>
<td><code>false</code></td>
<td>to Node와 from Node가 동일한 경우, 원이 그려집니다. 이것은 그 원의 반지름입니다.</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','selfReference', this);">
<td><span parent="arrows" class="right-caret"></span> selfReference</td>
<td>Object</td>
<td><code>Object</code></td>
<td>TODO
</td>
</tr>
<tr parent="selfReference" class="hidden">
<td class="indent">selfReference.size</td>
<td>Number</td>
<td><code>20</code></td>
<td>TODO
</td>
</tr>
<tr parent="selfReference" class="hidden">
<td class="indent">selfReference.angle</td>
<td>Number</td>
<td><code>π / 4</code></td>
<td>TODO
</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','shadow', this);">
<td><span parent="shadow" class="right-caret"></span> shadow</td>
<td>Object or Boolean</td>
Expand Down
32 changes: 30 additions & 2 deletions docs/network/edges.html
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,11 @@ <h3>Options</h3>
}
},
selectionWidth: 1,
selfReferenceSize:20,
selfReferenceSize: 20,
selfReference:{
size: 20,
angle: Math.PI / 4
},
shadow:{
enabled: false,
color: 'rgba(0,0,0,0.5)',
Expand Down Expand Up @@ -895,7 +899,31 @@ <h3>Options</h3>
<td>selfReferenceSize</td>
<td>Number</td>
<td><code>false</code></td>
<td>When the to and from nodes are the same, a circle is drawn. This is the radius of that circle.</td>
<td>When the to and from nodes are the same, a circle is drawn. This is the radius of that circle.
This property is deprecated please use selfReference instead.
</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','selfReference', this);">
<td><span parent="arrows" class="right-caret"></span> selfReference</td>
<td>Object</td>
<td><code>Object</code></td>
<td>When the to and from nodes are the same, a circle is drawn. This provides radius of circle and position.
</td>
</tr>
<tr parent="selfReference" class="hidden">
<td class="indent">selfReference.size</td>
<td>Number</td>
<td><code>20</code></td>
<td>This is the radius of circle.
</td>
</tr>
<tr parent="selfReference" class="hidden">
<td class="indent">selfReference.angle</td>
<td>Number</td>
<td><code>π / 4</code></td>
<td> This is the angle (Provided in radians) to indicate position for the circle. If position is not provided then it will
be top-right (π / 4) corner.
</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','shadow', this);">
<td><span parent="shadow" class="right-caret"></span> shadow</td>
Expand Down
84 changes: 84 additions & 0 deletions examples/network/edgeStyles/selfReference.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<!doctype html>
<html>

<head>
<title>Vis Network | Edge Styles | Self Reference</title>

<script type="text/javascript" src="../../../standalone/umd/vis-network.js"></script>

<style type="text/css">
#mynetwork {
width: 800px;
height: 600px;
border: 1px solid lightgray;
}
</style>
</head>

<body>

<div id="mynetwork"></div>

<script type="text/javascript">

// create an array with nodes
var nodes = new vis.DataSet([
{
id: 1,
label:
"I'm an alligator,\nI'm a mama-papa coming for you.\nI'm the space invader,\nI'll be a rock 'n' rollin' bitch for you",
x:0,
y:0
},
{
id: 2,
label:
"Test shape",
widthConstraint: { minimum: 100 }, heightConstraint: { minimum: 100 },
x:200,
y:200
}
]);

// create an array with edges
var edges = new vis.DataSet([
{ from: 1, to: 1, label: "Moonage Daydream" },
{ from: 2, to: 2, label: "Testing", arrows: 'to, middle, from', selfReference: { size: 40, angle: Math.PI / 6 } }
]);

// create a network
var container = document.getElementById("mynetwork");
var data = {
nodes: nodes,
edges: edges
};
var options = {};
var network = new vis.Network(container, data, options);

(async () => {
let angle = -100;

for (; ;) {
await new Promise(resolve => setTimeout(resolve, 100));

++angle;
console.log("set self reference angle to", angle / 10);
network.setOptions({
edges: {
arrows: { to: true, from: true, middle: true },
selfReference: {
size: 20,
angle: angle / 10
}
}
});
}
})();


</script>


</body>

</html>
5 changes: 4 additions & 1 deletion lib/network/modules/EdgesHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ class EdgesHandler {
}
},
selectionWidth: 1.5,
selfReferenceSize:20,
selfReference: {
size: 20,
angle: Math.PI / 4,
},
shadow:{
enabled: false,
color: 'rgba(0,0,0,0.5)',
Expand Down
42 changes: 28 additions & 14 deletions lib/network/modules/components/Edge.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class Edge {
'scaling',
'selectionWidth',
'selfReferenceSize',
'selfReference',
'to',
'title',
'value',
Expand Down Expand Up @@ -249,6 +250,15 @@ class Edge {
if (allowDeletion === true && newOptions.font === null) {
parentOptions.font = util.bridgeObject(globalOptions.font); // set the object back to the global options
}

if(newOptions.hasOwnProperty("selfReferenceSize")){
console.log('The selfReferenceSize property has been deprecated. Please use selfReference property instead. The selfReference can be set like thise selfReference:{size:30, angle:Math.PI / 4}');
parentOptions.selfReference = {
size: newOptions.selfReferenceSize,
angle: parentOptions.selfReference.angle
}
}

}


Expand Down Expand Up @@ -676,17 +686,22 @@ class Edge {
else {
// Ignore the orientations.
this.labelModule.pointToSelf = true;
var x, y;
var radius = this.options.selfReferenceSize;
if (node1.shape.width > node1.shape.height) {
x = node1.x + node1.shape.width * 0.5;
y = node1.y - radius;
}
else {
x = node1.x + radius;
y = node1.y - node1.shape.height * 0.5;
}
point = this._pointOnCircle(x, y, radius, 0.125);

// get circle coordinates
const coordinates = ComponentUtil.getSelfRefCoordinates(
ctx,
this.options.selfReference.angle,
this.options.selfReference.size,
node1
);

point = this._pointOnCircle(
coordinates.x,
coordinates.y,
this.options.selfReference.size,
this.options.selfReference.angle
);

this.labelModule.draw(ctx, point.x, point.y, this.selected, this.hover);
}
}
Expand Down Expand Up @@ -796,12 +811,11 @@ class Edge {
* @param {number} x
* @param {number} y
* @param {number} radius
* @param {number} percentage Value between 0 (line start) and 1 (line end)
* @param {number} angle
* @return {Object} point
* @private
*/
_pointOnCircle(x, y, radius, percentage) {
var angle = percentage * 2 * Math.PI;
_pointOnCircle(x, y, radius, angle) {
return {
x: x + radius * Math.cos(angle),
y: y - radius * Math.sin(angle)
Expand Down
49 changes: 28 additions & 21 deletions lib/network/modules/components/edges/util/edge-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
VNode
} from "./types";
import { drawDashedLine } from "./shapes";
import * as ComponentUtil from "./../../shared/ComponentUtil";

export interface FindBorderPositionOptions<Via> {
via: Via;
Expand Down Expand Up @@ -106,6 +107,7 @@ export abstract class EdgeBase<Via = undefined> implements EdgeType {
*/
public setOptions(options: EdgeOptions): void {
this.options = options;

this.from = this._body.nodes[this.options.from];
this.to = this._body.nodes[this.options.to];
this.id = this.options.id;
Expand Down Expand Up @@ -318,26 +320,23 @@ export abstract class EdgeBase<Via = undefined> implements EdgeType {
protected _getCircleData(
ctx?: CanvasRenderingContext2D
): [number, number, number] {
let x: number;
let y: number;
const node = this.from;
const radius = this.options.selfReferenceSize;
const radius = this.options.selfReference.size;

if (ctx !== undefined) {
if (node.shape.width === undefined) {
node.shape.resize(ctx);
if (this.from.shape.width === undefined) {
this.from.shape.resize(ctx);
}
}

// get circle coordinates
if (node.shape.width > node.shape.height) {
x = node.x + node.shape.width * 0.5;
y = node.y - radius;
} else {
x = node.x + radius;
y = node.y - node.shape.height * 0.5;
}
return [x, y, radius];
const coordinates = ComponentUtil.default.getSelfRefCoordinates(
ctx,
this.options.selfReference.angle,
radius,
this.from
);

return [coordinates.x, coordinates.y, radius];
}

/**
Expand Down Expand Up @@ -387,9 +386,10 @@ export abstract class EdgeBase<Via = undefined> implements EdgeType {
const direction = options.direction;

const maxIterations = 10;
const radius = this.options.selfReferenceSize;
const radius = this.options.selfReference.size;
const threshold = 0.05;
let pos: Point;

let middle = (low + high) * 0.5;

let iteration = 0;
Expand Down Expand Up @@ -746,28 +746,35 @@ export abstract class EdgeBase<Via = undefined> implements EdgeType {
const [x, y, radius] = this._getCircleData(ctx);

if (position === "from") {
const low = this.options.selfReference.angle - 2 * Math.PI;
const high = this.options.selfReference.angle;

const pointT = this._findBorderPositionCircle(this.from, ctx, {
x,
y,
low: 0.25,
high: 0.6,
low,
high,
direction: -1
});
angle = pointT.t * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
arrowPoint = pointT;
} else if (position === "to") {
const low = this.options.selfReference.angle - 2 * Math.PI;
const high = this.options.selfReference.angle;

const pointT = this._findBorderPositionCircle(this.from, ctx, {
x,
y,
low: 0.6,
high: 1.0,
low,
high,
direction: 1
});
angle = pointT.t * -2 * Math.PI + 1.5 * Math.PI - 1.1 * Math.PI;
arrowPoint = pointT;
} else {
arrowPoint = this._pointOnCircle(x, y, radius, 0.175);
angle = 3.9269908169872414; // === 0.175 * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
const pos = this.options.selfReference.angle / (2 * Math.PI);
arrowPoint = this._pointOnCircle(x, y, radius, pos);
angle = pos * -2 * Math.PI + 1.5 * Math.PI + 0.1 * Math.PI;
}
}

Expand Down
Loading

0 comments on commit 323e3a7

Please sign in to comment.