Skip to content

Commit ee43b1d

Browse files
authored
Example layout strategies (#503)
* Add example for custom views * Add layout strategies example * Clean up * Update example with Miro's comments
1 parent fac2ef3 commit ee43b1d

File tree

11 files changed

+2230
-0
lines changed

11 files changed

+2230
-0
lines changed

examples/browser-app.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import runJsxample from "./jsxample/src/standalone";
2727
import runStylingShowcase from "./styling-showcase/src/standalone";
2828
import runMicroLayoutShowcase from "./micro-layout-showcase/src/standalone";
2929
import runCustomViewsShowcase from "./custom-views-showcase/src/standalone";
30+
import runLayoutStrategiesShowcase from "./layout-strategies-showcase/src/standalone";
3031

3132
const appDiv = document.getElementById('sprotty-app');
3233
if (appDiv) {
@@ -53,6 +54,8 @@ if (appDiv) {
5354
runMicroLayoutShowcase();
5455
else if (appMode === 'custom-views-showcase')
5556
runCustomViewsShowcase();
57+
else if (appMode === 'layout-strategies-showcase')
58+
runLayoutStrategiesShowcase();
5659
else
5760
throw new Error('Dunno what to do :-(');
5861
}
Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
/********************************************************************************
2+
* Copyright (c) 2025 TypeFox and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the Eclipse
10+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
11+
* with the GNU Classpath Exception which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
********************************************************************************/
16+
17+
/* Custom Views Diagram Styles */
18+
19+
/* Basic Shape Views */
20+
.basic-shape-node {
21+
cursor: pointer;
22+
transition: all 0.2s ease;
23+
}
24+
25+
.basic-shape-node.mouseover {
26+
filter: brightness(1.1);
27+
}
28+
29+
.basic-shape-node.selected {
30+
filter: drop-shadow(0 0 8px rgba(25, 118, 210, 0.6));
31+
}
32+
33+
.basic-shape {
34+
transition: all 0.2s ease;
35+
}
36+
37+
.shape-circle {
38+
filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.1));
39+
}
40+
41+
.shape-triangle {
42+
filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.1));
43+
}
44+
45+
.shape-diamond {
46+
filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.1));
47+
}
48+
49+
/* Enhanced Node Views */
50+
.enhanced-node {
51+
cursor: pointer;
52+
transition: all 0.2s ease;
53+
}
54+
55+
.enhanced-rect {
56+
fill: #f8f9fa;
57+
stroke: #dee2e6;
58+
stroke-width: 1;
59+
transition: all 0.2s ease;
60+
}
61+
62+
.enhanced-node.status-warning .enhanced-rect {
63+
fill: #fff8e1;
64+
stroke: #ffb74d;
65+
}
66+
67+
.enhanced-node.status-error .enhanced-rect {
68+
fill: #ffebee;
69+
stroke: #ef5350;
70+
}
71+
72+
.enhanced-node.status-success .enhanced-rect {
73+
fill: #e8f5e8;
74+
stroke: #66bb6a;
75+
}
76+
77+
.enhanced-node.selected .enhanced-rect {
78+
stroke-width: 2;
79+
stroke: #1976d2;
80+
}
81+
82+
.enhanced-node.mouseover .enhanced-rect {
83+
filter: brightness(0.95);
84+
}
85+
86+
.status-indicator {
87+
transition: all 0.2s ease;
88+
}
89+
90+
.indicator-warning {
91+
fill: #ff9800;
92+
}
93+
94+
.indicator-error {
95+
fill: #f44336;
96+
}
97+
98+
.indicator-success {
99+
fill: #4caf50;
100+
}
101+
102+
.enhanced-border {
103+
stroke: #1976d2;
104+
stroke-dasharray: 5, 5;
105+
animation: border-dash 1s linear infinite;
106+
}
107+
108+
@keyframes border-dash {
109+
to {
110+
stroke-dashoffset: 10;
111+
}
112+
}
113+
114+
/* Complex Node Views */
115+
.complex-node {
116+
cursor: pointer;
117+
}
118+
119+
.complex-container {
120+
fill: #ffffff;
121+
stroke: #e0e0e0;
122+
stroke-width: 1;
123+
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.1));
124+
}
125+
126+
.complex-node.selected .complex-container {
127+
stroke: #1976d2;
128+
stroke-width: 2;
129+
}
130+
131+
.complex-node.mouseover .complex-container {
132+
filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.15));
133+
}
134+
135+
.header-rect {
136+
rx: 4;
137+
ry: 4;
138+
}
139+
140+
.header-title {
141+
font-weight: bold;
142+
font-size: 14px;
143+
}
144+
145+
.header-subtitle {
146+
font-size: 10px;
147+
opacity: 0.8;
148+
}
149+
150+
.header-icon {
151+
font-size: 16px;
152+
}
153+
154+
.body-rect {
155+
fill: #fafafa;
156+
}
157+
158+
.footer-line {
159+
stroke: #e0e0e0;
160+
stroke-width: 1;
161+
}
162+
163+
/* Stateful Node Views */
164+
.stateful-node {
165+
cursor: pointer;
166+
transition: all 0.3s ease;
167+
}
168+
169+
/* Loading state */
170+
.state-loading .loading-background {
171+
fill: #e3f2fd;
172+
stroke: #1976d2;
173+
stroke-width: 1;
174+
}
175+
176+
.progress-background {
177+
fill: #e0e0e0;
178+
rx: 2;
179+
ry: 2;
180+
}
181+
182+
.progress-fill {
183+
fill: #1976d2;
184+
rx: 2;
185+
ry: 2;
186+
transition: width 0.2s ease;
187+
}
188+
189+
.loading-text {
190+
fill: #1976d2;
191+
font-size: 12px;
192+
font-weight: 500;
193+
}
194+
195+
/* Error state */
196+
.state-error .error-background {
197+
fill: #ffebee;
198+
stroke: #f44336;
199+
stroke-width: 2;
200+
}
201+
202+
.error-icon {
203+
fill: #f44336;
204+
font-size: 16px;
205+
font-weight: bold;
206+
}
207+
208+
.error-text {
209+
fill: #d32f2f;
210+
font-size: 12px;
211+
font-weight: 500;
212+
}
213+
214+
/* Success state */
215+
.state-success .success-background {
216+
fill: #e8f5e8;
217+
stroke: #4caf50;
218+
stroke-width: 2;
219+
}
220+
221+
.success-icon {
222+
fill: #4caf50;
223+
font-size: 16px;
224+
font-weight: bold;
225+
}
226+
227+
.success-text {
228+
fill: #2e7d32;
229+
font-size: 12px;
230+
font-weight: 500;
231+
}
232+
233+
/* Idle state */
234+
.state-idle .idle-background {
235+
fill: #f5f5f5;
236+
stroke: #9e9e9e;
237+
stroke-width: 1;
238+
}
239+
240+
.idle-text {
241+
fill: #616161;
242+
font-size: 12px;
243+
}
244+
245+
/* Styled Edge Views */
246+
.styled-edge {
247+
transition: all 0.2s ease;
248+
}
249+
250+
.styled-edge.mouseover {
251+
filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.3));
252+
}
253+
254+
.edge-solid {
255+
/* Default solid style */
256+
}
257+
258+
.edge-dashed {
259+
stroke-dasharray: 10, 5;
260+
}
261+
262+
.edge-dotted {
263+
stroke-dasharray: 2, 3;
264+
}
265+
266+
.edge-animated {
267+
animation: edge-flow 2s linear infinite;
268+
}
269+
270+
@keyframes edge-flow {
271+
to {
272+
stroke-dashoffset: 20;
273+
}
274+
}
275+
276+
.arrow-head {
277+
transition: all 0.2s ease;
278+
}
279+
280+
/* Custom Label Views */
281+
.custom-label {
282+
pointer-events: none;
283+
}
284+
285+
.label-background {
286+
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));
287+
}
288+
289+
.label-text {
290+
fill: #333;
291+
text-anchor: middle;
292+
dominant-baseline: middle;
293+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
294+
}
295+
296+
/* General Sprotty overrides */
297+
.sprotty-graph {
298+
background: linear-gradient(45deg, #f0f2f5 25%, transparent 25%),
299+
linear-gradient(-45deg, #f0f2f5 25%, transparent 25%),
300+
linear-gradient(45deg, transparent 75%, #f0f2f5 75%),
301+
linear-gradient(-45deg, transparent 75%, #f0f2f5 75%);
302+
background-size: 20px 20px;
303+
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
304+
}
305+
306+
.sprotty-node:hover {
307+
cursor: pointer;
308+
}
309+
310+
.sprotty-edge:hover {
311+
cursor: pointer;
312+
}
313+
314+
/* Selection highlighting */
315+
.selected {
316+
filter: drop-shadow(0 0 8px rgba(25, 118, 210, 0.6));
317+
}
318+
319+
/* Hover effects */
320+
.mouseover {
321+
filter: brightness(1.05);
322+
}
323+
324+
/* Responsive adjustments */
325+
@media (max-width: 768px) {
326+
.header-title {
327+
font-size: 12px;
328+
}
329+
330+
.header-subtitle {
331+
font-size: 9px;
332+
}
333+
334+
.label-text {
335+
font-size: 10px;
336+
}
337+
}

examples/index.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ <h3>Recipes</h3>
3030
Comprehensive demonstration of custom view patterns including basic shapes, enhanced nodes,
3131
compositional views, stateful rendering, and custom edges.
3232
</li>
33+
<li><a href="layout-strategies-showcase/layout-strategies-showcase.html">Layout Strategies
34+
Showcase:</a><br>
35+
Interactive comparison of client-only, server-only, and hybrid layout strategies with
36+
performance
37+
monitoring and real-world use case examples.
38+
</li>
3339
</ul>
3440

3541
<h3>Without Server</h3>

0 commit comments

Comments
 (0)