Skip to content

Commit

Permalink
feat(selection): add marker to related elements
Browse files Browse the repository at this point in the history
  • Loading branch information
Niklas Kiefer committed Oct 30, 2018
1 parent 22174c2 commit edc4b0b
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 3 deletions.
19 changes: 18 additions & 1 deletion assets/diagram-js.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,39 @@
}

.djs-element.hover .djs-outline,
.djs-element.selected .djs-outline {
.djs-element.selected .djs-outline,
.djs-element.related-selected .djs-outline,
.djs-element.related-hover .djs-outline {
visibility: visible;
shape-rendering: crispEdges;
stroke-dasharray: 3,3;
}

.djs-element.selected .djs-outline {
stroke: #8888FF;
opacity: 1;
stroke-width: 1px;
}

.djs-element.hover .djs-outline {
stroke: #FF8888;
opacity: 1;
stroke-width: 1px;
}

.djs-element.related-selected .djs-outline {
stroke: #8888FF;
opacity: 0.5;
stroke-width: 1px;
}

.djs-element.related-hover .djs-outline {
stroke: #FF8888;
opacity: 0.5;
stroke-width: 1px;
}


.djs-shape.connect-ok .djs-visual > :nth-child(1) {
fill: #DCFECC /* light-green */ !important;
}
Expand Down
79 changes: 79 additions & 0 deletions lib/features/selection/HighlightRelated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
forEach
} from 'min-dash';

import {
getType
} from '../../util/Elements';

var MARKER_RELATED_SELECTED = 'related-selected',
MARKER_RELATED_HOVER = 'related-hover';


/**
* A plugin that adds a visible selection UI to related elements after an element
* was selected by appending the <code>related-selected</code> and
* <code>related-hover</code> classes to them.
*
* @class
*
* Creates outline on related elements after selecting an element
*
* @param {EventBus} events
* @param {Canvas} canvas
*/
export default function HighlightRelated(events, canvas) {

function applyToRelatedElements(e, cls, fn) {

// shape, connection -> mark related labels
if (getType(e) === 'shape' || getType(e) === 'connection') {
forEach(e.labels, function(label) {
fn(label, cls);
});
}

// label -> mark related shape, connection
if (e.labelTarget) {
fn(e.labelTarget, cls);
}
}

function addMarkerToRelated(e, cls) {
applyToRelatedElements(e, cls, canvas.addMarker.bind(canvas));
}

function removeMarkerFromRelated(e, cls) {
applyToRelatedElements(e, cls, canvas.removeMarker.bind(canvas));
}

events.on('element.hover', function(event) {
addMarkerToRelated(event.element, MARKER_RELATED_HOVER);
});

events.on('element.out', function(event) {
removeMarkerFromRelated(event.element, MARKER_RELATED_HOVER);
});

events.on('selection.changed', function(event) {
var oldSelection = event.oldSelection,
newSelection = event.newSelection;

forEach(oldSelection, function(e) {
if (newSelection.indexOf(e) === -1) {
removeMarkerFromRelated(e, MARKER_RELATED_SELECTED);
}
});

forEach(newSelection, function(e) {
if (oldSelection.indexOf(e) === -1) {
addMarkerToRelated(e, MARKER_RELATED_SELECTED);
}
});
});
}

HighlightRelated.$inject = [
'eventBus',
'canvas',
];
6 changes: 4 additions & 2 deletions lib/features/selection/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ import OutlineModule from '../outline';
import Selection from './Selection';
import SelectionVisuals from './SelectionVisuals';
import SelectionBehavior from './SelectionBehavior';
import HighlightRelated from './HighlightRelated';


export default {
__init__: [ 'selectionVisuals', 'selectionBehavior' ],
__init__: [ 'selectionVisuals', 'selectionBehavior', 'highlightRelated' ],
__depends__: [
InteractionEventsModule,
OutlineModule
],
selection: [ 'type', Selection ],
selectionVisuals: [ 'type', SelectionVisuals ],
selectionBehavior: [ 'type', SelectionBehavior ]
selectionBehavior: [ 'type', SelectionBehavior ],
highlightRelated: [ 'type', HighlightRelated ]
};
140 changes: 140 additions & 0 deletions test/spec/features/selection/HighlightRelatedSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import {
bootstrapDiagram,
inject
} from 'test/TestHelper';

import selectionModule from 'lib/features/selection';

import {
matches
} from 'min-dom';


describe('features/selection/HighlightRelated', function() {

beforeEach(bootstrapDiagram({ modules: [ selectionModule ] }));

describe('bootstrap', function() {

beforeEach(bootstrapDiagram({ modules: [ selectionModule ] }));

it('should bootstrap diagram with component', inject(function() {

}));

});

describe('selection box on related elements', function() {

var shape, shape2, connection, label, label2;

beforeEach(inject(function(elementFactory, canvas) {

// given
shape = elementFactory.createShape({
id: 'child',
x: 100, y: 100, width: 100, height: 100
});

canvas.addShape(shape);

shape2 = elementFactory.createShape({
id: 'child2',
x: 300, y: 100, width: 100, height: 100
});

canvas.addShape(shape2);

connection = elementFactory.createConnection({
id: 'connection',
waypoints: [ { x: 150, y: 150 }, { x: 150, y: 200 }, { x: 350, y: 150 } ],
source: shape,
target: shape2
});

canvas.addConnection(connection);

label = elementFactory.createLabel({
id: 'label',
x: 100, y: 200, width: 20, height: 20,
labelTarget: shape
});

canvas.addShape(label);

label2 = elementFactory.createLabel({
id: 'label2',
x: 200, y: 200, width: 20, height: 20,
labelTarget: connection
});

canvas.addShape(label2);
}));

describe('shapes', function() {


it('should show box on related label on select',
inject(function(selection, canvas) {

// when
selection.select(shape);

// then
var gfx = canvas.getGraphics(label),
hasOutline = matches(gfx, '.related-selected');

expect(hasOutline).to.be.true;
}));


it('should show box on shape on selecting label',
inject(function(selection, canvas) {

// when
selection.select(label);

// then
var gfx = canvas.getGraphics(shape),
hasOutline = matches(gfx, '.related-selected');

expect(hasOutline).to.be.true;
}));
});


describe('connection', function() {


it('should show box on related label on select',
inject(function(selection, canvas) {

// when
selection.select(connection);

// then
var gfx = canvas.getGraphics(label2),
hasOutline = matches(gfx, '.related-selected');

expect(hasOutline).to.be.true;
}));


it('should paler box on connection on selecting label',
inject(function(selection, canvas) {

// when
selection.select(label2);

// then
var gfx = canvas.getGraphics(connection),
hasOutline = matches(gfx, '.related-selected');

expect(hasOutline).to.be.true;
}));

});

});

});

0 comments on commit edc4b0b

Please sign in to comment.