-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathcustom-overlay.ts
More file actions
107 lines (89 loc) · 3.38 KB
/
custom-overlay.ts
File metadata and controls
107 lines (89 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
Copyright 2021 Bonitasoft S.A.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import type { OverlayStyle } from '../../registry';
import type { mxCellState, mxPoint as mxPointType, mxRectangle as mxRectangleType } from 'mxgraph';
import { mxCellOverlay, mxConstants, mxPoint, mxRectangle } from '../initializer';
export type VerticalAlignType = 'bottom' | 'middle' | 'top';
export type HorizontalAlignType = 'left' | 'center' | 'right';
export interface CustomCellOverlayOptions {
position: CustomCellOverlayPosition;
style: CustomCellOverlayStyle;
}
export interface CustomCellOverlayPosition {
horizontalAlign?: HorizontalAlignType;
verticalAlign?: VerticalAlignType;
}
export type CustomCellOverlayStyle = Required<OverlayStyle>;
export class CustomCellOverlay extends mxCellOverlay {
readonly style: CustomCellOverlayStyle;
constructor(
public label: string,
options: CustomCellOverlayOptions,
) {
super(null, '', options.position.horizontalAlign, options.position.verticalAlign, null, 'default');
this.style = options.style;
}
// Based on original method from mxCellOverlay (mxCellOverlay.prototype.getBounds)
override getBounds(state: mxCellState): mxRectangleType {
const isEdge = state.view.graph.getModel().isEdge(state.cell);
const s = state.view.scale;
let pt;
// START bpmn-visualization CUSTOMIZATION
// 0 values to position the text overlays on extreme/center points
const w = 0;
const h = 0;
// END bpmn-visualization CUSTOMIZATION
if (isEdge) {
pt = this.computeEdgeBounds(state);
} else {
pt = new mxPoint();
if (this.align == mxConstants.ALIGN_LEFT) {
pt.x = state.x;
} else if (this.align == mxConstants.ALIGN_CENTER) {
pt.x = state.x + state.width / 2;
} else {
pt.x = state.x + state.width;
}
if (this.verticalAlign == mxConstants.ALIGN_TOP) {
pt.y = state.y;
} else if (this.verticalAlign == mxConstants.ALIGN_MIDDLE) {
pt.y = state.y + state.height / 2;
} else {
pt.y = state.y + state.height;
}
}
return new mxRectangle(Math.round(pt.x - (w * this.defaultOverlap - this.offset.x) * s), Math.round(pt.y - (h * this.defaultOverlap - this.offset.y) * s), w * s, h * s);
}
private computeEdgeBounds(state: mxCellState): mxPointType {
const pts = state.absolutePoints;
// 1st point for start position
if (this.align == mxConstants.ALIGN_LEFT) {
return pts[0];
}
// middle point for middle position
else if (this.align == mxConstants.ALIGN_CENTER) {
if (pts.length % 2 == 1) {
return pts[Math.floor(pts.length / 2)];
} else {
const index = pts.length / 2;
const p0 = pts[index - 1];
const p1 = pts[index];
return new mxPoint(p0.x + (p1.x - p0.x) / 2, p0.y + (p1.y - p0.y) / 2);
}
}
// last point for end position
else {
return pts.at(-1);
}
}
}