From 7811a47faea523e54a403a541025d637295e692f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20St=C3=BCmmel?= Date: Tue, 19 Apr 2016 16:50:42 +0200 Subject: [PATCH] feat(label): improve positioning of sequence flow labels closes #512 --- lib/util/LabelUtil.js | 35 ++++++++++++++++++++++- test/spec/util/LabelUtil.bpmn | 37 ++++++++++++++++++++++++ test/spec/util/LabelUtilSpec.js | 50 +++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 test/spec/util/LabelUtil.bpmn create mode 100644 test/spec/util/LabelUtilSpec.js diff --git a/lib/util/LabelUtil.js b/lib/util/LabelUtil.js index 8f32112b..f4927609 100644 --- a/lib/util/LabelUtil.js +++ b/lib/util/LabelUtil.js @@ -25,6 +25,39 @@ module.exports.hasExternalLabel = function(semantic) { is(semantic, 'bpmn:MessageFlow'); }; +/** + * Get the position for sequence flow labels + * + * @param {Array} waypoints + * @return {Point} the label position + */ +function getFlowLabelPosition(waypoints) { + + // get the waypoints mid + var mid = waypoints.length / 2 - 1; + + var first = waypoints[Math.floor(mid)]; + var second = waypoints[Math.ceil(mid + 0.01)]; + + // get position + var position = getWaypointsMid(waypoints); + + // calculate angle + var angle = Math.atan( (second.y - first.y) / (second.x - first.x) ); + + var x = position.x, + y = position.y; + + if ( Math.abs(angle) < Math.PI / 2 ) { + y += DEFAULT_LABEL_SIZE.height / 2; + } else { + x += DEFAULT_LABEL_SIZE.width / 2; + } + + return { x: x, y: y }; +} + +module.exports.getFlowLabelPosition = getFlowLabelPosition; /** * Get the middle of a number of waypoints @@ -51,7 +84,7 @@ module.exports.getWaypointsMid = getWaypointsMid; function getExternalLabelMid(element) { if (element.waypoints) { - return getWaypointsMid(element.waypoints); + return getFlowLabelPosition(element.waypoints); } else { return { x: element.x + element.width / 2, diff --git a/test/spec/util/LabelUtil.bpmn b/test/spec/util/LabelUtil.bpmn new file mode 100644 index 00000000..7a41bdd3 --- /dev/null +++ b/test/spec/util/LabelUtil.bpmn @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/spec/util/LabelUtilSpec.js b/test/spec/util/LabelUtilSpec.js new file mode 100644 index 00000000..7832fb69 --- /dev/null +++ b/test/spec/util/LabelUtilSpec.js @@ -0,0 +1,50 @@ +'use strict'; + +require('../../TestHelper'); + +/* global bootstrapModeler, inject */ + +var coreModule = require('../../../lib/core'), + modelingModule = require('../../../lib/features/modeling'); + +var ModelUtil = require('../../../lib/util/ModelUtil'), + LabelUtil = require('../../../lib/util/LabelUtil'); + + +describe('LabelUtil', function() { + + var diagramXML = require('./LabelUtil.bpmn'); + + beforeEach(bootstrapModeler(diagramXML, { modules: [ coreModule, modelingModule ] })); + + + it('should correctly place horizontal label', inject(function(modeling, elementRegistry) { + + // given + var element1 = elementRegistry.get('StartEvent_1'), + element2 = elementRegistry.get('ExclusiveGateway_2'); + + // when + var connection = modeling.connect(element1, element2); + + // then + expect(connection.label.x).to.be.equal(427); + expect(connection.label.y).to.be.equal(357); + })); + + + it('should correctly place vertical label', inject(function(modeling, elementRegistry) { + + // given + var element1 = elementRegistry.get('StartEvent_1'), + element2 = elementRegistry.get('ExclusiveGateway_1'); + + // when + var connection = modeling.connect(element1, element2); + + // then + expect(connection.label.x).to.be.equal(322); + expect(connection.label.y).to.be.equal(219.5); + })); + +});