-
Notifications
You must be signed in to change notification settings - Fork 113
/
Copy pathconstraints.js
100 lines (85 loc) · 2.28 KB
/
constraints.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { Constraint, Operator, Strength } from 'kiwi.js';
/**
* Constraint base definitions.
*
* See `solve` function of `solver.js` for constraint specification.
*/
/**
* Layout constraint in Y for separating rows
*/
export const rowConstraint = {
property: 'y',
strict: (constraint, constants, variableA, variableB) =>
new Constraint(
variableA.minus(variableB),
Operator.Ge,
constants.spaceY,
Strength.required
),
};
/**
* Layout constraint in Y for separating layers
*/
export const layerConstraint = {
property: 'y',
strict: (constraint, constants, variableA, variableB) =>
new Constraint(
variableA.minus(variableB),
Operator.Ge,
constants.layerSpace,
Strength.required
),
};
/**
* Layout constraint in X for minimising distance from source to target for straight edges
*/
export const parallelConstraint = {
property: 'x',
solve: (constraint) => {
const { a, b, strength } = constraint;
const resolve = strength * (a.x - b.x);
a.x -= resolve;
b.x += resolve;
},
strict: (constraint, constants, variableA, variableB) =>
new Constraint(
variableA.minus(variableB),
Operator.Eq,
0,
Strength.create(1, 0, 0, constraint.strength)
),
};
/**
* Crossing constraint in X for minimising edge crossings
*/
export const crossingConstraint = {
property: 'x',
solve: (constraint) => {
const { edgeA, edgeB, separationA, separationB, strength } = constraint;
// Amount to move each node towards required separation
const resolveSource =
strength *
((edgeA.sourceNode.x - edgeB.sourceNode.x - separationA) / separationA);
const resolveTarget =
strength *
((edgeA.targetNode.x - edgeB.targetNode.x - separationB) / separationB);
// Apply the resolve each node
edgeA.sourceNode.x -= resolveSource;
edgeB.sourceNode.x += resolveSource;
edgeA.targetNode.x -= resolveTarget;
edgeB.targetNode.x += resolveTarget;
},
};
/**
* Layout constraint in X for minimum node separation
*/
export const separationConstraint = {
property: 'x',
strict: (constraint, constants, variableA, variableB) =>
new Constraint(
variableB.minus(variableA),
Operator.Ge,
constraint.separation,
Strength.required
),
};