@joint/core 4.0.4 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -8
- package/dist/geometry.js +4962 -6132
- package/dist/geometry.min.js +2 -2
- package/dist/joint.d.ts +328 -50
- package/dist/joint.js +34067 -37565
- package/dist/joint.min.js +2 -2
- package/dist/joint.nowrap.js +34067 -37565
- package/dist/joint.nowrap.min.js +2 -2
- package/dist/vectorizer.js +7288 -8907
- package/dist/vectorizer.min.js +2 -2
- package/dist/version.mjs +1 -1
- package/package.json +10 -15
- package/src/{linkTools → cellTools}/Button.mjs +8 -6
- package/src/{elementTools → cellTools}/Control.mjs +3 -3
- package/src/{linkTools → cellTools}/HoverConnect.mjs +1 -1
- package/src/dia/Cell.mjs +60 -33
- package/src/dia/CellView.mjs +75 -8
- package/src/dia/ElementView.mjs +13 -8
- package/src/dia/Graph.mjs +148 -40
- package/src/dia/HighlighterView.mjs +8 -4
- package/src/dia/LinkView.mjs +42 -3
- package/src/dia/Paper.mjs +84 -0
- package/src/dia/ToolView.mjs +29 -4
- package/src/dia/ToolsView.mjs +25 -10
- package/src/dia/attributes/connection.mjs +5 -0
- package/src/dia/attributes/defs.mjs +3 -0
- package/src/dia/attributes/eval.mjs +3 -3
- package/src/dia/attributes/index.mjs +3 -0
- package/src/dia/attributes/shape.mjs +4 -0
- package/src/dia/attributes/text.mjs +15 -5
- package/src/dia/ports.mjs +4 -0
- package/src/elementTools/HoverConnect.mjs +5 -5
- package/src/elementTools/index.mjs +5 -4
- package/src/g/rect.mjs +13 -5
- package/src/layout/ports/port.mjs +4 -5
- package/src/linkTools/Anchor.mjs +1 -1
- package/src/linkTools/Arrowhead.mjs +2 -1
- package/src/linkTools/RotateLabel.mjs +110 -0
- package/src/linkTools/Segments.mjs +1 -1
- package/src/linkTools/Vertices.mjs +41 -4
- package/src/linkTools/index.mjs +7 -4
- package/src/mvc/View.mjs +0 -1
- package/src/mvc/ViewBase.mjs +2 -1
- package/src/routers/rightAngle.mjs +538 -140
- package/src/shapes/standard.mjs +8 -1
- package/src/{dia/attributes → util}/calc.mjs +24 -12
- package/src/util/index.mjs +1 -0
- package/src/util/util.mjs +39 -0
- package/src/util/utilHelpers.mjs +2 -1
- package/types/geometry.d.ts +6 -1
- package/types/joint.d.ts +321 -48
- /package/src/{linkTools → cellTools}/Boundary.mjs +0 -0
- /package/src/{linkTools → cellTools}/Connect.mjs +0 -0
- /package/src/{linkTools → cellTools}/helpers.mjs +0 -0
package/src/dia/LinkView.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { CellView } from './CellView.mjs';
|
|
|
2
2
|
import { Link } from './Link.mjs';
|
|
3
3
|
import V from '../V/index.mjs';
|
|
4
4
|
import { addClassNamePrefix, merge, assign, isObject, isFunction, clone, isPercentage, result, isEqual } from '../util/index.mjs';
|
|
5
|
-
import { Point, Line, Path, normalizeAngle, Rect, Polyline } from '../g/index.mjs';
|
|
5
|
+
import { Point, Line, Path, normalizeAngle, Rect, Polyline, intersection } from '../g/index.mjs';
|
|
6
6
|
import * as routers from '../routers/index.mjs';
|
|
7
7
|
import * as connectors from '../connectors/index.mjs';
|
|
8
8
|
import { env } from '../env/index.mjs';
|
|
@@ -63,7 +63,7 @@ export const LinkView = CellView.extend({
|
|
|
63
63
|
attrs: [Flags.UPDATE],
|
|
64
64
|
router: [Flags.UPDATE],
|
|
65
65
|
connector: [Flags.CONNECTOR],
|
|
66
|
-
labels: [Flags.LABELS],
|
|
66
|
+
labels: [Flags.LABELS, Flags.TOOLS],
|
|
67
67
|
labelMarkup: [Flags.LABELS],
|
|
68
68
|
vertices: [Flags.UPDATE],
|
|
69
69
|
source: [Flags.SOURCE, Flags.UPDATE],
|
|
@@ -73,6 +73,7 @@ export const LinkView = CellView.extend({
|
|
|
73
73
|
initFlag: [Flags.RENDER, Flags.SOURCE, Flags.TARGET, Flags.TOOLS],
|
|
74
74
|
|
|
75
75
|
UPDATE_PRIORITY: 1,
|
|
76
|
+
EPSILON: 1e-6,
|
|
76
77
|
|
|
77
78
|
confirmUpdate: function(flags, opt) {
|
|
78
79
|
|
|
@@ -461,6 +462,13 @@ export const LinkView = CellView.extend({
|
|
|
461
462
|
|
|
462
463
|
if (!this._V.labels) return this;
|
|
463
464
|
|
|
465
|
+
if (!this.paper.options.labelLayer) {
|
|
466
|
+
// If there is no label layer, the cache needs to be cleared
|
|
467
|
+
// of the root node because the labels are attached
|
|
468
|
+
// to it and could affect the bounding box.
|
|
469
|
+
this.cleanNodeCache(this.el);
|
|
470
|
+
}
|
|
471
|
+
|
|
464
472
|
var model = this.model;
|
|
465
473
|
var labels = model.get('labels') || [];
|
|
466
474
|
var canLabelMove = this.can('labelMove');
|
|
@@ -816,6 +824,34 @@ export const LinkView = CellView.extend({
|
|
|
816
824
|
return connectionPoint.round(this.decimalsRounding);
|
|
817
825
|
},
|
|
818
826
|
|
|
827
|
+
isIntersecting: function(geometryShape, geometryData) {
|
|
828
|
+
const connection = this.getConnection();
|
|
829
|
+
if (!connection) return false;
|
|
830
|
+
return intersection.exists(
|
|
831
|
+
geometryShape,
|
|
832
|
+
connection,
|
|
833
|
+
geometryData,
|
|
834
|
+
{ segmentSubdivisions: this.getConnectionSubdivisions() },
|
|
835
|
+
);
|
|
836
|
+
},
|
|
837
|
+
|
|
838
|
+
isEnclosedIn: function(geometryRect) {
|
|
839
|
+
const connection = this.getConnection();
|
|
840
|
+
if (!connection) return false;
|
|
841
|
+
const bbox = connection.bbox();
|
|
842
|
+
if (!bbox) return false;
|
|
843
|
+
return geometryRect.containsRect(bbox);
|
|
844
|
+
},
|
|
845
|
+
|
|
846
|
+
isAtPoint: function(point /*, options */) {
|
|
847
|
+
// Note: `strict` option is not applicable for links.
|
|
848
|
+
// There is currently no method to determine if a path contains a point.
|
|
849
|
+
const area = new Rect(point);
|
|
850
|
+
// Intersection with a zero-size area is not possible.
|
|
851
|
+
area.inflate(this.EPSILON);
|
|
852
|
+
return this.isIntersecting(area);
|
|
853
|
+
},
|
|
854
|
+
|
|
819
855
|
// combine default label position with built-in default label position
|
|
820
856
|
_getDefaultLabelPositionProperty: function() {
|
|
821
857
|
|
|
@@ -1823,7 +1859,10 @@ export const LinkView = CellView.extend({
|
|
|
1823
1859
|
// checking view in close area of the pointer
|
|
1824
1860
|
|
|
1825
1861
|
var r = snapLinks.radius || 50;
|
|
1826
|
-
var viewsInArea = paper.
|
|
1862
|
+
var viewsInArea = paper.findElementViewsInArea(
|
|
1863
|
+
{ x: x - r, y: y - r, width: 2 * r, height: 2 * r },
|
|
1864
|
+
snapLinks.findInAreaOptions
|
|
1865
|
+
);
|
|
1827
1866
|
|
|
1828
1867
|
var prevClosestView = data.closestView || null;
|
|
1829
1868
|
var prevClosestMagnet = data.closestMagnet || null;
|
package/src/dia/Paper.mjs
CHANGED
|
@@ -382,6 +382,11 @@ export const Paper = View.extend({
|
|
|
382
382
|
],
|
|
383
383
|
MIN_SCALE: 1e-6,
|
|
384
384
|
|
|
385
|
+
// Default find buffer for the findViewsInArea and findViewsAtPoint methods.
|
|
386
|
+
// The find buffer is used to extend the area of the search
|
|
387
|
+
// to mitigate the differences between the model and view geometry.
|
|
388
|
+
DEFAULT_FIND_BUFFER: 200,
|
|
389
|
+
|
|
385
390
|
init: function() {
|
|
386
391
|
|
|
387
392
|
const { options } = this;
|
|
@@ -1858,6 +1863,85 @@ export const Paper = View.extend({
|
|
|
1858
1863
|
}, this);
|
|
1859
1864
|
},
|
|
1860
1865
|
|
|
1866
|
+
findElementViewsInArea(plainArea, opt) {
|
|
1867
|
+
return this._filterViewsInArea(
|
|
1868
|
+
plainArea,
|
|
1869
|
+
(extArea, findOpt) => this.model.findElementsInArea(extArea, findOpt),
|
|
1870
|
+
opt
|
|
1871
|
+
);
|
|
1872
|
+
},
|
|
1873
|
+
|
|
1874
|
+
findLinkViewsInArea: function(plainArea, opt) {
|
|
1875
|
+
return this._filterViewsInArea(
|
|
1876
|
+
plainArea,
|
|
1877
|
+
(extArea, findOpt) => this.model.findLinksInArea(extArea, findOpt),
|
|
1878
|
+
opt
|
|
1879
|
+
);
|
|
1880
|
+
},
|
|
1881
|
+
|
|
1882
|
+
findCellViewsInArea: function(plainArea, opt) {
|
|
1883
|
+
return this._filterViewsInArea(
|
|
1884
|
+
plainArea,
|
|
1885
|
+
(extArea, findOpt) => this.model.findCellsInArea(extArea, findOpt),
|
|
1886
|
+
opt
|
|
1887
|
+
);
|
|
1888
|
+
},
|
|
1889
|
+
|
|
1890
|
+
findElementViewsAtPoint: function(plainPoint, opt) {
|
|
1891
|
+
return this._filterViewsAtPoint(
|
|
1892
|
+
plainPoint,
|
|
1893
|
+
(extArea) => this.model.findElementsInArea(extArea),
|
|
1894
|
+
opt
|
|
1895
|
+
);
|
|
1896
|
+
},
|
|
1897
|
+
|
|
1898
|
+
findLinkViewsAtPoint: function(plainPoint, opt) {
|
|
1899
|
+
return this._filterViewsAtPoint(
|
|
1900
|
+
plainPoint,
|
|
1901
|
+
(extArea) => this.model.findLinksInArea(extArea),
|
|
1902
|
+
opt,
|
|
1903
|
+
);
|
|
1904
|
+
},
|
|
1905
|
+
|
|
1906
|
+
findCellViewsAtPoint: function(plainPoint, opt) {
|
|
1907
|
+
return this._filterViewsAtPoint(
|
|
1908
|
+
plainPoint,
|
|
1909
|
+
// Note: we do not want to pass `opt` to `findCellsInArea`
|
|
1910
|
+
// because the `strict` option works differently for querying at a point
|
|
1911
|
+
(extArea) => this.model.findCellsInArea(extArea),
|
|
1912
|
+
opt
|
|
1913
|
+
);
|
|
1914
|
+
},
|
|
1915
|
+
|
|
1916
|
+
_findInExtendedArea: function(area, findCellsFn, opt = {}) {
|
|
1917
|
+
const {
|
|
1918
|
+
buffer = this.DEFAULT_FIND_BUFFER,
|
|
1919
|
+
} = opt;
|
|
1920
|
+
const extendedArea = (new Rect(area)).inflate(buffer);
|
|
1921
|
+
const cellsInExtendedArea = findCellsFn(extendedArea, opt);
|
|
1922
|
+
return cellsInExtendedArea.map(element => this.findViewByModel(element));
|
|
1923
|
+
},
|
|
1924
|
+
|
|
1925
|
+
_filterViewsInArea: function(plainArea, findCells, opt = {}) {
|
|
1926
|
+
const area = new Rect(plainArea);
|
|
1927
|
+
const viewsInExtendedArea = this._findInExtendedArea(area, findCells, opt);
|
|
1928
|
+
const viewsInArea = viewsInExtendedArea.filter(view => {
|
|
1929
|
+
if (!view) return false;
|
|
1930
|
+
return view.isInArea(area, opt);
|
|
1931
|
+
});
|
|
1932
|
+
return viewsInArea;
|
|
1933
|
+
},
|
|
1934
|
+
|
|
1935
|
+
_filterViewsAtPoint: function(plainPoint, findCells, opt = {}) {
|
|
1936
|
+
const area = new Rect(plainPoint); // zero-size area
|
|
1937
|
+
const viewsInExtendedArea = this._findInExtendedArea(area, findCells, opt);
|
|
1938
|
+
const viewsAtPoint = viewsInExtendedArea.filter(view => {
|
|
1939
|
+
if (!view) return false;
|
|
1940
|
+
return view.isAtPoint(plainPoint, opt);
|
|
1941
|
+
});
|
|
1942
|
+
return viewsAtPoint;
|
|
1943
|
+
},
|
|
1944
|
+
|
|
1861
1945
|
removeTools: function() {
|
|
1862
1946
|
this.dispatchToolsEvent('remove');
|
|
1863
1947
|
return this;
|
package/src/dia/ToolView.mjs
CHANGED
|
@@ -6,6 +6,7 @@ export const ToolView = mvc.View.extend({
|
|
|
6
6
|
className: 'tool',
|
|
7
7
|
svgElement: true,
|
|
8
8
|
_visible: true,
|
|
9
|
+
_visibleExplicit: true,
|
|
9
10
|
|
|
10
11
|
init: function() {
|
|
11
12
|
var name = this.name;
|
|
@@ -30,16 +31,40 @@ export const ToolView = mvc.View.extend({
|
|
|
30
31
|
return this.name;
|
|
31
32
|
},
|
|
32
33
|
|
|
34
|
+
// Evaluate the visibility of the tool and update the `display` CSS property
|
|
35
|
+
updateVisibility: function() {
|
|
36
|
+
const isVisible = this.computeVisibility();
|
|
37
|
+
this.el.style.display = isVisible ? '' : 'none';
|
|
38
|
+
this._visible = isVisible;
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
// Evaluate the visibility of the tool. The method returns `true` if the tool
|
|
42
|
+
// should be visible in the DOM.
|
|
43
|
+
computeVisibility() {
|
|
44
|
+
if (!this.isExplicitlyVisible()) return false;
|
|
45
|
+
const { visibility } = this.options;
|
|
46
|
+
if (typeof visibility !== 'function') return true;
|
|
47
|
+
return !!visibility.call(this, this.relatedView, this);
|
|
48
|
+
},
|
|
49
|
+
|
|
33
50
|
show: function() {
|
|
34
|
-
this.
|
|
35
|
-
this.
|
|
51
|
+
this._visibleExplicit = true;
|
|
52
|
+
this.updateVisibility();
|
|
36
53
|
},
|
|
37
54
|
|
|
38
55
|
hide: function() {
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
56
|
+
this._visibleExplicit = false;
|
|
57
|
+
this.updateVisibility();
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
// The method returns `false` if the `hide()` method was called on the tool.
|
|
61
|
+
isExplicitlyVisible: function() {
|
|
62
|
+
return !!this._visibleExplicit;
|
|
41
63
|
},
|
|
42
64
|
|
|
65
|
+
// The method returns `false` if the tool is not visible (it has `display: none`).
|
|
66
|
+
// This can happen if the `hide()` method was called or the tool is not visible
|
|
67
|
+
// because of the `visibility` option was evaluated to `false`.
|
|
43
68
|
isVisible: function() {
|
|
44
69
|
return !!this._visible;
|
|
45
70
|
},
|
package/src/dia/ToolsView.mjs
CHANGED
|
@@ -44,25 +44,37 @@ export const ToolsView = mvc.View.extend({
|
|
|
44
44
|
update: function(opt) {
|
|
45
45
|
|
|
46
46
|
opt || (opt = {});
|
|
47
|
-
|
|
47
|
+
const tools = this.tools;
|
|
48
48
|
if (!tools) return this;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
const n = tools.length;
|
|
50
|
+
const wasRendered = this.isRendered;
|
|
51
|
+
for (let i = 0; i < n; i++) {
|
|
52
|
+
const tool = tools[i];
|
|
53
|
+
tool.updateVisibility();
|
|
54
|
+
if (!tool.isVisible()) continue;
|
|
55
|
+
if (!this.isRendered) {
|
|
56
|
+
// There is at least one visible tool
|
|
57
|
+
this.isRendered = Array(n).fill(false);
|
|
58
|
+
}
|
|
59
|
+
if (!this.isRendered[i]) {
|
|
53
60
|
// First update executes render()
|
|
54
61
|
tool.render();
|
|
55
|
-
|
|
62
|
+
this.isRendered[i] = true;
|
|
63
|
+
} else if (opt.tool !== tool.cid) {
|
|
56
64
|
tool.update();
|
|
57
65
|
}
|
|
58
66
|
}
|
|
67
|
+
if (!this.isRendered && n > 0) {
|
|
68
|
+
// None of the tools is visible
|
|
69
|
+
// Note: ToolsView with no tools are always mounted
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
59
72
|
if (!this.isMounted()) {
|
|
60
73
|
this.mount();
|
|
61
74
|
}
|
|
62
|
-
if (!
|
|
75
|
+
if (!wasRendered) {
|
|
63
76
|
// Make sure tools are visible (if they were hidden and the tool removed)
|
|
64
77
|
this.blurTool();
|
|
65
|
-
this.isRendered = true;
|
|
66
78
|
}
|
|
67
79
|
return this;
|
|
68
80
|
},
|
|
@@ -87,9 +99,12 @@ export const ToolsView = mvc.View.extend({
|
|
|
87
99
|
if (!tools) return this;
|
|
88
100
|
for (var i = 0, n = tools.length; i < n; i++) {
|
|
89
101
|
var tool = tools[i];
|
|
90
|
-
if (tool !== blurredTool && !tool.
|
|
102
|
+
if (tool !== blurredTool && !tool.isExplicitlyVisible()) {
|
|
91
103
|
tool.show();
|
|
92
|
-
tool
|
|
104
|
+
// Check if the tool is conditionally visible too
|
|
105
|
+
if (tool.isVisible()) {
|
|
106
|
+
tool.update();
|
|
107
|
+
}
|
|
93
108
|
}
|
|
94
109
|
}
|
|
95
110
|
return this;
|
|
@@ -25,6 +25,7 @@ const connectionAttributesNS = {
|
|
|
25
25
|
|
|
26
26
|
'connection': {
|
|
27
27
|
qualify: isLinkView,
|
|
28
|
+
unset: 'd',
|
|
28
29
|
set: function({ stubs = 0 }) {
|
|
29
30
|
let d;
|
|
30
31
|
if (isFinite(stubs) && stubs !== 0) {
|
|
@@ -49,21 +50,25 @@ const connectionAttributesNS = {
|
|
|
49
50
|
|
|
50
51
|
'at-connection-length-keep-gradient': {
|
|
51
52
|
qualify: isLinkView,
|
|
53
|
+
unset: 'transform',
|
|
52
54
|
set: atConnectionWrapper('getTangentAtLength', { rotate: true })
|
|
53
55
|
},
|
|
54
56
|
|
|
55
57
|
'at-connection-length-ignore-gradient': {
|
|
56
58
|
qualify: isLinkView,
|
|
59
|
+
unset: 'transform',
|
|
57
60
|
set: atConnectionWrapper('getTangentAtLength', { rotate: false })
|
|
58
61
|
},
|
|
59
62
|
|
|
60
63
|
'at-connection-ratio-keep-gradient': {
|
|
61
64
|
qualify: isLinkView,
|
|
65
|
+
unset: 'transform',
|
|
62
66
|
set: atConnectionWrapper('getTangentAtRatio', { rotate: true })
|
|
63
67
|
},
|
|
64
68
|
|
|
65
69
|
'at-connection-ratio-ignore-gradient': {
|
|
66
70
|
qualify: isLinkView,
|
|
71
|
+
unset: 'transform',
|
|
67
72
|
set: atConnectionWrapper('getTangentAtRatio', { rotate: false })
|
|
68
73
|
}
|
|
69
74
|
|
|
@@ -33,6 +33,7 @@ const defsAttributesNS = {
|
|
|
33
33
|
|
|
34
34
|
'source-marker': {
|
|
35
35
|
qualify: isPlainObject,
|
|
36
|
+
unset: 'marker-start',
|
|
36
37
|
set: function(marker, refBBox, node, attrs) {
|
|
37
38
|
marker = assign(contextMarker(attrs), marker);
|
|
38
39
|
return { 'marker-start': 'url(#' + this.paper.defineMarker(marker) + ')' };
|
|
@@ -41,6 +42,7 @@ const defsAttributesNS = {
|
|
|
41
42
|
|
|
42
43
|
'target-marker': {
|
|
43
44
|
qualify: isPlainObject,
|
|
45
|
+
unset: 'marker-end',
|
|
44
46
|
set: function(marker, refBBox, node, attrs) {
|
|
45
47
|
marker = assign(contextMarker(attrs), { 'transform': 'rotate(180)' }, marker);
|
|
46
48
|
return { 'marker-end': 'url(#' + this.paper.defineMarker(marker) + ')' };
|
|
@@ -49,6 +51,7 @@ const defsAttributesNS = {
|
|
|
49
51
|
|
|
50
52
|
'vertex-marker': {
|
|
51
53
|
qualify: isPlainObject,
|
|
54
|
+
unset: 'marker-mid',
|
|
52
55
|
set: function(marker, refBBox, node, attrs) {
|
|
53
56
|
marker = assign(contextMarker(attrs), marker);
|
|
54
57
|
return { 'marker-mid': 'url(#' + this.paper.defineMarker(marker) + ')' };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isCalcExpression, evalCalcExpression } from '../../util/calc.mjs';
|
|
2
2
|
|
|
3
3
|
const calcAttributesList = [
|
|
4
4
|
'transform',
|
|
@@ -53,8 +53,8 @@ export function evalAttributes(attrs, refBBox) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export function evalAttribute(attrName, attrValue, refBBox) {
|
|
56
|
-
if (attrName in calcAttributes &&
|
|
57
|
-
let evalAttrValue =
|
|
56
|
+
if (attrName in calcAttributes && isCalcExpression(attrValue)) {
|
|
57
|
+
let evalAttrValue = evalCalcExpression(attrValue, refBBox);
|
|
58
58
|
if (attrName in positiveValueAttributes) {
|
|
59
59
|
evalAttrValue = Math.max(0, evalAttrValue);
|
|
60
60
|
}
|
|
@@ -69,18 +69,22 @@ function pointsWrapper(opt) {
|
|
|
69
69
|
const shapeAttributesNS = {
|
|
70
70
|
|
|
71
71
|
'ref-d-reset-offset': {
|
|
72
|
+
unset: 'd',
|
|
72
73
|
set: dWrapper({ resetOffset: true })
|
|
73
74
|
},
|
|
74
75
|
|
|
75
76
|
'ref-d-keep-offset': {
|
|
77
|
+
unset: 'd',
|
|
76
78
|
set: dWrapper({ resetOffset: false })
|
|
77
79
|
},
|
|
78
80
|
|
|
79
81
|
'ref-points-reset-offset': {
|
|
82
|
+
unset: 'points',
|
|
80
83
|
set: pointsWrapper({ resetOffset: true })
|
|
81
84
|
},
|
|
82
85
|
|
|
83
86
|
'ref-points-keep-offset': {
|
|
87
|
+
unset: 'points',
|
|
84
88
|
set: pointsWrapper({ resetOffset: false })
|
|
85
89
|
},
|
|
86
90
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assign, isPlainObject, isObject, isPercentage, breakText } from '../../util/util.mjs';
|
|
2
|
-
import {
|
|
2
|
+
import { isCalcExpression, evalCalcExpression } from '../../util/calc.mjs';
|
|
3
3
|
import $ from '../../mvc/Dom/index.mjs';
|
|
4
4
|
import V from '../../V/index.mjs';
|
|
5
5
|
|
|
@@ -40,6 +40,9 @@ const textAttributesNS = {
|
|
|
40
40
|
const textWrap = attrs['text-wrap'];
|
|
41
41
|
return !textWrap || !isPlainObject(textWrap);
|
|
42
42
|
},
|
|
43
|
+
unset: function(node) {
|
|
44
|
+
node.textContent = '';
|
|
45
|
+
},
|
|
43
46
|
set: function(text, refBBox, node, attrs) {
|
|
44
47
|
const cacheName = 'joint-text';
|
|
45
48
|
const cache = $.data.get(node, cacheName);
|
|
@@ -91,8 +94,8 @@ const textAttributesNS = {
|
|
|
91
94
|
var width = value.width || 0;
|
|
92
95
|
if (isPercentage(width)) {
|
|
93
96
|
size.width = refBBox.width * parseFloat(width) / 100;
|
|
94
|
-
} else if (
|
|
95
|
-
size.width = Number(
|
|
97
|
+
} else if (isCalcExpression(width)) {
|
|
98
|
+
size.width = Number(evalCalcExpression(width, refBBox));
|
|
96
99
|
} else {
|
|
97
100
|
if (value.width === null) {
|
|
98
101
|
// breakText() requires width to be specified.
|
|
@@ -107,8 +110,8 @@ const textAttributesNS = {
|
|
|
107
110
|
var height = value.height || 0;
|
|
108
111
|
if (isPercentage(height)) {
|
|
109
112
|
size.height = refBBox.height * parseFloat(height) / 100;
|
|
110
|
-
} else if (
|
|
111
|
-
size.height = Number(
|
|
113
|
+
} else if (isCalcExpression(height)) {
|
|
114
|
+
size.height = Number(evalCalcExpression(height, refBBox));
|
|
112
115
|
} else {
|
|
113
116
|
if (value.height === null) {
|
|
114
117
|
// if height is not specified breakText() does not
|
|
@@ -171,6 +174,13 @@ const textAttributesNS = {
|
|
|
171
174
|
// HTMLElement title is specified via an attribute (i.e. not an element)
|
|
172
175
|
return node instanceof SVGElement;
|
|
173
176
|
},
|
|
177
|
+
unset: function(node) {
|
|
178
|
+
$.data.remove(node, 'joint-title');
|
|
179
|
+
const titleNode = node.firstElementChild;
|
|
180
|
+
if (titleNode) {
|
|
181
|
+
titleNode.remove();
|
|
182
|
+
}
|
|
183
|
+
},
|
|
174
184
|
set: function(title, refBBox, node) {
|
|
175
185
|
var cacheName = 'joint-title';
|
|
176
186
|
var cache = $.data.get(node, cacheName);
|
package/src/dia/ports.mjs
CHANGED
|
@@ -280,6 +280,10 @@ export const elementPortPrototype = {
|
|
|
280
280
|
}));
|
|
281
281
|
},
|
|
282
282
|
|
|
283
|
+
getPortGroupNames: function() {
|
|
284
|
+
return Object.keys(this._portSettingsData.groups);
|
|
285
|
+
},
|
|
286
|
+
|
|
283
287
|
/**
|
|
284
288
|
* @param {string} groupName
|
|
285
289
|
* @returns {Object<portId, {x: number, y: number, angle: number}>}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { HoverConnect as LinkHoverConnect } from '../
|
|
1
|
+
import { HoverConnect as LinkHoverConnect } from '../cellTools/HoverConnect.mjs';
|
|
2
2
|
import V from '../V/index.mjs';
|
|
3
3
|
import * as g from '../g/index.mjs';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { isCalcExpression, evalCalcExpression } from '../util/calc.mjs';
|
|
5
|
+
import { getViewBBox } from '../cellTools/helpers.mjs';
|
|
6
6
|
|
|
7
7
|
export const HoverConnect = LinkHoverConnect.extend({
|
|
8
8
|
|
|
@@ -15,9 +15,9 @@ export const HoverConnect = LinkHoverConnect.extend({
|
|
|
15
15
|
if (typeof trackPath === 'function') {
|
|
16
16
|
trackPath = trackPath.call(this, view);
|
|
17
17
|
}
|
|
18
|
-
if (
|
|
18
|
+
if (isCalcExpression(trackPath)) {
|
|
19
19
|
const bbox = getViewBBox(view, useModelGeometry);
|
|
20
|
-
trackPath =
|
|
20
|
+
trackPath = evalCalcExpression(trackPath, bbox);
|
|
21
21
|
}
|
|
22
22
|
return new g.Path(V.normalizePathData(trackPath));
|
|
23
23
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export * from './Control.mjs';
|
|
2
|
-
export { Button, Remove } from '../linkTools/Button.mjs';
|
|
3
|
-
export { Connect } from '../linkTools/Connect.mjs';
|
|
4
|
-
export { Boundary } from '../linkTools/Boundary.mjs';
|
|
5
1
|
export { HoverConnect } from './HoverConnect.mjs';
|
|
2
|
+
|
|
3
|
+
export { Button, Remove } from '../cellTools/Button.mjs';
|
|
4
|
+
export { Connect } from '../cellTools/Connect.mjs';
|
|
5
|
+
export { Boundary } from '../cellTools/Boundary.mjs';
|
|
6
|
+
export { Control } from '../cellTools/Control.mjs';
|
package/src/g/rect.mjs
CHANGED
|
@@ -138,12 +138,20 @@ Rect.prototype = {
|
|
|
138
138
|
},
|
|
139
139
|
|
|
140
140
|
// @return {bool} true if point p is inside me.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
// @param {bool} strict If true, the point has to be strictly inside (not on the border).
|
|
142
|
+
containsPoint: function(p, opt) {
|
|
143
|
+
let x, y;
|
|
144
|
+
if (!p || (typeof p === 'string')) {
|
|
145
|
+
// Backwards compatibility: if the point is not provided,
|
|
146
|
+
// the point is considered to be the origin [0, 0].
|
|
147
|
+
({ x, y } = new Point(p));
|
|
148
|
+
} else {
|
|
149
|
+
// Do not create a new Point object if the point is already a Point-like object.
|
|
150
|
+
({ x = 0, y = 0 } = p);
|
|
145
151
|
}
|
|
146
|
-
return
|
|
152
|
+
return opt && opt.strict
|
|
153
|
+
? (x > this.x && x < this.x + this.width && y > this.y && y < this.y + this.height)
|
|
154
|
+
: x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height;
|
|
147
155
|
},
|
|
148
156
|
|
|
149
157
|
// @return {bool} true if rectangle `r` is inside me.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { evalCalcAttribute, isCalcAttribute } from '../../dia/attributes/calc.mjs';
|
|
2
1
|
import * as g from '../../g/index.mjs';
|
|
3
2
|
import * as util from '../../util/index.mjs';
|
|
4
3
|
|
|
@@ -58,13 +57,13 @@ function argTransform(bbox, args) {
|
|
|
58
57
|
let { x, y, angle } = args;
|
|
59
58
|
if (util.isPercentage(x)) {
|
|
60
59
|
x = parseFloat(x) / 100 * bbox.width;
|
|
61
|
-
} else if (
|
|
62
|
-
x = Number(
|
|
60
|
+
} else if (util.isCalcExpression(x)) {
|
|
61
|
+
x = Number(util.evalCalcExpression(x, bbox));
|
|
63
62
|
}
|
|
64
63
|
if (util.isPercentage(y)) {
|
|
65
64
|
y = parseFloat(y) / 100 * bbox.height;
|
|
66
|
-
} else if (
|
|
67
|
-
y = Number(
|
|
65
|
+
} else if (util.isCalcExpression(y)) {
|
|
66
|
+
y = Number(util.evalCalcExpression(y, bbox));
|
|
68
67
|
}
|
|
69
68
|
return { x, y, angle };
|
|
70
69
|
}
|
package/src/linkTools/Anchor.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as g from '../g/index.mjs';
|
|
2
2
|
import * as util from '../util/index.mjs';
|
|
3
3
|
import { ToolView } from '../dia/ToolView.mjs';
|
|
4
|
-
import { getAnchor, snapAnchor } from '
|
|
4
|
+
import { getAnchor, snapAnchor } from '../cellTools/helpers.mjs';
|
|
5
5
|
|
|
6
6
|
const Anchor = ToolView.extend({
|
|
7
7
|
tagName: 'g',
|
|
@@ -51,7 +51,8 @@ const Arrowhead = ToolView.extend({
|
|
|
51
51
|
var paper = relatedView.paper;
|
|
52
52
|
relatedView.model.startBatch('arrowhead-move', { ui: true, tool: this.cid });
|
|
53
53
|
relatedView.startArrowheadMove(this.arrowheadType);
|
|
54
|
-
|
|
54
|
+
const data = evt.data || (evt.data = {});
|
|
55
|
+
this.delegateDocumentEvents(null, data);
|
|
55
56
|
paper.undelegateEvents();
|
|
56
57
|
this.focus();
|
|
57
58
|
this.el.style.pointerEvents = 'none';
|