@fmsim/machine 1.0.17 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/carrier.js +168 -0
- package/dist/carrier.js.map +1 -0
- package/dist/features/animation-default.js +20 -0
- package/dist/features/animation-default.js.map +1 -0
- package/dist/features/mcs-status-default.js +3 -3
- package/dist/features/mcs-status-default.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcs-carrier-holder.js +20 -111
- package/dist/mcs-carrier-holder.js.map +1 -1
- package/dist/mcs-unit.js +2 -2
- package/dist/mcs-unit.js.map +1 -1
- package/dist/port-flow.js +22 -17
- package/dist/port-flow.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/carrier.ts +213 -0
- package/src/features/animation-default.ts +27 -0
- package/src/features/mcs-status-default.ts +3 -3
- package/src/index.ts +1 -0
- package/src/mcs-carrier-holder.ts +25 -153
- package/src/mcs-unit.ts +2 -2
- package/src/port-flow.ts +23 -17
- package/translations/en.json +1 -0
- package/translations/ja.json +1 -0
- package/translations/ko.json +2 -1
- package/translations/ms.json +1 -0
- package/translations/zh.json +1 -0
package/src/carrier.ts
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import JSON5 from 'json5'
|
|
2
|
+
|
|
3
|
+
import { BOUNDS, Component, ComponentNature, RectPath, Shape } from '@hatiolab/things-scene'
|
|
4
|
+
import { ANIMATION_DEFAULT, AnimationPreset, AnimationConfig } from './features/animation-default.js'
|
|
5
|
+
import { LEGEND_CARRIER, Legend } from './features/mcs-status-default.js'
|
|
6
|
+
import { MCSStatusMixin } from './features/mcs-status-mixin.js'
|
|
7
|
+
|
|
8
|
+
const NATURE: ComponentNature = {
|
|
9
|
+
mutable: false,
|
|
10
|
+
resizable: false,
|
|
11
|
+
rotatable: false
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default class Carrier extends MCSStatusMixin(Shape) {
|
|
15
|
+
static get nature() {
|
|
16
|
+
return NATURE
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
id?: string
|
|
20
|
+
emptyType?: 'FULL' | 'EMPTY' | 'EMPTYEMPTY'
|
|
21
|
+
carrierStatus?: string
|
|
22
|
+
|
|
23
|
+
get path() {
|
|
24
|
+
const { left, top, width, height } = this.calculateShrunkRectangle(this.parent.bounds)
|
|
25
|
+
|
|
26
|
+
return [
|
|
27
|
+
{ x: left, y: top },
|
|
28
|
+
{ x: left + width / 2, y: top },
|
|
29
|
+
{ x: left + width, y: top + height / 2 },
|
|
30
|
+
{ x: left + width, y: top + height },
|
|
31
|
+
{ x: left, y: top + height }
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
set path(path) {}
|
|
36
|
+
|
|
37
|
+
onchangeData(after, before) {
|
|
38
|
+
const { CARRIERNAME, CARRIERTYPE = '', EMPTYTYPE, CARRIERSTATUS } = this.data || {}
|
|
39
|
+
|
|
40
|
+
this.setState('id', CARRIERNAME)
|
|
41
|
+
|
|
42
|
+
this.emptyType = EMPTYTYPE
|
|
43
|
+
this.carrierStatus = CARRIERSTATUS
|
|
44
|
+
|
|
45
|
+
// TODO carrierstatus에 따라서 매핑되는 애니메이션 테마 수행
|
|
46
|
+
if (after.data.CARRIERSTATUS !== before.data?.CARRIERSTATUS) {
|
|
47
|
+
const { CARRIERSTATUS: lastCarrierStatus } = before.data || {}
|
|
48
|
+
const lastAnimationConfig = lastCarrierStatus && this.getAnimationConfig(lastCarrierStatus)
|
|
49
|
+
|
|
50
|
+
if (lastAnimationConfig) {
|
|
51
|
+
let { animation, decorator, border, arrow } = lastAnimationConfig
|
|
52
|
+
if (animation) {
|
|
53
|
+
;(this as any).started = false
|
|
54
|
+
;(this as any)._animation = null
|
|
55
|
+
this.setState('animation', {
|
|
56
|
+
oncreate: null
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (decorator) {
|
|
61
|
+
this.trigger('iconoff')
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (border) {
|
|
65
|
+
this.trigger('borderoff')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (arrow) {
|
|
69
|
+
this.trigger('bouncingoff')
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const animationConfig = this.getAnimationConfig(this.carrierStatus)
|
|
74
|
+
|
|
75
|
+
if (animationConfig) {
|
|
76
|
+
let { animation, decorator, border, arrow } = animationConfig
|
|
77
|
+
if (animation) {
|
|
78
|
+
;(this as any).started = false
|
|
79
|
+
;(this as any)._animation = null
|
|
80
|
+
this.setState('animation', {
|
|
81
|
+
oncreate: animation
|
|
82
|
+
})
|
|
83
|
+
;(this as any).started = true
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (decorator) {
|
|
87
|
+
this.trigger('iconoff')
|
|
88
|
+
this.trigger('icon', decorator)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (border) {
|
|
92
|
+
this.trigger('borderoff')
|
|
93
|
+
this.trigger('border', border)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (arrow) {
|
|
97
|
+
this.trigger('bouncingoff')
|
|
98
|
+
this.trigger('bouncing', arrow)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
get status() {
|
|
105
|
+
return this.emptyType
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
get legend(): Legend {
|
|
109
|
+
const { carrierLegendName } = this.parent?.state || {}
|
|
110
|
+
|
|
111
|
+
if (carrierLegendName) {
|
|
112
|
+
return (this.root as any)?.style[carrierLegendName]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return LEGEND_CARRIER
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
getAnimationConfig(carrierStatus): AnimationConfig | null {
|
|
119
|
+
const config = this.animationPreset[carrierStatus || 'default']
|
|
120
|
+
|
|
121
|
+
if (config && typeof config == 'string') {
|
|
122
|
+
try {
|
|
123
|
+
return JSON5.parse(config)
|
|
124
|
+
} catch (e) {
|
|
125
|
+
console.error(e)
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
return (config as AnimationConfig) || null
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return null
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
get animationPreset(): AnimationPreset {
|
|
135
|
+
const { carrierAnimationName } = this.parent?.state || {}
|
|
136
|
+
|
|
137
|
+
if (carrierAnimationName) {
|
|
138
|
+
return (this.parent.root as any)?.style[carrierAnimationName] || ANIMATION_DEFAULT
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return ANIMATION_DEFAULT
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
calculateShrunkRectangle(originalRect: BOUNDS): BOUNDS {
|
|
145
|
+
const shrunkRect: BOUNDS = { ...originalRect }
|
|
146
|
+
|
|
147
|
+
shrunkRect.left = originalRect.width * 0.1
|
|
148
|
+
shrunkRect.width *= 0.8
|
|
149
|
+
|
|
150
|
+
shrunkRect.top = originalRect.height * 0.1
|
|
151
|
+
shrunkRect.height *= 0.8
|
|
152
|
+
|
|
153
|
+
return shrunkRect
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
contains(x, y) {
|
|
157
|
+
if (!this.emptyType) {
|
|
158
|
+
return false
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const rect = this.bounds
|
|
162
|
+
x -= rect.left
|
|
163
|
+
y -= rect.top
|
|
164
|
+
|
|
165
|
+
if (x < 0 || y < 0 || x > rect.width || y > rect.height) {
|
|
166
|
+
return false
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 윗변 중앙 좌표
|
|
170
|
+
const topCenterX = rect.width / 2
|
|
171
|
+
const topCenterY = 0
|
|
172
|
+
|
|
173
|
+
// 오른쪽 변 중앙 좌표
|
|
174
|
+
const rightCenterX = rect.width
|
|
175
|
+
const rightCenterY = rect.height / 2
|
|
176
|
+
|
|
177
|
+
// 기울기 m = (y2 - y1) / (x2 - x1)
|
|
178
|
+
const m = (rightCenterY - topCenterY) / (rightCenterX - topCenterX)
|
|
179
|
+
|
|
180
|
+
// y 절편 b = y - mx
|
|
181
|
+
const b = topCenterY - m * topCenterX
|
|
182
|
+
|
|
183
|
+
// 점(px, py)이 선 아래(좌하부)에 있는지 확인
|
|
184
|
+
return y > m * x + b
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
render(ctx: CanvasRenderingContext2D) {
|
|
188
|
+
if (!this.emptyType) {
|
|
189
|
+
return
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const { width, height } = this.bounds
|
|
193
|
+
const path = this.path
|
|
194
|
+
|
|
195
|
+
ctx.beginPath()
|
|
196
|
+
ctx.moveTo(path[0].x, path[0].y)
|
|
197
|
+
|
|
198
|
+
path.slice(1).forEach(({ x, y }) => {
|
|
199
|
+
ctx.lineTo(x, y)
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
ctx.closePath()
|
|
203
|
+
|
|
204
|
+
ctx.lineWidth = Math.round(Math.min(width, height) * 0.1) > 5 ? 1 : 0.5
|
|
205
|
+
ctx.fillStyle = this.statusColor || 'transparent'
|
|
206
|
+
ctx.strokeStyle = this.auxColor || 'transparent'
|
|
207
|
+
|
|
208
|
+
ctx.fill()
|
|
209
|
+
ctx.stroke()
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
Component.register('Carrier', Carrier)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type AnimationConfig = {
|
|
2
|
+
[key: string]: any
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface AnimationPreset {
|
|
6
|
+
[state: string]: AnimationConfig | string | null
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const ANIMATION_DEFAULT: AnimationPreset = {
|
|
10
|
+
WARN: {
|
|
11
|
+
animation: {
|
|
12
|
+
type: 'vibration',
|
|
13
|
+
duration: 1000,
|
|
14
|
+
theta: 0.3,
|
|
15
|
+
repeat: true
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
CRITICAL: {
|
|
19
|
+
animation: {
|
|
20
|
+
type: 'vibration',
|
|
21
|
+
duration: 500,
|
|
22
|
+
theta: 0.5,
|
|
23
|
+
repeat: true
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
default: null
|
|
27
|
+
}
|
|
@@ -55,9 +55,9 @@ export const LEGEND_CRANE: Legend = {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export const LEGEND_CARRIER: Legend = {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
FULL: '#4AA7FE',
|
|
59
|
+
EMPTY: '#8BDA5B',
|
|
60
|
+
EMPTYEMPTY: '#019D59',
|
|
61
61
|
default: '#F0F0F0'
|
|
62
62
|
}
|
|
63
63
|
|
package/src/index.ts
CHANGED
|
@@ -1,136 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { themesColorMap } from '@fmsim/api'
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import MCSUnit from './mcs-unit'
|
|
6
|
-
|
|
7
|
-
export class Carrier extends MCSStatusMixin(Object) {
|
|
8
|
-
host: Component
|
|
9
|
-
|
|
10
|
-
id?: string
|
|
11
|
-
type: ('ALL' | 'BOBIN' | 'MAGAZINE' | 'PALLET' | 'REEL_TRAY' | 'PLATE')[] = []
|
|
12
|
-
// emptyType?: '5000' | '5001' | '5002' // 'Full' | 'Empty' | 'EmptyEmpty'
|
|
13
|
-
emptyType?: 'Full' | 'Empty' | 'EmptyEmpty'
|
|
14
|
-
|
|
15
|
-
constructor(host: Component) {
|
|
16
|
-
super()
|
|
17
|
-
this.host = host
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
set data(data: any) {
|
|
21
|
-
const { CARRIERID, CARRIERTYPE = '', EMPTYTYPE } = data || {}
|
|
22
|
-
|
|
23
|
-
this.id = CARRIERID
|
|
24
|
-
this.type = CARRIERTYPE.split(';')
|
|
25
|
-
this.emptyType = EMPTYTYPE
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get status() {
|
|
29
|
-
return this.emptyType
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
get legend(): Legend {
|
|
33
|
-
const { carrierLegendName } = this.host.state
|
|
34
|
-
|
|
35
|
-
if (carrierLegendName) {
|
|
36
|
-
return (this.host.root as any)?.style[carrierLegendName]
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return LEGEND_CARRIER
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
calculateShrunkRectangle(originalRect: BOUNDS): BOUNDS {
|
|
43
|
-
const shrunkRect: BOUNDS = { ...originalRect }
|
|
44
|
-
|
|
45
|
-
shrunkRect.left += originalRect.width * 0.1
|
|
46
|
-
shrunkRect.width *= 0.8
|
|
47
|
-
|
|
48
|
-
shrunkRect.top += originalRect.height * 0.1
|
|
49
|
-
shrunkRect.height *= 0.8
|
|
50
|
-
|
|
51
|
-
return shrunkRect
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
isPointOnCarrier(x, y, { left, top, width, height }) {
|
|
55
|
-
const rect = this.calculateShrunkRectangle({ left, top, width, height })
|
|
56
|
-
x -= rect.left
|
|
57
|
-
y -= rect.top
|
|
58
|
-
|
|
59
|
-
if (x < 0 || y < 0 || x > rect.width || y > rect.height) {
|
|
60
|
-
return false
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// 윗변 중앙 좌표
|
|
64
|
-
const topCenterX = rect.width / 2
|
|
65
|
-
const topCenterY = 0
|
|
66
|
-
|
|
67
|
-
// 오른쪽 변 중앙 좌표
|
|
68
|
-
const rightCenterX = rect.width
|
|
69
|
-
const rightCenterY = rect.height / 2
|
|
70
|
-
|
|
71
|
-
// 기울기 m = (y2 - y1) / (x2 - x1)
|
|
72
|
-
const m = (rightCenterY - topCenterY) / (rightCenterX - topCenterX)
|
|
73
|
-
|
|
74
|
-
// y 절편 b = y - mx
|
|
75
|
-
const b = topCenterY - m * topCenterX
|
|
76
|
-
|
|
77
|
-
// 점(px, py)이 선 아래(좌하부)에 있는지 확인
|
|
78
|
-
return y > m * x + b
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
render(ctx: CanvasRenderingContext2D) {
|
|
82
|
-
if (!this.emptyType) {
|
|
83
|
-
return
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const { left, top, width, height } = this.calculateShrunkRectangle(this.host.bounds)
|
|
87
|
-
|
|
88
|
-
const radius = Math.round(Math.min(width, height) * 0.1)
|
|
89
|
-
|
|
90
|
-
// 시작점 설정
|
|
91
|
-
ctx.beginPath()
|
|
92
|
-
ctx.moveTo(left + radius, top)
|
|
93
|
-
|
|
94
|
-
// 상단 가로선 그리기
|
|
95
|
-
ctx.lineTo(left + width / 2, top)
|
|
96
|
-
|
|
97
|
-
// 우측 세로선 그리기
|
|
98
|
-
ctx.lineTo(left + width, top + height / 2)
|
|
99
|
-
ctx.lineTo(left + width, top + height)
|
|
100
|
-
|
|
101
|
-
// 하단 가로선 그리기
|
|
102
|
-
ctx.lineTo(left, top + height)
|
|
103
|
-
|
|
104
|
-
// 좌측 세로선 그리기
|
|
105
|
-
ctx.lineTo(left, top)
|
|
106
|
-
|
|
107
|
-
// 경로 닫기 및 그리기
|
|
108
|
-
ctx.closePath()
|
|
109
|
-
|
|
110
|
-
ctx.lineWidth = radius > 5 ? 1 : 0.5
|
|
111
|
-
ctx.fillStyle = this.statusColor || 'transparent'
|
|
112
|
-
ctx.strokeStyle = this.auxColor || 'transparent'
|
|
113
|
-
|
|
114
|
-
ctx.fill()
|
|
115
|
-
ctx.stroke()
|
|
116
|
-
|
|
117
|
-
ctx.beginPath()
|
|
118
|
-
|
|
119
|
-
const text =
|
|
120
|
-
this.emptyType == 'Full' ? 'F' : this.emptyType == 'Empty' ? 'E' : this.emptyType == 'EmptyEmpty' ? 'X' : ''
|
|
121
|
-
|
|
122
|
-
if (text) {
|
|
123
|
-
const { x: cx, y: cy } = this.host.center
|
|
124
|
-
|
|
125
|
-
ctx.fillStyle = 'black'
|
|
126
|
-
ctx.font = `normal ${Math.round(radius * 8)}px Arial`
|
|
127
|
-
ctx.textAlign = 'center'
|
|
128
|
-
ctx.textBaseline = 'middle'
|
|
129
|
-
|
|
130
|
-
ctx.fillText(text, cx - width / 8, cy + height / 8)
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
1
|
+
import { Model } from '@hatiolab/things-scene'
|
|
2
|
+
import { themesColorMap, themesAnimationMap } from '@fmsim/api'
|
|
3
|
+
import MCSUnit from './mcs-unit.js'
|
|
4
|
+
import Carrier from './carrier.js'
|
|
134
5
|
|
|
135
6
|
export default class MCSCarrierHolder extends MCSUnit {
|
|
136
7
|
static get properties(): any {
|
|
@@ -143,40 +14,41 @@ export default class MCSCarrierHolder extends MCSUnit {
|
|
|
143
14
|
property: {
|
|
144
15
|
options: themesColorMap
|
|
145
16
|
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: 'select',
|
|
20
|
+
label: 'carrier-animation-name',
|
|
21
|
+
name: 'carrierAnimationName',
|
|
22
|
+
property: {
|
|
23
|
+
options: themesAnimationMap
|
|
24
|
+
}
|
|
146
25
|
}
|
|
147
26
|
]
|
|
148
27
|
}
|
|
149
28
|
|
|
150
|
-
carrier
|
|
29
|
+
carrier?: Carrier | null
|
|
151
30
|
|
|
152
31
|
ready() {
|
|
153
|
-
|
|
154
|
-
}
|
|
32
|
+
super.ready()
|
|
155
33
|
|
|
156
|
-
|
|
157
|
-
this.carrier.render(ctx)
|
|
34
|
+
this.carrier = Model.compile({ type: 'Carrier' }, this.root.app) as any
|
|
158
35
|
|
|
159
|
-
|
|
36
|
+
this.carrier!.data = this.data
|
|
37
|
+
|
|
38
|
+
this.addComponent(this.carrier!)
|
|
160
39
|
}
|
|
161
40
|
|
|
162
|
-
|
|
163
|
-
this.carrier
|
|
41
|
+
dispose(): void {
|
|
42
|
+
this.carrier = null
|
|
164
43
|
|
|
165
|
-
super.
|
|
44
|
+
super.dispose()
|
|
166
45
|
}
|
|
167
46
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
return false
|
|
47
|
+
onchangeData(after: any, before: any) {
|
|
48
|
+
if (this.carrier) {
|
|
49
|
+
this.carrier.data = this.data
|
|
172
50
|
}
|
|
173
51
|
|
|
174
|
-
|
|
175
|
-
const { left, top, width, height } = this.bounds
|
|
176
|
-
|
|
177
|
-
point.x -= left
|
|
178
|
-
point.y -= top
|
|
179
|
-
|
|
180
|
-
return this.carrier.isPointOnCarrier(point.x, point.y, { left: 0, top: 0, width, height })
|
|
52
|
+
super.onchangeData(after, before)
|
|
181
53
|
}
|
|
182
54
|
}
|
package/src/mcs-unit.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component } from '@hatiolab/things-scene'
|
|
1
|
+
import { Component, ContainerAbstract } from '@hatiolab/things-scene'
|
|
2
2
|
import { getPopupData } from '@fmsim/api'
|
|
3
3
|
|
|
4
4
|
import { MCSStatusMixin, MCSStatusMixinProperties } from './features/mcs-status-mixin'
|
|
@@ -8,7 +8,7 @@ import { ParentObjectMixin, ParentObjectMixinProperties } from './features/paren
|
|
|
8
8
|
/**
|
|
9
9
|
* MCS용 Unit들의 공통 속성을 정의한 오브젝트
|
|
10
10
|
*/
|
|
11
|
-
export default class MCSUnit extends MCSStatusMixin(ParentObjectMixin(
|
|
11
|
+
export default class MCSUnit extends MCSStatusMixin(ParentObjectMixin(ContainerAbstract)) {
|
|
12
12
|
static get properties(): any {
|
|
13
13
|
return [...MCSStatusMixinProperties, ...ParentObjectMixinProperties]
|
|
14
14
|
}
|
package/src/port-flow.ts
CHANGED
|
@@ -12,7 +12,7 @@ const NATURE: ComponentNature = {
|
|
|
12
12
|
name: 'orientation',
|
|
13
13
|
label: 'orientation',
|
|
14
14
|
property: {
|
|
15
|
-
options: ['left
|
|
15
|
+
options: ['left to right', 'right to left', 'top to bottom', 'bottom to top']
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
{
|
|
@@ -28,7 +28,7 @@ const NATURE: ComponentNature = {
|
|
|
28
28
|
name: 'direction',
|
|
29
29
|
label: 'direction',
|
|
30
30
|
property: {
|
|
31
|
-
options: ['
|
|
31
|
+
options: ['IN', 'OUT', 'BOTH']
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
]
|
|
@@ -78,19 +78,25 @@ export default class PortFlow extends ParentObjectMixin(RectPath(Shape)) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
get text() {
|
|
81
|
-
const { direction = '
|
|
81
|
+
const { direction = 'IN' } = this.state
|
|
82
82
|
|
|
83
83
|
return direction.toUpperCase()
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
render(ctx) {
|
|
87
87
|
const { left, top, width, height } = this.bounds
|
|
88
|
-
|
|
88
|
+
var { orientation = 'left to right', direction = 'BOTH' }: { orientation?: string; direction?: string } = this.state
|
|
89
|
+
const { INOUTTYPE } = this.data || {}
|
|
90
|
+
|
|
91
|
+
if (INOUTTYPE) {
|
|
92
|
+
// TODO bothtype value 조정하기.
|
|
93
|
+
direction = INOUTTYPE /* IN | OUT | BOTH */
|
|
94
|
+
}
|
|
89
95
|
|
|
90
96
|
ctx.beginPath()
|
|
91
97
|
|
|
92
98
|
const arrowSize = Math.min(width, height) * 0.3
|
|
93
|
-
const bodyWidth = orientation === 'left
|
|
99
|
+
const bodyWidth = orientation === 'left to right' || orientation === 'right to left' ? height * 0.2 : width * 0.2
|
|
94
100
|
const centerX = left + width / 2
|
|
95
101
|
const centerY = top + height / 2
|
|
96
102
|
|
|
@@ -98,26 +104,26 @@ export default class PortFlow extends ParentObjectMixin(RectPath(Shape)) {
|
|
|
98
104
|
let reverse = 1
|
|
99
105
|
|
|
100
106
|
switch (orientation) {
|
|
101
|
-
case 'left
|
|
107
|
+
case 'left to right':
|
|
102
108
|
startX = left
|
|
103
109
|
endX = left + width
|
|
104
110
|
startY = centerY
|
|
105
111
|
endY = centerY
|
|
106
112
|
break
|
|
107
|
-
case 'right
|
|
113
|
+
case 'right to left':
|
|
108
114
|
startX = left + width
|
|
109
115
|
endX = left
|
|
110
116
|
startY = centerY
|
|
111
117
|
endY = centerY
|
|
112
118
|
reverse = -1
|
|
113
119
|
break
|
|
114
|
-
case 'top
|
|
120
|
+
case 'top to bottom':
|
|
115
121
|
startX = centerX
|
|
116
122
|
endX = centerX
|
|
117
123
|
startY = top
|
|
118
124
|
endY = top + height
|
|
119
125
|
break
|
|
120
|
-
case 'bottom
|
|
126
|
+
case 'bottom to top':
|
|
121
127
|
startX = centerX
|
|
122
128
|
endX = centerX
|
|
123
129
|
startY = top + height
|
|
@@ -129,7 +135,7 @@ export default class PortFlow extends ParentObjectMixin(RectPath(Shape)) {
|
|
|
129
135
|
ctx.lineTo(startX, startY)
|
|
130
136
|
|
|
131
137
|
if (orientation.includes('left')) {
|
|
132
|
-
if (direction === '
|
|
138
|
+
if (direction === 'OUT' || direction === 'BOTH') {
|
|
133
139
|
ctx.lineTo(startX + arrowSize * reverse, startY - bodyWidth * reverse * 2)
|
|
134
140
|
} else {
|
|
135
141
|
ctx.lineTo(startX, startY - bodyWidth * reverse)
|
|
@@ -138,7 +144,7 @@ export default class PortFlow extends ParentObjectMixin(RectPath(Shape)) {
|
|
|
138
144
|
ctx.lineTo(startX + arrowSize * reverse, startY - bodyWidth * reverse)
|
|
139
145
|
ctx.lineTo(endX - arrowSize * reverse, endY - bodyWidth * reverse)
|
|
140
146
|
|
|
141
|
-
if (direction === '
|
|
147
|
+
if (direction === 'IN' || direction === 'BOTH') {
|
|
142
148
|
ctx.lineTo(endX - arrowSize * reverse, endY - bodyWidth * 2 * reverse)
|
|
143
149
|
} else {
|
|
144
150
|
ctx.lineTo(endX, endY - bodyWidth * reverse)
|
|
@@ -146,7 +152,7 @@ export default class PortFlow extends ParentObjectMixin(RectPath(Shape)) {
|
|
|
146
152
|
|
|
147
153
|
ctx.lineTo(endX, endY)
|
|
148
154
|
|
|
149
|
-
if (direction === '
|
|
155
|
+
if (direction === 'IN' || direction === 'BOTH') {
|
|
150
156
|
ctx.lineTo(endX - arrowSize * reverse, endY + bodyWidth * 2 * reverse)
|
|
151
157
|
} else {
|
|
152
158
|
ctx.lineTo(endX, endY + bodyWidth * reverse)
|
|
@@ -155,13 +161,13 @@ export default class PortFlow extends ParentObjectMixin(RectPath(Shape)) {
|
|
|
155
161
|
ctx.lineTo(endX - arrowSize * reverse, endY + bodyWidth * reverse)
|
|
156
162
|
ctx.lineTo(startX + arrowSize * reverse, startY + bodyWidth * reverse)
|
|
157
163
|
|
|
158
|
-
if (direction === '
|
|
164
|
+
if (direction === 'OUT' || direction === 'BOTH') {
|
|
159
165
|
ctx.lineTo(startX + arrowSize * reverse, startY + bodyWidth * 2 * reverse)
|
|
160
166
|
} else {
|
|
161
167
|
ctx.lineTo(startX, startY + bodyWidth * reverse)
|
|
162
168
|
}
|
|
163
169
|
} else {
|
|
164
|
-
if (direction === '
|
|
170
|
+
if (direction === 'OUT' || direction === 'BOTH') {
|
|
165
171
|
ctx.lineTo(startX - bodyWidth * reverse * 2, startY + arrowSize * reverse)
|
|
166
172
|
} else {
|
|
167
173
|
ctx.lineTo(startX - bodyWidth * reverse, startY)
|
|
@@ -170,7 +176,7 @@ export default class PortFlow extends ParentObjectMixin(RectPath(Shape)) {
|
|
|
170
176
|
ctx.lineTo(startX - bodyWidth * reverse, startY + arrowSize * reverse)
|
|
171
177
|
ctx.lineTo(endX - bodyWidth * reverse, endY - arrowSize * reverse)
|
|
172
178
|
|
|
173
|
-
if (direction === '
|
|
179
|
+
if (direction === 'IN' || direction === 'BOTH') {
|
|
174
180
|
ctx.lineTo(endX - bodyWidth * 2 * reverse, endY - arrowSize * reverse)
|
|
175
181
|
} else {
|
|
176
182
|
ctx.lineTo(endX - bodyWidth * reverse, endY)
|
|
@@ -178,7 +184,7 @@ export default class PortFlow extends ParentObjectMixin(RectPath(Shape)) {
|
|
|
178
184
|
|
|
179
185
|
ctx.lineTo(endX, endY)
|
|
180
186
|
|
|
181
|
-
if (direction === '
|
|
187
|
+
if (direction === 'IN' || direction === 'BOTH') {
|
|
182
188
|
ctx.lineTo(endX + bodyWidth * 2 * reverse, endY - arrowSize * reverse)
|
|
183
189
|
} else {
|
|
184
190
|
ctx.lineTo(endX + bodyWidth * reverse, endY)
|
|
@@ -187,7 +193,7 @@ export default class PortFlow extends ParentObjectMixin(RectPath(Shape)) {
|
|
|
187
193
|
ctx.lineTo(endX + bodyWidth * reverse, endY - arrowSize * reverse)
|
|
188
194
|
ctx.lineTo(startX + bodyWidth * reverse, startY + arrowSize * reverse)
|
|
189
195
|
|
|
190
|
-
if (direction === '
|
|
196
|
+
if (direction === 'OUT' || direction === 'BOTH') {
|
|
191
197
|
ctx.lineTo(startX + bodyWidth * 2 * reverse, startY + arrowSize * reverse)
|
|
192
198
|
} else {
|
|
193
199
|
ctx.lineTo(startX + bodyWidth * reverse, startY)
|
package/translations/en.json
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"label.high-watermark": "high watermark",
|
|
5
5
|
"label.legend-name": "legend",
|
|
6
6
|
"label.max-capacity": "max capacity",
|
|
7
|
+
"label.carrier-animation-name": "carrier animation",
|
|
7
8
|
"label.carrier-legend-name": "carrier legend",
|
|
8
9
|
"label.sc-state": "sc state",
|
|
9
10
|
"label.full-rate": "full rate",
|
package/translations/ja.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"label.low-watermark": "low watermark",
|
|
6
6
|
"label.legend-name": "legend",
|
|
7
7
|
"label.max-capacity": "max capacity",
|
|
8
|
+
"label.carrier-animation-name": "carrier animation",
|
|
8
9
|
"label.carrier-legend-name": "carrier legend",
|
|
9
10
|
"label.sc-state": "sc state",
|
|
10
11
|
"label.full-rate": "full rate",
|
package/translations/ko.json
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
"label.low-watermark": "저수위워터마크",
|
|
6
6
|
"label.legend-name": "레전드",
|
|
7
7
|
"label.max-capacity": "최대 용량",
|
|
8
|
-
"label.carrier-
|
|
8
|
+
"label.carrier-animation-name": "캐리어 애니메이션",
|
|
9
|
+
"label.carrier-legend-name": "캐리어 레전드",
|
|
9
10
|
"label.sc-state": "sc state",
|
|
10
11
|
"label.full-rate": "full rate",
|
|
11
12
|
"label.reserved-carrier": "reserved carrier",
|
package/translations/ms.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"label.low-watermark": "low watermark",
|
|
6
6
|
"label.legend-name": "legend",
|
|
7
7
|
"label.max-capacity": "max capacity",
|
|
8
|
+
"label.carrier-animation-name": "carrier animation",
|
|
8
9
|
"label.carrier-legend-name": "carrier legend",
|
|
9
10
|
"label.sc-state": "sc state",
|
|
10
11
|
"label.full-rate": "full rate",
|
package/translations/zh.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"label.low-watermark": "low watermark",
|
|
6
6
|
"label.legend-name": "legend",
|
|
7
7
|
"label.max-capacity": "max capacity",
|
|
8
|
+
"label.carrier-animation-name": "carrier animation",
|
|
8
9
|
"label.carrier-legend-name": "carrier legend",
|
|
9
10
|
"label.sc-state": "sc state",
|
|
10
11
|
"label.full-rate": "full rate",
|