UNPKG

bpmn-js

Version:

A bpmn 2.0 toolkit and web modeler

268 lines (217 loc) 5.2 kB
import { assign } from 'min-dash'; import { is } from './ModelUtil'; /** * @typedef {import('diagram-js/lib/util/Types').Point} Point * @typedef {import('diagram-js/lib/util/Types').Rect} Rect * * @typedef {import('../model/Types').Element} Element * @typedef {import('../model/Types').ModdleElement} ModdleElement */ export var DEFAULT_LABEL_SIZE = { width: 90, height: 20 }; export var FLOW_LABEL_INDENT = 15; /** * Return true if the given semantic has an external label. * * @param {Element} semantic * * @return {boolean} */ 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'); } /** * Return true if the given element has an external label. * * @param {Element} element * * @return {boolean} */ export function hasExternalLabel(element) { return isLabel(element.label); } /** * Get the position of a sequence flow label. * * @param {Point[]} waypoints * * @return {Point} */ 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 {Point[]} waypoints * * @return {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 }; } /** * Get the middle of the external label of an element. * * @param {Element} element * * @return {Point} */ 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 }; } } /** * Return the bounds of an elements label, parsed from the elements DI or * generated from its bounds. * * @param {ModdleElement} di * @param {Element} element * * @return {Rect} */ export function getExternalLabelBounds(di, element) { var mid, size, bounds, 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); } /** * @param {Element} element * * @return {boolean} */ export function isLabel(element) { return element && !!element.labelTarget; } /** * @param {ModdleElement} semantic * * @returns {string} */ function getLabelAttr(semantic) { if ( is(semantic, 'bpmn:FlowElement') || is(semantic, 'bpmn:Participant') || is(semantic, 'bpmn:Lane') || is(semantic, 'bpmn:SequenceFlow') || is(semantic, 'bpmn:MessageFlow') || is(semantic, 'bpmn:DataInput') || is(semantic, 'bpmn:DataOutput') ) { return 'name'; } if (is(semantic, 'bpmn:TextAnnotation')) { return 'text'; } if (is(semantic, 'bpmn:Group')) { return 'categoryValueRef'; } } /** * @param {ModdleElement} semantic * * @returns {string} */ function getCategoryValue(semantic) { var categoryValueRef = semantic['categoryValueRef']; if (!categoryValueRef) { return ''; } return categoryValueRef.value || ''; } /** * @param {Element} element * * @return {string} */ export function getLabel(element) { var semantic = element.businessObject, attr = getLabelAttr(semantic); if (attr) { if (attr === 'categoryValueRef') { return getCategoryValue(semantic); } return semantic[attr] || ''; } } /** * @param {Element} element * @param {string} text * * @return {Element} */ export function setLabel(element, text) { var semantic = element.businessObject, attr = getLabelAttr(semantic); if (attr) { if (attr === 'categoryValueRef') { semantic['categoryValueRef'].value = text; } else { semantic[attr] = text; } } return element; }