Skip to content

Commit f8a2dda

Browse files
author
Niklas Kiefer
committed
feat(selection): add marker to related elements
wip iu
1 parent 22174c2 commit f8a2dda

File tree

4 files changed

+239
-3
lines changed

4 files changed

+239
-3
lines changed

assets/diagram-js.css

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,39 @@
88
}
99

1010
.djs-element.hover .djs-outline,
11-
.djs-element.selected .djs-outline {
11+
.djs-element.selected .djs-outline,
12+
.djs-element.related-selected .djs-outline,
13+
.djs-element.related-hover .djs-outline {
1214
visibility: visible;
1315
shape-rendering: crispEdges;
1416
stroke-dasharray: 3,3;
1517
}
1618

1719
.djs-element.selected .djs-outline {
1820
stroke: #8888FF;
21+
opacity: 1;
1922
stroke-width: 1px;
2023
}
2124

2225
.djs-element.hover .djs-outline {
26+
stroke: #FF8888 !important;
27+
opacity: 1 !important;
28+
stroke-width: 1px;
29+
}
30+
31+
.djs-element.related-selected .djs-outline {
32+
stroke: #8888FF;
33+
opacity: 0.5;
34+
stroke-width: 1px;
35+
}
36+
37+
.djs-element.related-hover .djs-outline {
2338
stroke: #FF8888;
39+
opacity: 0.5;
2440
stroke-width: 1px;
2541
}
2642

43+
2744
.djs-shape.connect-ok .djs-visual > :nth-child(1) {
2845
fill: #DCFECC /* light-green */ !important;
2946
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import {
2+
forEach
3+
} from 'min-dash';
4+
5+
import {
6+
getType
7+
} from '../../util/Elements';
8+
9+
var MARKER_RELATED_SELECTED = 'related-selected',
10+
MARKER_RELATED_HOVER = 'related-hover';
11+
12+
13+
/**
14+
* A plugin that adds a visible selection UI to related elements after an element
15+
* was selected by appending the <code>related-selected</code> and
16+
* <code>related-hover</code> classes to them.
17+
*
18+
* @class
19+
*
20+
* Creates outline on related elements after selecting an element
21+
*
22+
* @param {EventBus} events
23+
* @param {Canvas} canvas
24+
*/
25+
export default function HighlightRelated(events, canvas) {
26+
27+
function applyToRelatedElements(e, cls, fn) {
28+
29+
// shape, connection -> mark related labels
30+
if (getType(e) === 'shape' || getType(e) === 'connection') {
31+
forEach(e.labels, function(label) {
32+
fn(label, cls);
33+
});
34+
}
35+
36+
// label -> mark related shape, connection
37+
if (e.labelTarget) {
38+
fn(e.labelTarget, cls);
39+
}
40+
}
41+
42+
function addMarkerToRelated(e, cls) {
43+
applyToRelatedElements(e, cls, canvas.addMarker.bind(canvas));
44+
}
45+
46+
function removeMarkerFromRelated(e, cls) {
47+
applyToRelatedElements(e, cls, canvas.removeMarker.bind(canvas));
48+
}
49+
50+
events.on('element.hover', function(event) {
51+
addMarkerToRelated(event.element, MARKER_RELATED_HOVER);
52+
});
53+
54+
events.on('element.out', function(event) {
55+
removeMarkerFromRelated(event.element, MARKER_RELATED_HOVER);
56+
});
57+
58+
events.on('selection.changed', function(event) {
59+
var oldSelection = event.oldSelection,
60+
newSelection = event.newSelection;
61+
62+
forEach(oldSelection, function(e) {
63+
if (newSelection.indexOf(e) === -1) {
64+
removeMarkerFromRelated(e, MARKER_RELATED_SELECTED);
65+
}
66+
});
67+
68+
forEach(newSelection, function(e) {
69+
if (oldSelection.indexOf(e) === -1) {
70+
addMarkerToRelated(e, MARKER_RELATED_SELECTED);
71+
}
72+
});
73+
});
74+
}
75+
76+
HighlightRelated.$inject = [
77+
'eventBus',
78+
'canvas',
79+
];

lib/features/selection/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@ import OutlineModule from '../outline';
44
import Selection from './Selection';
55
import SelectionVisuals from './SelectionVisuals';
66
import SelectionBehavior from './SelectionBehavior';
7+
import HighlightRelated from './HighlightRelated';
78

89

910
export default {
10-
__init__: [ 'selectionVisuals', 'selectionBehavior' ],
11+
__init__: [ 'selectionVisuals', 'selectionBehavior', 'highlightRelated' ],
1112
__depends__: [
1213
InteractionEventsModule,
1314
OutlineModule
1415
],
1516
selection: [ 'type', Selection ],
1617
selectionVisuals: [ 'type', SelectionVisuals ],
17-
selectionBehavior: [ 'type', SelectionBehavior ]
18+
selectionBehavior: [ 'type', SelectionBehavior ],
19+
highlightRelated: [ 'type', HighlightRelated ]
1820
};
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import {
2+
bootstrapDiagram,
3+
inject
4+
} from 'test/TestHelper';
5+
6+
import selectionModule from 'lib/features/selection';
7+
8+
import {
9+
matches
10+
} from 'min-dom';
11+
12+
13+
describe('features/selection/HighlightRelated', function() {
14+
15+
beforeEach(bootstrapDiagram({ modules: [ selectionModule ] }));
16+
17+
describe('bootstrap', function() {
18+
19+
beforeEach(bootstrapDiagram({ modules: [ selectionModule ] }));
20+
21+
it('should bootstrap diagram with component', inject(function() {
22+
23+
}));
24+
25+
});
26+
27+
describe('selection box on related elements', function() {
28+
29+
var shape, shape2, connection, label, label2;
30+
31+
beforeEach(inject(function(elementFactory, canvas) {
32+
33+
// given
34+
shape = elementFactory.createShape({
35+
id: 'child',
36+
x: 100, y: 100, width: 100, height: 100
37+
});
38+
39+
canvas.addShape(shape);
40+
41+
shape2 = elementFactory.createShape({
42+
id: 'child2',
43+
x: 300, y: 100, width: 100, height: 100
44+
});
45+
46+
canvas.addShape(shape2);
47+
48+
connection = elementFactory.createConnection({
49+
id: 'connection',
50+
waypoints: [ { x: 150, y: 150 }, { x: 150, y: 200 }, { x: 350, y: 150 } ],
51+
source: shape,
52+
target: shape2
53+
});
54+
55+
canvas.addConnection(connection);
56+
57+
label = elementFactory.createLabel({
58+
id: 'label',
59+
x: 100, y: 200, width: 20, height: 20,
60+
labelTarget: shape
61+
});
62+
63+
canvas.addShape(label);
64+
65+
label2 = elementFactory.createLabel({
66+
id: 'label2',
67+
x: 200, y: 200, width: 20, height: 20,
68+
labelTarget: connection
69+
});
70+
71+
canvas.addShape(label2);
72+
}));
73+
74+
describe('shapes', function() {
75+
76+
it('should show box on related label on select',
77+
inject(function(selection, canvas) {
78+
79+
// when
80+
selection.select(shape);
81+
82+
// then
83+
var gfx = canvas.getGraphics(label),
84+
hasOutline = matches(gfx, '.related-selected');
85+
86+
expect(hasOutline).to.be.true;
87+
}));
88+
89+
90+
it('should show box on shape on selecting label',
91+
inject(function(selection, canvas) {
92+
93+
// when
94+
selection.select(label);
95+
96+
// then
97+
var gfx = canvas.getGraphics(shape),
98+
hasOutline = matches(gfx, '.related-selected');
99+
100+
expect(hasOutline).to.be.true;
101+
}));
102+
});
103+
104+
105+
describe('connection', function() {
106+
107+
it('should show box on related label on select',
108+
inject(function(selection, canvas) {
109+
110+
// when
111+
selection.select(connection);
112+
113+
// then
114+
var gfx = canvas.getGraphics(label2),
115+
hasOutline = matches(gfx, '.related-selected');
116+
117+
expect(hasOutline).to.be.true;
118+
}));
119+
120+
121+
it('should paler box on connection on selecting label',
122+
inject(function(selection, canvas) {
123+
124+
// when
125+
selection.select(label2);
126+
127+
// then
128+
var gfx = canvas.getGraphics(connection),
129+
hasOutline = matches(gfx, '.related-selected');
130+
131+
expect(hasOutline).to.be.true;
132+
}));
133+
134+
});
135+
136+
});
137+
138+
});

0 commit comments

Comments
 (0)