bpmn-js/lib/util/LabelUtil.js

158 lines
3.3 KiB
JavaScript

import {
assign
} from 'min-dash';
import { is } from './ModelUtil';
export var DEFAULT_LABEL_SIZE = {
width: 90,
height: 20
};
export var FLOW_LABEL_INDENT = 15;
/**
* Returns true if the given semantic has an external label
*
* @param {BpmnElement} semantic
* @return {Boolean} true if has label
*/
export function isLabelExternal(semantic) {
return is(semantic, 'bpmn:Event') ||
is(semantic, 'bpmn:Gateway') ||
is(semantic, 'bpmn:DataStoreReference') ||
is(semantic, 'bpmn:DataObjectReference') ||
is(semantic, 'bpmn:DataInput') ||
is(semantic, 'bpmn:DataOutput') ||
is(semantic, 'bpmn:SequenceFlow') ||
is(semantic, 'bpmn:MessageFlow') ||
is(semantic, 'bpmn:Group');
}
/**
* Returns true if the given element has an external label
*
* @param {djs.model.shape} element
* @return {Boolean} true if has label
*/
export function hasExternalLabel(element) {
return isLabel(element.label);
}
/**
* Get the position for sequence flow labels
*
* @param {Array<Point>} waypoints
* @return {Point} the label position
*/
export 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 -= FLOW_LABEL_INDENT;
} else {
x += FLOW_LABEL_INDENT;
}
return { x: x, y: y };
}
/**
* Get the middle of a number of waypoints
*
* @param {Array<Point>} waypoints
* @return {Point} the mid point
*/
export function getWaypointsMid(waypoints) {
var mid = waypoints.length / 2 - 1;
var first = waypoints[Math.floor(mid)];
var second = waypoints[Math.ceil(mid + 0.01)];
return {
x: first.x + (second.x - first.x) / 2,
y: first.y + (second.y - first.y) / 2
};
}
export function getExternalLabelMid(element) {
if (element.waypoints) {
return getFlowLabelPosition(element.waypoints);
} else if (is(element, 'bpmn:Group')) {
return {
x: element.x + element.width / 2,
y: element.y + DEFAULT_LABEL_SIZE.height / 2
};
} else {
return {
x: element.x + element.width / 2,
y: element.y + element.height + DEFAULT_LABEL_SIZE.height / 2
};
}
}
/**
* Returns the bounds of an elements label, parsed from the elements DI or
* generated from its bounds.
*
* @param {BpmnElement} semantic
* @param {djs.model.Base} element
*/
export function getExternalLabelBounds(semantic, element) {
var mid,
size,
bounds,
di = semantic.di,
label = di.label;
if (label && label.bounds) {
bounds = label.bounds;
size = {
width: Math.max(DEFAULT_LABEL_SIZE.width, bounds.width),
height: bounds.height
};
mid = {
x: bounds.x + bounds.width / 2,
y: bounds.y + bounds.height / 2
};
} else {
mid = getExternalLabelMid(element);
size = DEFAULT_LABEL_SIZE;
}
return assign({
x: mid.x - size.width / 2,
y: mid.y - size.height / 2
}, size);
}
export function isLabel(element) {
return element && !!element.labelTarget;
}