@fmsim/machine 1.0.57 → 1.0.58
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/agv.js +72 -14
- package/dist/agv.js.map +1 -1
- package/dist/features/mcs-status-default.js +7 -0
- package/dist/features/mcs-status-default.js.map +1 -1
- package/dist/scene/root-container-override.js +14 -0
- package/dist/scene/root-container-override.js.map +1 -1
- package/dist/templates/index.js +0 -2
- package/dist/templates/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/agv.ts +88 -14
- package/src/features/mcs-status-default.ts +8 -0
- package/src/scene/root-container-override.ts +16 -0
- package/src/templates/index.ts +0 -2
- package/translations/en.json +2 -1
- package/translations/ja.json +2 -1
- package/translations/ko.json +2 -1
- package/translations/ms.json +2 -1
- package/translations/zh.json +2 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@fmsim/machine",
|
|
3
3
|
"description": "Layout View를 구성하는 설비(machine)들과 유닛을 구현한 모듈입니다.",
|
|
4
4
|
"author": "heartyoh",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.58",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
8
8
|
"things-scene": true,
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"prettier --write"
|
|
55
55
|
]
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "a96ffbe06662de2e62fcd78033b1f0d614206599"
|
|
58
58
|
}
|
package/src/agv.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Component, ComponentNature, Properties } from '@hatiolab/things-scene'
|
|
2
2
|
import MCSVehicle from './mcs-vehicle'
|
|
3
|
+
import { getVaueOnRanges } from './utils/get-value-on-ranges'
|
|
4
|
+
import { BATTERY_RATE_LEGEND } from './features/mcs-status-default'
|
|
3
5
|
|
|
4
6
|
const NATURE: ComponentNature = {
|
|
5
7
|
mutable: false,
|
|
@@ -22,22 +24,32 @@ export default class AGV extends MCSVehicle {
|
|
|
22
24
|
return this.root.agvLegendTheme || super.getLegendFallback()
|
|
23
25
|
}
|
|
24
26
|
|
|
27
|
+
getBatteryLegendTheme() {
|
|
28
|
+
return this.root.batteryRateLegendTheme || BATTERY_RATE_LEGEND
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getBatteryColor(rate: number) {
|
|
32
|
+
return getVaueOnRanges(rate, this.getBatteryLegendTheme())
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
render(ctx: CanvasRenderingContext2D) {
|
|
26
36
|
var { left, top, width, height } = this.bounds
|
|
27
37
|
|
|
28
38
|
ctx.translate(left, top)
|
|
29
39
|
ctx.beginPath()
|
|
30
40
|
|
|
41
|
+
// 작은 크기에서도 보이도록 최소 선 두께 설정
|
|
42
|
+
const minLineWidth = 0.5
|
|
43
|
+
const scaleFactor = Math.min(width, height) / 100
|
|
44
|
+
const lineWidth = Math.max(minLineWidth, scaleFactor)
|
|
45
|
+
|
|
31
46
|
ctx.strokeStyle = this.auxColor
|
|
32
47
|
ctx.fillStyle = this.statusColor!
|
|
33
|
-
ctx.lineWidth =
|
|
48
|
+
ctx.lineWidth = lineWidth
|
|
34
49
|
ctx.lineCap = 'round'
|
|
35
50
|
ctx.setLineDash([])
|
|
36
51
|
|
|
37
|
-
//
|
|
38
|
-
// const radius = Math.round(Math.min(width, height) * 0.1)
|
|
39
|
-
// ctx.roundRect(1, 0, width - 2, height, radius)
|
|
40
|
-
// ctx.roundRect(GAP + 1, GAP, width - (GAP + 1) * 2, height - GAP * 2, radius - 1)
|
|
52
|
+
// 기본 사각형 그리기
|
|
41
53
|
ctx.rect(1, 0, width - 2, height)
|
|
42
54
|
ctx.rect(GAP + 1, GAP, width - (GAP + 1) * 2, height - GAP * 2)
|
|
43
55
|
|
|
@@ -46,7 +58,7 @@ export default class AGV extends MCSVehicle {
|
|
|
46
58
|
|
|
47
59
|
ctx.beginPath()
|
|
48
60
|
|
|
49
|
-
//
|
|
61
|
+
// 바퀴 그리기
|
|
50
62
|
ctx.strokeStyle = 'black'
|
|
51
63
|
|
|
52
64
|
ctx.moveTo(0, (height * 1) / 3)
|
|
@@ -59,23 +71,85 @@ export default class AGV extends MCSVehicle {
|
|
|
59
71
|
ctx.translate(-left, -top)
|
|
60
72
|
}
|
|
61
73
|
|
|
74
|
+
// 사선 패턴을 그리는 함수
|
|
75
|
+
drawHatchPattern(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number) {
|
|
76
|
+
// 크기에 따라 패턴 간격과 선 두께 조정 (2배 덜 조밀하게)
|
|
77
|
+
const minSpacing = 4 // 최소 간격 2배 증가 (원래 2의 2배)
|
|
78
|
+
const maxSpacing = 16 // 최대 간격 2배 증가 (원래 8의 2배)
|
|
79
|
+
const preferredSpacing = Math.max(minSpacing, Math.min(width, height) / 5) // 간격 계산 시 나누는 값 1/2로 감소
|
|
80
|
+
const spacing = Math.min(preferredSpacing, maxSpacing)
|
|
81
|
+
|
|
82
|
+
// 선 두께 계산 (작은 크기에서도 보이도록)
|
|
83
|
+
const minLineWidth = 0.35
|
|
84
|
+
const scaleFactor = Math.min(width, height) / 130
|
|
85
|
+
const lineWidth = Math.max(minLineWidth, scaleFactor)
|
|
86
|
+
|
|
87
|
+
ctx.beginPath()
|
|
88
|
+
ctx.strokeStyle = 'black'
|
|
89
|
+
ctx.lineWidth = lineWidth
|
|
90
|
+
|
|
91
|
+
// 배터리 박스 내부로 클리핑 설정
|
|
92
|
+
ctx.save()
|
|
93
|
+
ctx.rect(x, y, width, height)
|
|
94
|
+
ctx.clip()
|
|
95
|
+
|
|
96
|
+
// 사선 패턴 그리기
|
|
97
|
+
for (let i = -height; i < width + height; i += spacing) {
|
|
98
|
+
ctx.moveTo(x + i, y)
|
|
99
|
+
ctx.lineTo(x + i - height, y + height)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
ctx.stroke()
|
|
103
|
+
// 클리핑 해제
|
|
104
|
+
ctx.restore()
|
|
105
|
+
}
|
|
106
|
+
|
|
62
107
|
postrender(ctx: CanvasRenderingContext2D): void {
|
|
63
108
|
super.postrender(ctx)
|
|
64
109
|
|
|
65
110
|
const BATTERYRATE = this.data?.BATTERYRATE
|
|
66
111
|
|
|
67
|
-
if (typeof BATTERYRATE
|
|
112
|
+
if (typeof BATTERYRATE === 'number') {
|
|
68
113
|
const { left, top, width, height } = this.bounds
|
|
69
114
|
ctx.translate(left, top)
|
|
70
115
|
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
const
|
|
116
|
+
// 배터리 크기 및 위치 설정 (최소 크기 보장)
|
|
117
|
+
const minBatteryHeight = 2
|
|
118
|
+
const minBatteryWidth = 4
|
|
119
|
+
const preferredHeight = height / 5
|
|
120
|
+
const preferredWidth = (width * 3) / 4
|
|
121
|
+
|
|
122
|
+
const batteryHeight = Math.max(minBatteryHeight, preferredHeight)
|
|
123
|
+
const batteryWidth = Math.max(minBatteryWidth, preferredWidth)
|
|
124
|
+
const batteryX = (width - batteryWidth) / 2
|
|
125
|
+
const batteryY = (height - batteryHeight) * 1.1
|
|
126
|
+
|
|
127
|
+
// 배터리 테두리 그리기 (크기에 비례한 선 두께)
|
|
128
|
+
const minLineWidth = 0.5
|
|
129
|
+
const scaleFactor = Math.min(width, height) / 100
|
|
130
|
+
const lineWidth = Math.max(minLineWidth, scaleFactor)
|
|
131
|
+
|
|
132
|
+
// 배터리 배경을 흰색으로 채우기
|
|
133
|
+
ctx.fillStyle = 'white'
|
|
134
|
+
ctx.fillRect(batteryX, batteryY, batteryWidth, batteryHeight)
|
|
135
|
+
|
|
136
|
+
// 배터리 전체 영역에 사선 패턴 그리기
|
|
137
|
+
this.drawHatchPattern(ctx, batteryX, batteryY, batteryWidth, batteryHeight)
|
|
138
|
+
|
|
139
|
+
// 배터리 잔량 표시
|
|
140
|
+
const fillWidth = (batteryWidth * BATTERYRATE) / 100
|
|
141
|
+
|
|
142
|
+
// 배터리 잔량에 따른 색상 설정 - 테마 적용
|
|
143
|
+
ctx.fillStyle = this.getBatteryColor(BATTERYRATE)
|
|
144
|
+
|
|
145
|
+
// 배터리 잔량 영역 채우기
|
|
146
|
+
ctx.fillRect(batteryX, batteryY, fillWidth, batteryHeight)
|
|
74
147
|
|
|
75
|
-
|
|
76
|
-
ctx.
|
|
77
|
-
ctx.
|
|
78
|
-
ctx.
|
|
148
|
+
// 배터리 테두리 다시 그리기
|
|
149
|
+
ctx.beginPath()
|
|
150
|
+
ctx.strokeStyle = 'black'
|
|
151
|
+
ctx.lineWidth = lineWidth
|
|
152
|
+
ctx.strokeRect(batteryX, batteryY, batteryWidth, batteryHeight)
|
|
79
153
|
|
|
80
154
|
ctx.translate(-left, -top)
|
|
81
155
|
}
|
|
@@ -67,3 +67,11 @@ export const LEGEND_CAPACITY: Legend = {
|
|
|
67
67
|
'80~100': '#FD9B00',
|
|
68
68
|
default: '#F0F0F0'
|
|
69
69
|
}
|
|
70
|
+
|
|
71
|
+
export const BATTERY_RATE_LEGEND: Legend = {
|
|
72
|
+
'0~20': '#EB3245', // 0-20%: 빨간색 (위험)
|
|
73
|
+
'20~40': '#FD9B00', // 20-40%: 주황색 (경고)
|
|
74
|
+
'40~60': '#F4F226', // 40-60%: 노란색 (주의)
|
|
75
|
+
'60~100': '#8BDA5B', // 60-100%: 녹색 (정상)
|
|
76
|
+
default: '#F0F0F0'
|
|
77
|
+
}
|
|
@@ -10,6 +10,7 @@ declare module '@hatiolab/things-scene' {
|
|
|
10
10
|
carrierAnimationTheme?: any
|
|
11
11
|
stockerCapacityLegendTheme?: any
|
|
12
12
|
zoneCapacityLegendTheme?: any
|
|
13
|
+
batteryRateLegendTheme?: any
|
|
13
14
|
bufferLegendTheme?: any
|
|
14
15
|
agvlineLegendTheme?: any
|
|
15
16
|
ohtlineLegendTheme?: any
|
|
@@ -183,6 +184,14 @@ Object.defineProperty(ModelLayer.prototype, 'nature', {
|
|
|
183
184
|
property: {
|
|
184
185
|
options: themesColorRange
|
|
185
186
|
}
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
type: 'select',
|
|
190
|
+
label: 'battery-rate-legend-name',
|
|
191
|
+
name: 'batteryRateLegendName',
|
|
192
|
+
property: {
|
|
193
|
+
options: themesColorRange
|
|
194
|
+
}
|
|
186
195
|
}
|
|
187
196
|
],
|
|
188
197
|
'value-property': 'text'
|
|
@@ -302,6 +311,13 @@ Object.defineProperty(RootContainer.prototype, 'zoneCapacityLegendTheme', {
|
|
|
302
311
|
}
|
|
303
312
|
})
|
|
304
313
|
|
|
314
|
+
Object.defineProperty(RootContainer.prototype, 'batteryRateLegendTheme', {
|
|
315
|
+
get: function () {
|
|
316
|
+
const { batteryRateLegendName } = this.rootModel.state
|
|
317
|
+
return batteryRateLegendName && this.state.style[batteryRateLegendName]
|
|
318
|
+
}
|
|
319
|
+
})
|
|
320
|
+
|
|
305
321
|
Object.defineProperty(RootContainer.prototype, 'vehicleAnimation', {
|
|
306
322
|
get: function () {
|
|
307
323
|
const { vehicleAnimation } = this.rootModel.state
|
package/src/templates/index.ts
CHANGED
|
@@ -18,7 +18,6 @@ import ohtLine from './oht-line'
|
|
|
18
18
|
import conveyor from './conveyor'
|
|
19
19
|
|
|
20
20
|
import Node from './node'
|
|
21
|
-
import NodePath from './node-path'
|
|
22
21
|
import DataSubscription from './data-subscription'
|
|
23
22
|
|
|
24
23
|
export default [
|
|
@@ -42,6 +41,5 @@ export default [
|
|
|
42
41
|
Port,
|
|
43
42
|
|
|
44
43
|
Node,
|
|
45
|
-
NodePath,
|
|
46
44
|
DataSubscription
|
|
47
45
|
]
|
package/translations/en.json
CHANGED
|
@@ -45,5 +45,6 @@
|
|
|
45
45
|
"label.equipment-legend-name": "equipment",
|
|
46
46
|
"label.node-machine": "node machine",
|
|
47
47
|
"label.nodes": "nodes",
|
|
48
|
-
"label.vehicle-animation": "vehicle animation"
|
|
48
|
+
"label.vehicle-animation": "vehicle animation",
|
|
49
|
+
"label.battery-rate-legend-name": "battery rate"
|
|
49
50
|
}
|
package/translations/ja.json
CHANGED
|
@@ -47,5 +47,6 @@
|
|
|
47
47
|
"label.equipment-legend-name": "equipment",
|
|
48
48
|
"label.node-machine": "node machine",
|
|
49
49
|
"label.nodes": "nodes",
|
|
50
|
-
"label.vehicle-animation": "vehicle animation"
|
|
50
|
+
"label.vehicle-animation": "vehicle animation",
|
|
51
|
+
"label.battery-rate-legend-name": "battery rate"
|
|
51
52
|
}
|
package/translations/ko.json
CHANGED
package/translations/ms.json
CHANGED
|
@@ -47,5 +47,6 @@
|
|
|
47
47
|
"label.equipment-legend-name": "equipment",
|
|
48
48
|
"label.node-machine": "node machine",
|
|
49
49
|
"label.nodes": "nodes",
|
|
50
|
-
"label.vehicle-animation": "vehicle animation"
|
|
50
|
+
"label.vehicle-animation": "vehicle animation",
|
|
51
|
+
"label.battery-rate-legend-name": "battery rate"
|
|
51
52
|
}
|
package/translations/zh.json
CHANGED
|
@@ -47,5 +47,6 @@
|
|
|
47
47
|
"label.equipment-legend-name": "equipment",
|
|
48
48
|
"label.node-machine": "node machine",
|
|
49
49
|
"label.nodes": "nodes",
|
|
50
|
-
"label.vehicle-animation": "vehicle animation"
|
|
50
|
+
"label.vehicle-animation": "vehicle animation",
|
|
51
|
+
"label.battery-rate-legend-name": "battery rate"
|
|
51
52
|
}
|