Skip to content

Commit 858d049

Browse files
authored
feat(router): add minPathMargin option to rightAngle router to suppress margin-overlap detours (#3266)
1 parent 6363f39 commit 858d049

8 files changed

Lines changed: 1149 additions & 502 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<meta name="description" content="A playground for the right-angle router with movable vertices, anchors, and a resize handle.">
8+
<title>JointJS: Right Angle Router Playground</title>
9+
</head>
10+
11+
<body id="app">
12+
<div id="paper-container"></div>
13+
<!-- Application files: -->
14+
<script type="module" src="/src/main.js"></script>
15+
</body>
16+
17+
</html>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "@joint/demo-right-angle-playground-js",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "tsc && vite build",
9+
"preview": "vite preview"
10+
},
11+
"devDependencies": {
12+
"vite": "^7.3.1"
13+
},
14+
"dependencies": {
15+
"@joint/core": "workspace:^"
16+
}
17+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import { dia, shapes, linkTools, elementTools } from '@joint/core';
2+
import './styles.css';
3+
4+
class ResizeTool extends elementTools.Control {
5+
getPosition(view) {
6+
const model = view.model;
7+
const { width, height } = model.size();
8+
return { x: width, y: height };
9+
}
10+
11+
setPosition(view, coordinates) {
12+
const model = view.model;
13+
model.resize(
14+
Math.max(Math.round(coordinates.x / 10) * 10, 50),
15+
Math.max(Math.round(coordinates.y / 10) * 10, 50)
16+
);
17+
}
18+
}
19+
20+
const graph = new dia.Graph({}, { cellNamespace: shapes });
21+
22+
const paper = new dia.Paper({
23+
el: document.getElementById('paper-container'),
24+
width: '100%',
25+
height: '100%',
26+
gridSize: 10,
27+
async: true,
28+
frozen: true,
29+
model: graph,
30+
cellViewNamespace: shapes,
31+
defaultRouter: { name: 'rightAngle', args: {
32+
useVertices: true,
33+
margin: 40,
34+
minPathMargin: 10,
35+
//sourceMargin: 40,
36+
//targetMargin: 30
37+
}},
38+
defaultConnector: { name: 'rounded' },
39+
background: {
40+
color: '#151D29'
41+
},
42+
defaultLinkAnchor: {
43+
name: 'connectionRatio',
44+
args: {
45+
ratio: 0.25
46+
}
47+
}
48+
});
49+
50+
paper.setGrid({ name: 'dot'});
51+
52+
const rect = new shapes.standard.Rectangle({
53+
position: { x: 120, y: 120 },
54+
size: { width: 220, height: 60 },
55+
attrs: {
56+
body: {
57+
stroke: 'none',
58+
fill: '#DF423D',
59+
rx: 10,
60+
ry: 10,
61+
}
62+
}
63+
});
64+
65+
const rect2 = rect.clone();
66+
67+
rect2.resize(60, 220);
68+
rect2.position(300, 250);
69+
70+
const link = new shapes.standard.Link({
71+
attrs: {
72+
line: {
73+
stroke: 'white'
74+
}
75+
}
76+
});
77+
78+
link.source({ id: rect.id, anchor: { name: 'top' }});
79+
link.target({ id: rect2.id, anchor: { name: 'right' }});
80+
81+
graph.addCells([rect, rect2, link]);
82+
83+
rect.findView(paper).addTools(
84+
new dia.ToolsView({
85+
tools: [
86+
new ResizeTool({
87+
selector: 'body',
88+
89+
})
90+
]
91+
})
92+
);
93+
94+
rect2.findView(paper).addTools(
95+
new dia.ToolsView({
96+
tools: [
97+
new ResizeTool({
98+
selector: 'body'
99+
})
100+
]
101+
})
102+
);
103+
104+
const linkToolsView = new dia.ToolsView({
105+
tools: [
106+
new linkTools.Vertices({
107+
focusOpacity: 0.5,
108+
}),
109+
new linkTools.TargetAnchor({
110+
focusOpacity: 0.5,
111+
scale: 1.2
112+
}),
113+
new linkTools.SourceAnchor({
114+
focusOpacity: 0.5,
115+
scale: 1.2
116+
}),
117+
]
118+
});
119+
120+
link.findView(paper).addTools(linkToolsView);
121+
122+
function scaleToFit() {
123+
const graphBBox = graph.getBBox();
124+
paper.transformToFitContent({
125+
contentArea: graphBBox.clone().inflate(0, 100)
126+
});
127+
const { sy } = paper.scale();
128+
const area = paper.getArea();
129+
const yTop = area.height / 2 - graphBBox.y - graphBBox.height / 2;
130+
const xLeft = area.width / 2 - graphBBox.x - graphBBox.width / 2;
131+
paper.translate(xLeft * sy, yTop * sy);
132+
}
133+
134+
window.addEventListener('resize', () => scaleToFit());
135+
scaleToFit();
136+
137+
paper.unfreeze();
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
* {
2+
box-sizing: border-box;
3+
margin: 0;
4+
padding: 0;
5+
}
6+
7+
body {
8+
background-color: #151D29;
9+
width: 100%;
10+
height: 100vh;
11+
}
12+
13+
#paper-container {
14+
position: absolute;
15+
inset: 0;
16+
overflow: hidden;
17+
}

0 commit comments

Comments
 (0)