UNPKG

5.17 kBJavaScriptView Raw
1import {
2 assign
3} from 'min-dash';
4
5import { is } from './ModelUtil';
6
7import { isLabel } from 'diagram-js/lib/util/ModelUtil';
8
9export { isLabel } from 'diagram-js/lib/util/ModelUtil';
10
11/**
12 * @typedef {import('diagram-js/lib/util/Types').Point} Point
13 * @typedef {import('diagram-js/lib/util/Types').Rect} Rect
14 *
15 * @typedef {import('../model/Types').Element} Element
16 * @typedef {import('../model/Types').ModdleElement} ModdleElement
17 */
18
19export var DEFAULT_LABEL_SIZE = {
20 width: 90,
21 height: 20
22};
23
24export var FLOW_LABEL_INDENT = 15;
25
26
27/**
28 * Return true if the given semantic has an external label.
29 *
30 * @param {Element} semantic
31 *
32 * @return {boolean}
33 */
34export function isLabelExternal(semantic) {
35 return is(semantic, 'bpmn:Event') ||
36 is(semantic, 'bpmn:Gateway') ||
37 is(semantic, 'bpmn:DataStoreReference') ||
38 is(semantic, 'bpmn:DataObjectReference') ||
39 is(semantic, 'bpmn:DataInput') ||
40 is(semantic, 'bpmn:DataOutput') ||
41 is(semantic, 'bpmn:SequenceFlow') ||
42 is(semantic, 'bpmn:MessageFlow') ||
43 is(semantic, 'bpmn:Group');
44}
45
46/**
47 * Return true if the given element has an external label.
48 *
49 * @param {Element} element
50 *
51 * @return {boolean}
52 */
53export function hasExternalLabel(element) {
54 return isLabel(element.label);
55}
56
57/**
58 * Get the position of a sequence flow label.
59 *
60 * @param {Point[]} waypoints
61 *
62 * @return {Point}
63 */
64export function getFlowLabelPosition(waypoints) {
65
66 // get the waypoints mid
67 var mid = waypoints.length / 2 - 1;
68
69 var first = waypoints[Math.floor(mid)];
70 var second = waypoints[Math.ceil(mid + 0.01)];
71
72 // get position
73 var position = getWaypointsMid(waypoints);
74
75 // calculate angle
76 var angle = Math.atan((second.y - first.y) / (second.x - first.x));
77
78 var x = position.x,
79 y = position.y;
80
81 if (Math.abs(angle) < Math.PI / 2) {
82 y -= FLOW_LABEL_INDENT;
83 } else {
84 x += FLOW_LABEL_INDENT;
85 }
86
87 return { x: x, y: y };
88}
89
90
91/**
92 * Get the middle of a number of waypoints.
93 *
94 * @param {Point[]} waypoints
95 *
96 * @return {Point}
97 */
98export function getWaypointsMid(waypoints) {
99
100 var mid = waypoints.length / 2 - 1;
101
102 var first = waypoints[Math.floor(mid)];
103 var second = waypoints[Math.ceil(mid + 0.01)];
104
105 return {
106 x: first.x + (second.x - first.x) / 2,
107 y: first.y + (second.y - first.y) / 2
108 };
109}
110
111/**
112 * Get the middle of the external label of an element.
113 *
114 * @param {Element} element
115 *
116 * @return {Point}
117 */
118export function getExternalLabelMid(element) {
119
120 if (element.waypoints) {
121 return getFlowLabelPosition(element.waypoints);
122 } else if (is(element, 'bpmn:Group')) {
123 return {
124 x: element.x + element.width / 2,
125 y: element.y + DEFAULT_LABEL_SIZE.height / 2
126 };
127 } else {
128 return {
129 x: element.x + element.width / 2,
130 y: element.y + element.height + DEFAULT_LABEL_SIZE.height / 2
131 };
132 }
133}
134
135
136/**
137 * Return the bounds of an elements label, parsed from the elements DI or
138 * generated from its bounds.
139 *
140 * @param {ModdleElement} di
141 * @param {Element} element
142 *
143 * @return {Rect}
144 */
145export function getExternalLabelBounds(di, element) {
146
147 var mid,
148 size,
149 bounds,
150 label = di.label;
151
152 if (label && label.bounds) {
153 bounds = label.bounds;
154
155 size = {
156 width: Math.max(DEFAULT_LABEL_SIZE.width, bounds.width),
157 height: bounds.height
158 };
159
160 mid = {
161 x: bounds.x + bounds.width / 2,
162 y: bounds.y + bounds.height / 2
163 };
164 } else {
165
166 mid = getExternalLabelMid(element);
167
168 size = DEFAULT_LABEL_SIZE;
169 }
170
171 return assign({
172 x: mid.x - size.width / 2,
173 y: mid.y - size.height / 2
174 }, size);
175}
176
177/**
178 * @param {ModdleElement} semantic
179 *
180 * @returns {string}
181 */
182function getLabelAttr(semantic) {
183 if (
184 is(semantic, 'bpmn:FlowElement') ||
185 is(semantic, 'bpmn:Participant') ||
186 is(semantic, 'bpmn:Lane') ||
187 is(semantic, 'bpmn:SequenceFlow') ||
188 is(semantic, 'bpmn:MessageFlow') ||
189 is(semantic, 'bpmn:DataInput') ||
190 is(semantic, 'bpmn:DataOutput')
191 ) {
192 return 'name';
193 }
194
195 if (is(semantic, 'bpmn:TextAnnotation')) {
196 return 'text';
197 }
198
199 if (is(semantic, 'bpmn:Group')) {
200 return 'categoryValueRef';
201 }
202}
203
204/**
205 * @param {ModdleElement} semantic
206 *
207 * @returns {string}
208 */
209function getCategoryValue(semantic) {
210 var categoryValueRef = semantic['categoryValueRef'];
211
212 if (!categoryValueRef) {
213 return '';
214 }
215
216
217 return categoryValueRef.value || '';
218}
219
220/**
221 * @param {Element} element
222 *
223 * @return {string}
224 */
225export function getLabel(element) {
226 var semantic = element.businessObject,
227 attr = getLabelAttr(semantic);
228
229 if (attr) {
230
231 if (attr === 'categoryValueRef') {
232
233 return getCategoryValue(semantic);
234 }
235
236 return semantic[attr] || '';
237 }
238}
239
240
241/**
242 * @param {Element} element
243 * @param {string} text
244 *
245 * @return {Element}
246 */
247export function setLabel(element, text) {
248 var semantic = element.businessObject,
249 attr = getLabelAttr(semantic);
250
251 if (attr) {
252
253 if (attr === 'categoryValueRef') {
254 semantic['categoryValueRef'].value = text;
255 } else {
256 semantic[attr] = text;
257 }
258
259 }
260
261 return element;
262}