@fmsim/machine 2.0.0-beta.10 → 2.0.0-beta.100
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 +6 -2
- package/dist/agv.js.map +1 -1
- package/dist/carrier-manager.js +183 -0
- package/dist/carrier-manager.js.map +1 -0
- package/dist/carrier.js +99 -9
- package/dist/carrier.js.map +1 -1
- package/dist/conveyor-join.js +8 -2
- package/dist/conveyor-join.js.map +1 -1
- package/dist/conveyor.js +8 -0
- package/dist/conveyor.js.map +1 -1
- package/dist/crane.js +144 -1
- package/dist/crane.js.map +1 -1
- package/dist/factories/agv-3d.js +8 -9
- package/dist/factories/agv-3d.js.map +1 -1
- package/dist/factories/conveyor-3d.js +168 -81
- package/dist/factories/conveyor-3d.js.map +1 -1
- package/dist/factories/crane-3d.js +48 -12
- package/dist/factories/crane-3d.js.map +1 -1
- package/dist/factories/crane-rail-3d.js +6 -6
- package/dist/factories/crane-rail-3d.js.map +1 -1
- package/dist/factories/machine-3d.js +527 -181
- package/dist/factories/machine-3d.js.map +1 -1
- package/dist/factories/oht-3d.js +20 -20
- package/dist/factories/oht-3d.js.map +1 -1
- package/dist/factories/shuttle-3d.js +2 -5
- package/dist/factories/shuttle-3d.js.map +1 -1
- package/dist/factories/z-priority-defaults.js +33 -0
- package/dist/factories/z-priority-defaults.js.map +1 -0
- package/dist/factories/z-priority.js +54 -0
- package/dist/factories/z-priority.js.map +1 -0
- package/dist/features/conveyor-mixin.js.map +1 -1
- package/dist/features/mcs-status-default.js +15 -1
- package/dist/features/mcs-status-default.js.map +1 -1
- package/dist/features/mcs-status-mixin.js +22 -0
- package/dist/features/mcs-status-mixin.js.map +1 -1
- package/dist/features/mcs-zone-mixin.js.map +1 -1
- package/dist/features/parent-object-mixin.js +15 -7
- package/dist/features/parent-object-mixin.js.map +1 -1
- package/dist/floating-container.js +5 -0
- package/dist/floating-container.js.map +1 -1
- package/dist/index.js +52 -34
- package/dist/index.js.map +1 -1
- package/dist/mcs-carrier-holder.js +56 -22
- package/dist/mcs-carrier-holder.js.map +1 -1
- package/dist/mcs-machine.js +39 -0
- package/dist/mcs-machine.js.map +1 -1
- package/dist/mcs-unit.js +20 -0
- package/dist/mcs-unit.js.map +1 -1
- package/dist/mcs-vehicle.js +8 -3
- package/dist/mcs-vehicle.js.map +1 -1
- package/dist/node.js +10 -3
- package/dist/node.js.map +1 -1
- package/dist/oht.js +4 -0
- package/dist/oht.js.map +1 -1
- package/dist/port-flow.js +4 -0
- package/dist/port-flow.js.map +1 -1
- package/dist/port.js +4 -0
- package/dist/port.js.map +1 -1
- package/dist/scanner.js +30 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scene/root-container-override.js +160 -96
- package/dist/scene/root-container-override.js.map +1 -1
- package/dist/shelf.js +4 -0
- package/dist/shelf.js.map +1 -1
- package/dist/static-container.js +5 -0
- package/dist/static-container.js.map +1 -1
- package/dist/stocker-abnormal-bar.js +5 -1
- package/dist/stocker-abnormal-bar.js.map +1 -1
- package/dist/stocker-capacity-bar.js +253 -6
- package/dist/stocker-capacity-bar.js.map +1 -1
- package/dist/stocker-carrier-bar.js +5 -1
- package/dist/stocker-carrier-bar.js.map +1 -1
- package/dist/stocker.js +6 -0
- package/dist/stocker.js.map +1 -1
- package/dist/templates/backdrop.js +30 -0
- package/dist/templates/backdrop.js.map +1 -0
- package/dist/templates/decal.js +21 -0
- package/dist/templates/decal.js.map +1 -0
- package/dist/templates/index.js +7 -1
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/scanner.js +20 -0
- package/dist/templates/scanner.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/crane-position.js +83 -0
- package/dist/utils/crane-position.js.map +1 -0
- package/dist/utils/data-value.js +21 -0
- package/dist/utils/data-value.js.map +1 -0
- package/dist/utils/fit-gauge-scale.js +28 -0
- package/dist/utils/fit-gauge-scale.js.map +1 -0
- package/dist/utils/get-value-on-ranges.js +2 -4
- package/dist/utils/get-value-on-ranges.js.map +1 -1
- package/dist/utils/stocker-gauge.js +78 -0
- package/dist/utils/stocker-gauge.js.map +1 -0
- package/dist/zone-capacity-bar.js +3 -3
- package/dist/zone-capacity-bar.js.map +1 -1
- package/icons/backdrop.png +0 -0
- package/icons/decal.png +0 -0
- package/jest.config.js +10 -0
- package/package.json +4 -3
- package/src/agv.ts +7 -2
- package/src/carrier-manager.ts +223 -0
- package/src/carrier.ts +103 -10
- package/src/conveyor-join.ts +5 -2
- package/src/conveyor.ts +8 -0
- package/src/crane.ts +181 -1
- package/src/factories/agv-3d.ts +9 -10
- package/src/factories/conveyor-3d.ts +171 -84
- package/src/factories/crane-3d.ts +53 -12
- package/src/factories/crane-rail-3d.ts +8 -7
- package/src/factories/machine-3d.ts +616 -191
- package/src/factories/oht-3d.ts +20 -20
- package/src/factories/shuttle-3d.ts +2 -6
- package/src/factories/z-priority-defaults.ts +38 -0
- package/src/factories/z-priority.ts +60 -0
- package/src/features/conveyor-mixin.ts +1 -1
- package/src/features/mcs-status-default.ts +15 -1
- package/src/features/mcs-status-mixin.ts +26 -4
- package/src/features/mcs-zone-mixin.ts +1 -1
- package/src/features/parent-object-mixin.ts +17 -8
- package/src/floating-container.ts +5 -0
- package/src/index.ts +58 -34
- package/src/mcs-carrier-holder.ts +57 -34
- package/src/mcs-machine.ts +42 -0
- package/src/mcs-unit.ts +24 -1
- package/src/mcs-vehicle.ts +9 -6
- package/src/node.ts +9 -3
- package/src/oht.ts +6 -1
- package/src/port-flow.ts +5 -0
- package/src/port.ts +5 -0
- package/src/scanner.ts +29 -0
- package/src/scene/root-container-override.ts +154 -103
- package/src/shelf.ts +5 -0
- package/src/static-container.ts +5 -0
- package/src/stocker-abnormal-bar.ts +6 -1
- package/src/stocker-capacity-bar.ts +298 -7
- package/src/stocker-carrier-bar.ts +6 -1
- package/src/stocker.ts +7 -0
- package/src/templates/backdrop.ts +30 -0
- package/src/templates/decal.ts +21 -0
- package/src/templates/index.ts +7 -1
- package/src/templates/scanner.ts +20 -0
- package/src/utils/crane-position.ts +105 -0
- package/src/utils/data-value.ts +19 -0
- package/src/utils/fit-gauge-scale.ts +35 -0
- package/src/utils/get-value-on-ranges.ts +2 -4
- package/src/utils/stocker-gauge.ts +111 -0
- package/src/zone-capacity-bar.ts +3 -3
- package/translations/en.json +26 -1
- package/translations/ja.json +26 -1
- package/translations/ko.json +26 -1
- package/translations/ms.json +26 -1
- package/translations/zh.json +26 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Crane 위치 데이터 (data.cranePosition) 변환 유틸.
|
|
3
|
+
*
|
|
4
|
+
* 명세:
|
|
5
|
+
* {
|
|
6
|
+
* cranePosition: {
|
|
7
|
+
* current: { x, y, z }, // 실 좌표값
|
|
8
|
+
* limit: { x:{min,max}, y:{min,max}, z:{min,max} } // 각 축 한계
|
|
9
|
+
* }
|
|
10
|
+
* }
|
|
11
|
+
*
|
|
12
|
+
* current 를 limit 범위 안의 0~1 비율로 환산한 뒤 host(부모) footprint 에 매핑한다.
|
|
13
|
+
* x → host 긴쪽, y → 짧은쪽, z → 포크 높이(forkZ 0~100).
|
|
14
|
+
*/
|
|
15
|
+
import { parseIfJsonString } from './data-value';
|
|
16
|
+
/**
|
|
17
|
+
* current 값을 limit 범위 안에서 0~1 비율로 환산.
|
|
18
|
+
* limit 누락 / 0 span / 비정상 입력 시 0 반환 (안전 fallback).
|
|
19
|
+
*/
|
|
20
|
+
export function axisRatio(value, lim) {
|
|
21
|
+
const v = Number(value);
|
|
22
|
+
const min = Number(lim === null || lim === void 0 ? void 0 : lim.min) || 0;
|
|
23
|
+
const max = Number(lim === null || lim === void 0 ? void 0 : lim.max);
|
|
24
|
+
if (!Number.isFinite(v) || !Number.isFinite(max) || max === min)
|
|
25
|
+
return 0;
|
|
26
|
+
return Math.max(0, Math.min(1, (v - min) / (max - min)));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* host(부모) footprint 안에서 0~1 비율 (rx,ry) → 크레인 top-left 로컬 좌표.
|
|
30
|
+
*
|
|
31
|
+
* **스토커 안쪽 오프셋**: 크레인의 폭/두께를 감안해, 크레인 *전체* 가 host 안에
|
|
32
|
+
* 머무르도록 top-left 좌표를 [0, hostLen - craneLen] 범위로 매핑한다 (= 양끝에서
|
|
33
|
+
* craneLen/2 만큼 inset 된 중심선 위를 움직임). 크레인이 host 보다 크면 span 0
|
|
34
|
+
* 으로 떨어져 host 모서리에 정렬.
|
|
35
|
+
*
|
|
36
|
+
* x(rx) 는 host 의 긴쪽, y(ry) 는 짧은쪽에 매핑 (가상 rail 은 host 긴쪽 방향).
|
|
37
|
+
*/
|
|
38
|
+
export function mapCraneLocalPosition(hostW, hostH, craneW, craneH, rx, ry) {
|
|
39
|
+
const longIsWidth = hostW >= hostH;
|
|
40
|
+
const longLen = longIsWidth ? hostW : hostH;
|
|
41
|
+
const shortLen = longIsWidth ? hostH : hostW;
|
|
42
|
+
const craneLongSize = longIsWidth ? craneW : craneH;
|
|
43
|
+
const craneShortSize = longIsWidth ? craneH : craneW;
|
|
44
|
+
// 크레인 크기를 뺀 inset 가용 span. top-left = ratio * span 이므로 크레인
|
|
45
|
+
// 전체가 host [0, hostLen] 안에 들어온다.
|
|
46
|
+
const longSpan = Math.max(0, longLen - craneLongSize);
|
|
47
|
+
const shortSpan = Math.max(0, shortLen - craneShortSize);
|
|
48
|
+
const longPos = rx * longSpan;
|
|
49
|
+
const shortPos = ry * shortSpan;
|
|
50
|
+
return {
|
|
51
|
+
left: longIsWidth ? longPos : shortPos,
|
|
52
|
+
top: longIsWidth ? shortPos : longPos
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 객체 키를 재귀적으로 소문자화한 사본 반환 (배열/원시값은 그대로, 값은 변형 안 함).
|
|
57
|
+
* 데이터 키는 모두 대문자 전제 — CRANEPOSITION 의 중첩 키(CURRENT/LIMIT/X/Y/Z/MIN/MAX)를
|
|
58
|
+
* 내부 표준형(소문자 current/limit/x/y/z/min/max)으로 변환하기 위한 정규화.
|
|
59
|
+
*/
|
|
60
|
+
export function lowerKeysDeep(value) {
|
|
61
|
+
if (Array.isArray(value))
|
|
62
|
+
return value.map(v => lowerKeysDeep(v));
|
|
63
|
+
if (value && typeof value === 'object') {
|
|
64
|
+
const out = {};
|
|
65
|
+
for (const k of Object.keys(value)) {
|
|
66
|
+
out[k.toLowerCase()] = lowerKeysDeep(value[k]);
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* raw CRANEPOSITION → 내부 표준형(소문자 키) 구조(CranePositionData).
|
|
74
|
+
* 값이 JSON 문자열로 올 수 있어 먼저 파싱하고, 중첩 키(CURRENT/LIMIT/X/Y/Z/MIN/MAX)를
|
|
75
|
+
* 소문자(current.x / limit.x.min)로 변환. 파싱 실패/비객체면 undefined.
|
|
76
|
+
*/
|
|
77
|
+
export function normalizeCranePosition(raw) {
|
|
78
|
+
const obj = parseIfJsonString(raw);
|
|
79
|
+
if (!obj || typeof obj !== 'object')
|
|
80
|
+
return undefined;
|
|
81
|
+
return lowerKeysDeep(obj);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=crane-position.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crane-position.js","sourceRoot":"","sources":["../../src/utils/crane-position.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Crane 위치 데이터 (data.cranePosition) 변환 유틸.\n *\n * 명세:\n * {\n * cranePosition: {\n * current: { x, y, z }, // 실 좌표값\n * limit: { x:{min,max}, y:{min,max}, z:{min,max} } // 각 축 한계\n * }\n * }\n *\n * current 를 limit 범위 안의 0~1 비율로 환산한 뒤 host(부모) footprint 에 매핑한다.\n * x → host 긴쪽, y → 짧은쪽, z → 포크 높이(forkZ 0~100).\n */\n\nimport { parseIfJsonString } from './data-value'\n\n/** 축별 한계 (cranePosition.limit.{x|y|z}). */\nexport interface AxisLimit {\n min?: number\n max?: number\n}\n\n/** 새 데이터 명세 — data.cranePosition. */\nexport interface CranePositionData {\n current?: { x?: number; y?: number; z?: number }\n limit?: { x?: AxisLimit; y?: AxisLimit; z?: AxisLimit }\n}\n\n/**\n * current 값을 limit 범위 안에서 0~1 비율로 환산.\n * limit 누락 / 0 span / 비정상 입력 시 0 반환 (안전 fallback).\n */\nexport function axisRatio(value: unknown, lim?: AxisLimit): number {\n const v = Number(value)\n const min = Number(lim?.min) || 0\n const max = Number(lim?.max)\n if (!Number.isFinite(v) || !Number.isFinite(max) || max === min) return 0\n return Math.max(0, Math.min(1, (v - min) / (max - min)))\n}\n\n/**\n * host(부모) footprint 안에서 0~1 비율 (rx,ry) → 크레인 top-left 로컬 좌표.\n *\n * **스토커 안쪽 오프셋**: 크레인의 폭/두께를 감안해, 크레인 *전체* 가 host 안에\n * 머무르도록 top-left 좌표를 [0, hostLen - craneLen] 범위로 매핑한다 (= 양끝에서\n * craneLen/2 만큼 inset 된 중심선 위를 움직임). 크레인이 host 보다 크면 span 0\n * 으로 떨어져 host 모서리에 정렬.\n *\n * x(rx) 는 host 의 긴쪽, y(ry) 는 짧은쪽에 매핑 (가상 rail 은 host 긴쪽 방향).\n */\nexport function mapCraneLocalPosition(\n hostW: number,\n hostH: number,\n craneW: number,\n craneH: number,\n rx: number,\n ry: number\n): { left: number; top: number } {\n const longIsWidth = hostW >= hostH\n const longLen = longIsWidth ? hostW : hostH\n const shortLen = longIsWidth ? hostH : hostW\n const craneLongSize = longIsWidth ? craneW : craneH\n const craneShortSize = longIsWidth ? craneH : craneW\n\n // 크레인 크기를 뺀 inset 가용 span. top-left = ratio * span 이므로 크레인\n // 전체가 host [0, hostLen] 안에 들어온다.\n const longSpan = Math.max(0, longLen - craneLongSize)\n const shortSpan = Math.max(0, shortLen - craneShortSize)\n const longPos = rx * longSpan\n const shortPos = ry * shortSpan\n\n return {\n left: longIsWidth ? longPos : shortPos,\n top: longIsWidth ? shortPos : longPos\n }\n}\n\n/**\n * 객체 키를 재귀적으로 소문자화한 사본 반환 (배열/원시값은 그대로, 값은 변형 안 함).\n * 데이터 키는 모두 대문자 전제 — CRANEPOSITION 의 중첩 키(CURRENT/LIMIT/X/Y/Z/MIN/MAX)를\n * 내부 표준형(소문자 current/limit/x/y/z/min/max)으로 변환하기 위한 정규화.\n */\nexport function lowerKeysDeep<T = any>(value: any): T {\n if (Array.isArray(value)) return value.map(v => lowerKeysDeep(v)) as any\n if (value && typeof value === 'object') {\n const out: Record<string, any> = {}\n for (const k of Object.keys(value)) {\n out[k.toLowerCase()] = lowerKeysDeep(value[k])\n }\n return out as T\n }\n return value as T\n}\n\n/**\n * raw CRANEPOSITION → 내부 표준형(소문자 키) 구조(CranePositionData).\n * 값이 JSON 문자열로 올 수 있어 먼저 파싱하고, 중첩 키(CURRENT/LIMIT/X/Y/Z/MIN/MAX)를\n * 소문자(current.x / limit.x.min)로 변환. 파싱 실패/비객체면 undefined.\n */\nexport function normalizeCranePosition(raw: any): CranePositionData | undefined {\n const obj = parseIfJsonString(raw)\n if (!obj || typeof obj !== 'object') return undefined\n return lowerKeysDeep<CranePositionData>(obj)\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* 데이터 필드값이 JSON 문자열로 전달될 수 있어(예: CRANEPOSITION, MULTICARRIERS)
|
|
5
|
+
* 객체/배열로 변환하기 위한 헬퍼.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 값이 JSON 문자열이면 파싱해서 반환. 객체/배열 등 비문자열은 그대로 반환.
|
|
9
|
+
* 파싱 실패 시 undefined.
|
|
10
|
+
*/
|
|
11
|
+
export function parseIfJsonString(value) {
|
|
12
|
+
if (typeof value !== 'string')
|
|
13
|
+
return value;
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(value);
|
|
16
|
+
}
|
|
17
|
+
catch (_a) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=data-value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-value.js","sourceRoot":"","sources":["../../src/utils/data-value.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAU;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC1B,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * 데이터 필드값이 JSON 문자열로 전달될 수 있어(예: CRANEPOSITION, MULTICARRIERS)\n * 객체/배열로 변환하기 위한 헬퍼.\n */\n\n/**\n * 값이 JSON 문자열이면 파싱해서 반환. 객체/배열 등 비문자열은 그대로 반환.\n * 파싱 실패 시 undefined.\n */\nexport function parseIfJsonString(value: any): any {\n if (typeof value !== 'string') return value\n try {\n return JSON.parse(value)\n } catch {\n return undefined\n }\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 스토커 지붕 위 용량 게이지 바의 비례 축소 계수를 계산한다.
|
|
3
|
+
*
|
|
4
|
+
* 정책:
|
|
5
|
+
* - 게이지 바의 *최대* 크기는 maxW × maxH. 스토커가 충분히 크면 이 크기 그대로 (계수 1).
|
|
6
|
+
* - 스토커가 그보다 작으면 지붕 footprint 안에 들어오도록 *비례* 축소 (uniform).
|
|
7
|
+
* - *확대는 하지 않는다* (계수 상한 1) — 현재 크기가 상한이라는 요구사항.
|
|
8
|
+
*
|
|
9
|
+
* 방향 매핑: 바의 가로축(maxW)은 스토커의 *장축*에 정렬된다 (buildGauge 의
|
|
10
|
+
* `isWidthLonger ? geo.rotateY` 처리와 일치). 따라서 가용 치수도 그 기준으로 매칭한다.
|
|
11
|
+
*
|
|
12
|
+
* @param w 스토커 footprint 가로 (월드 단위)
|
|
13
|
+
* @param h 스토커 footprint 세로 (월드 단위)
|
|
14
|
+
* @param maxW 게이지 바 최대 가로
|
|
15
|
+
* @param maxH 게이지 바 최대 세로
|
|
16
|
+
* @param margin 지붕 가장자리 여백 비율 (0~1, 기본 0.85)
|
|
17
|
+
* @returns 0 < scale <= 1
|
|
18
|
+
*/
|
|
19
|
+
export function fitGaugeScale(w, h, maxW, maxH, margin = 0.85) {
|
|
20
|
+
const isWidthLonger = w >= h;
|
|
21
|
+
// 바 가로축(maxW)이 정렬되는 스토커 치수 = 장축, 세로축(maxH) = 단축
|
|
22
|
+
const availAlongW = isWidthLonger ? w : h;
|
|
23
|
+
const availAlongH = isWidthLonger ? h : w;
|
|
24
|
+
const scale = Math.min(1, (availAlongW * margin) / maxW, (availAlongH * margin) / maxH);
|
|
25
|
+
// 음수/NaN 방어 — 0 이하로 떨어지면 안 됨
|
|
26
|
+
return scale > 0 && Number.isFinite(scale) ? scale : 1;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=fit-gauge-scale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fit-gauge-scale.js","sourceRoot":"","sources":["../../src/utils/fit-gauge-scale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,aAAa,CAC3B,CAAS,EACT,CAAS,EACT,IAAY,EACZ,IAAY,EACZ,SAAiB,IAAI;IAErB,MAAM,aAAa,GAAG,CAAC,IAAI,CAAC,CAAA;IAC5B,gDAAgD;IAChD,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACzC,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;IAEvF,6BAA6B;IAC7B,OAAO,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AACxD,CAAC","sourcesContent":["/**\n * 스토커 지붕 위 용량 게이지 바의 비례 축소 계수를 계산한다.\n *\n * 정책:\n * - 게이지 바의 *최대* 크기는 maxW × maxH. 스토커가 충분히 크면 이 크기 그대로 (계수 1).\n * - 스토커가 그보다 작으면 지붕 footprint 안에 들어오도록 *비례* 축소 (uniform).\n * - *확대는 하지 않는다* (계수 상한 1) — 현재 크기가 상한이라는 요구사항.\n *\n * 방향 매핑: 바의 가로축(maxW)은 스토커의 *장축*에 정렬된다 (buildGauge 의\n * `isWidthLonger ? geo.rotateY` 처리와 일치). 따라서 가용 치수도 그 기준으로 매칭한다.\n *\n * @param w 스토커 footprint 가로 (월드 단위)\n * @param h 스토커 footprint 세로 (월드 단위)\n * @param maxW 게이지 바 최대 가로\n * @param maxH 게이지 바 최대 세로\n * @param margin 지붕 가장자리 여백 비율 (0~1, 기본 0.85)\n * @returns 0 < scale <= 1\n */\nexport function fitGaugeScale(\n w: number,\n h: number,\n maxW: number,\n maxH: number,\n margin: number = 0.85\n): number {\n const isWidthLonger = w >= h\n // 바 가로축(maxW)이 정렬되는 스토커 치수 = 장축, 세로축(maxH) = 단축\n const availAlongW = isWidthLonger ? w : h\n const availAlongH = isWidthLonger ? h : w\n\n const scale = Math.min(1, (availAlongW * margin) / maxW, (availAlongH * margin) / maxH)\n\n // 음수/NaN 방어 — 0 이하로 떨어지면 안 됨\n return scale > 0 && Number.isFinite(scale) ? scale : 1\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function
|
|
1
|
+
export function getValueOnRanges(value, param) {
|
|
2
2
|
for (let range in param) {
|
|
3
3
|
let [from, to] = range.split('~');
|
|
4
4
|
let from_defined = !!from;
|
|
@@ -6,14 +6,12 @@ export function getVaueOnRanges(value, param) {
|
|
|
6
6
|
from = parseFloat(from);
|
|
7
7
|
to = parseFloat(to);
|
|
8
8
|
value = Number(value) || 0;
|
|
9
|
-
// from이나 to 둘 중 하나만 있는 경우 먼저 계산
|
|
10
9
|
if (from_defined && !to_defined && value >= from) {
|
|
11
10
|
return param[range];
|
|
12
11
|
}
|
|
13
|
-
else if (!from_defined && to_defined && value <
|
|
12
|
+
else if (!from_defined && to_defined && value < to) {
|
|
14
13
|
return param[range];
|
|
15
14
|
}
|
|
16
|
-
// 소수점이 있으므로 from <= value < to 가 되야함
|
|
17
15
|
if (value >= from && value < to) {
|
|
18
16
|
return param[range];
|
|
19
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-value-on-ranges.js","sourceRoot":"","sources":["../../src/utils/get-value-on-ranges.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"get-value-on-ranges.js","sourceRoot":"","sources":["../../src/utils/get-value-on-ranges.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAAC,KAAK,EAAE,KAAK;IAC3C,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,GAAwB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACtD,IAAI,YAAY,GAAG,CAAC,CAAC,IAAI,CAAA;QACzB,IAAI,UAAU,GAAG,CAAC,CAAC,EAAE,CAAA;QAErB,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;QACvB,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC,CAAA;QACnB,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAE1B,IAAI,YAAY,IAAI,CAAC,UAAU,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YACjD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;aAAM,IAAI,CAAC,YAAY,IAAI,UAAU,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YACrD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;QAED,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,SAAS,CAAC,CAAA;AACzB,CAAC","sourcesContent":["export function getValueOnRanges(value, param): any {\n for (let range in param) {\n let [from, to]: (number | string)[] = range.split('~')\n let from_defined = !!from\n let to_defined = !!to\n\n from = parseFloat(from)\n to = parseFloat(to)\n value = Number(value) || 0\n\n if (from_defined && !to_defined && value >= from) {\n return param[range]\n } else if (!from_defined && to_defined && value < to) {\n return param[range]\n }\n\n if (value >= from && value < to) {\n return param[range]\n }\n }\n\n return param['default']\n}\n"]}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* 스토커 게이지 세그먼트 계산 (2D/3D 공통 단일 소스).
|
|
3
|
+
*
|
|
4
|
+
* 2D(StockerCapacityBar) 와 3D(machine-3d buildGauge) 가 각자 세그먼트 비율/색상을
|
|
5
|
+
* 중복 계산하면 필드/색상 drift 가 발생한다(실제로 carrier 필드명이 어긋난 전례).
|
|
6
|
+
* 이 모듈이 carrier/abnormal 세그먼트 계산의 단일 소스이며 순수 함수라 단위 테스트가
|
|
7
|
+
* 용이하다. 표현(라벨 포맷·watermark·테두리색)은 렌더러별로 다르므로 여기서 다루지 않는다.
|
|
8
|
+
*
|
|
9
|
+
* canonical 데이터 필드(2D 기준):
|
|
10
|
+
* - carrier : CARRIER_FULL / CARRIER_EMPTY / CARRIER_EMPTY_EMPTY
|
|
11
|
+
* - abnormal : CARRIER_NORMAL / CARRIER_ABNORMAL
|
|
12
|
+
*/
|
|
13
|
+
/** carrier 세그먼트 색상 (2D/3D 공통). LEGEND_CARRIER 기본값과 동일 — 테마 미지정 시 폴백. */
|
|
14
|
+
export const CARRIER_COLORS = {
|
|
15
|
+
full: '#4AA7FE',
|
|
16
|
+
empty: '#8BDA5B',
|
|
17
|
+
emptyEmpty: '#019D59'
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* carrier legend(테마)에서 full/empty/emptyEmpty 색상 추출.
|
|
21
|
+
* carrier 컴포넌트의 색 취득 로직(statusColor = legend[status] || legend.default)과 동일하게,
|
|
22
|
+
* status 키(FULL/EMPTY/EMPTYEMPTY)로 직접 조회한다. 키/default 모두 없으면 CARRIER_COLORS 로 폴백.
|
|
23
|
+
*/
|
|
24
|
+
export function carrierColorsFromLegend(legend) {
|
|
25
|
+
const pick = (key, fallback) => (legend && (legend[key] || legend.default)) || fallback;
|
|
26
|
+
return {
|
|
27
|
+
full: pick('FULL', CARRIER_COLORS.full),
|
|
28
|
+
empty: pick('EMPTY', CARRIER_COLORS.empty),
|
|
29
|
+
emptyEmpty: pick('EMPTYEMPTY', CARRIER_COLORS.emptyEmpty)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** abnormal 세그먼트 색상 (2D/3D 공통). */
|
|
33
|
+
export const ABNORMAL_COLORS = {
|
|
34
|
+
normal: '#8BDA5B',
|
|
35
|
+
abnormal: '#F4B4B4'
|
|
36
|
+
};
|
|
37
|
+
function num(v) {
|
|
38
|
+
const n = Number(v);
|
|
39
|
+
return Number.isFinite(n) && n > 0 ? n : 0;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 캐리어 상태 세그먼트 (Full / Empty / EmptyEmpty). total 0 이면 모든 ratio 0.
|
|
43
|
+
* colors 미지정 시 CARRIER_COLORS(기본). 테마 색은 carrierColorsFromLegend 로 만들어 전달.
|
|
44
|
+
*/
|
|
45
|
+
export function carrierSegments(full, empty, emptyEmpty, colors = CARRIER_COLORS) {
|
|
46
|
+
const f = num(full);
|
|
47
|
+
const e = num(empty);
|
|
48
|
+
const ee = num(emptyEmpty);
|
|
49
|
+
const total = f + e + ee;
|
|
50
|
+
const r = (c) => (total > 0 ? c / total : 0);
|
|
51
|
+
return [
|
|
52
|
+
{ label: 'Full', count: f, ratio: r(f), color: colors.full },
|
|
53
|
+
{ label: 'Empty', count: e, ratio: r(e), color: colors.empty },
|
|
54
|
+
{ label: 'Empty\nEmpty', count: ee, ratio: r(ee), color: colors.emptyEmpty }
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
/** 캐리어 정상/비정상 세그먼트 (Normal / Abnormal). total 0 이면 모든 ratio 0. */
|
|
58
|
+
export function abnormalSegments(normal, abnormal) {
|
|
59
|
+
const n = num(normal);
|
|
60
|
+
const a = num(abnormal);
|
|
61
|
+
const total = n + a;
|
|
62
|
+
const r = (c) => (total > 0 ? c / total : 0);
|
|
63
|
+
return [
|
|
64
|
+
{ label: 'Normal', count: n, ratio: r(n), color: ABNORMAL_COLORS.normal },
|
|
65
|
+
{ label: 'Abnormal', count: a, ratio: r(a), color: ABNORMAL_COLORS.abnormal }
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
/** 캐리어 세그먼트 — canonical raw data(CARRIER_*) 에서 직접. 3D 처럼 raw data 소스용. */
|
|
69
|
+
export function carrierSegmentsFromData(data, colors) {
|
|
70
|
+
const d = data && typeof data === 'object' ? data : {};
|
|
71
|
+
return carrierSegments(d.CARRIER_FULL, d.CARRIER_EMPTY, d.CARRIER_EMPTY_EMPTY, colors);
|
|
72
|
+
}
|
|
73
|
+
/** 비정상 세그먼트 — canonical raw data(CARRIER_*) 에서 직접. */
|
|
74
|
+
export function abnormalSegmentsFromData(data) {
|
|
75
|
+
const d = data && typeof data === 'object' ? data : {};
|
|
76
|
+
return abnormalSegments(d.CARRIER_NORMAL, d.CARRIER_ABNORMAL);
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=stocker-gauge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stocker-gauge.js","sourceRoot":"","sources":["../../src/utils/stocker-gauge.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * 스토커 게이지 세그먼트 계산 (2D/3D 공통 단일 소스).\n *\n * 2D(StockerCapacityBar) 와 3D(machine-3d buildGauge) 가 각자 세그먼트 비율/색상을\n * 중복 계산하면 필드/색상 drift 가 발생한다(실제로 carrier 필드명이 어긋난 전례).\n * 이 모듈이 carrier/abnormal 세그먼트 계산의 단일 소스이며 순수 함수라 단위 테스트가\n * 용이하다. 표현(라벨 포맷·watermark·테두리색)은 렌더러별로 다르므로 여기서 다루지 않는다.\n *\n * canonical 데이터 필드(2D 기준):\n * - carrier : CARRIER_FULL / CARRIER_EMPTY / CARRIER_EMPTY_EMPTY\n * - abnormal : CARRIER_NORMAL / CARRIER_ABNORMAL\n */\n\nimport { Legend } from '../features/mcs-status-default'\n\nexport type StockerGaugeMode = 'capacity' | 'carrier' | 'abnormal'\n\nexport interface GaugeSegment {\n /** 세그먼트 라벨(2D per-segment 표시용, '\\n' 은 줄바꿈). */\n label: string\n /** 카운트 원본값. */\n count: number\n /** 전체 대비 비율 (0~1). total 이 0 이면 0. */\n ratio: number\n /** 채움 색상. */\n color: string\n}\n\n/** carrier 세그먼트 색상 (2D/3D 공통). LEGEND_CARRIER 기본값과 동일 — 테마 미지정 시 폴백. */\nexport const CARRIER_COLORS = {\n full: '#4AA7FE',\n empty: '#8BDA5B',\n emptyEmpty: '#019D59'\n}\n\nexport interface CarrierColors {\n full: string\n empty: string\n emptyEmpty: string\n}\n\n/**\n * carrier legend(테마)에서 full/empty/emptyEmpty 색상 추출.\n * carrier 컴포넌트의 색 취득 로직(statusColor = legend[status] || legend.default)과 동일하게,\n * status 키(FULL/EMPTY/EMPTYEMPTY)로 직접 조회한다. 키/default 모두 없으면 CARRIER_COLORS 로 폴백.\n */\nexport function carrierColorsFromLegend(legend?: Legend): CarrierColors {\n const pick = (key: string, fallback: string) => (legend && (legend[key] || legend.default)) || fallback\n return {\n full: pick('FULL', CARRIER_COLORS.full),\n empty: pick('EMPTY', CARRIER_COLORS.empty),\n emptyEmpty: pick('EMPTYEMPTY', CARRIER_COLORS.emptyEmpty)\n }\n}\n\n/** abnormal 세그먼트 색상 (2D/3D 공통). */\nexport const ABNORMAL_COLORS = {\n normal: '#8BDA5B',\n abnormal: '#F4B4B4'\n}\n\nfunction num(v: unknown): number {\n const n = Number(v)\n return Number.isFinite(n) && n > 0 ? n : 0\n}\n\n/**\n * 캐리어 상태 세그먼트 (Full / Empty / EmptyEmpty). total 0 이면 모든 ratio 0.\n * colors 미지정 시 CARRIER_COLORS(기본). 테마 색은 carrierColorsFromLegend 로 만들어 전달.\n */\nexport function carrierSegments(\n full: unknown,\n empty: unknown,\n emptyEmpty: unknown,\n colors: CarrierColors = CARRIER_COLORS\n): GaugeSegment[] {\n const f = num(full)\n const e = num(empty)\n const ee = num(emptyEmpty)\n const total = f + e + ee\n const r = (c: number) => (total > 0 ? c / total : 0)\n return [\n { label: 'Full', count: f, ratio: r(f), color: colors.full },\n { label: 'Empty', count: e, ratio: r(e), color: colors.empty },\n { label: 'Empty\\nEmpty', count: ee, ratio: r(ee), color: colors.emptyEmpty }\n ]\n}\n\n/** 캐리어 정상/비정상 세그먼트 (Normal / Abnormal). total 0 이면 모든 ratio 0. */\nexport function abnormalSegments(normal: unknown, abnormal: unknown): GaugeSegment[] {\n const n = num(normal)\n const a = num(abnormal)\n const total = n + a\n const r = (c: number) => (total > 0 ? c / total : 0)\n return [\n { label: 'Normal', count: n, ratio: r(n), color: ABNORMAL_COLORS.normal },\n { label: 'Abnormal', count: a, ratio: r(a), color: ABNORMAL_COLORS.abnormal }\n ]\n}\n\n/** 캐리어 세그먼트 — canonical raw data(CARRIER_*) 에서 직접. 3D 처럼 raw data 소스용. */\nexport function carrierSegmentsFromData(data: any, colors?: CarrierColors): GaugeSegment[] {\n const d = data && typeof data === 'object' ? data : {}\n return carrierSegments(d.CARRIER_FULL, d.CARRIER_EMPTY, d.CARRIER_EMPTY_EMPTY, colors)\n}\n\n/** 비정상 세그먼트 — canonical raw data(CARRIER_*) 에서 직접. */\nexport function abnormalSegmentsFromData(data: any): GaugeSegment[] {\n const d = data && typeof data === 'object' ? data : {}\n return abnormalSegments(d.CARRIER_NORMAL, d.CARRIER_ABNORMAL)\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import { sceneComponent } from '@hatiolab/things-scene';
|
|
|
3
3
|
import { themesColorRange } from '@fmsim/api';
|
|
4
4
|
import { LEGEND_CAPACITY } from './features/mcs-status-default';
|
|
5
5
|
import { safeRound } from './utils/safe-round';
|
|
6
|
-
import {
|
|
6
|
+
import { getValueOnRanges } from './utils/get-value-on-ranges';
|
|
7
7
|
import { MCSZoneMixin, MCSZoneMixinProperties } from './features/mcs-zone-mixin';
|
|
8
8
|
import { ParentObjectMixinProperties } from './features/parent-object-mixin';
|
|
9
9
|
import MCSUnit from './mcs-unit';
|
|
@@ -94,7 +94,7 @@ let ZoneCapacityBar = class ZoneCapacityBar extends MCSZoneMixin(MCSUnit) {
|
|
|
94
94
|
}
|
|
95
95
|
get statusColor() {
|
|
96
96
|
const { fullup } = this.state;
|
|
97
|
-
return fullup ? 'red' :
|
|
97
|
+
return fullup ? 'red' : getValueOnRanges(this.usage, this.legend);
|
|
98
98
|
}
|
|
99
99
|
get text() {
|
|
100
100
|
return this.usage + '%';
|
|
@@ -215,7 +215,7 @@ let ZoneCapacityBar = class ZoneCapacityBar extends MCSZoneMixin(MCSUnit) {
|
|
|
215
215
|
// intentionally have done nothing
|
|
216
216
|
}
|
|
217
217
|
onchangeData(after, before) {
|
|
218
|
-
const { CURRENTCAPACITY = 0, MAXCAPACITY = 100, HIGHWATERMARK = 100, LOWWATERMARK = 0, FULLUP = 'F' } = typeof this.data == 'object' ? this.data : {};
|
|
218
|
+
const { CURRENTCAPACITY = 0, MAXCAPACITY = 100, HIGHWATERMARK = 100, LOWWATERMARK = 0, FULLUP = 'F' } = this.data && typeof this.data == 'object' ? this.data : {};
|
|
219
219
|
const currentUsage = Number(CURRENTCAPACITY) || 0;
|
|
220
220
|
const maxCapacity = Number(MAXCAPACITY) || 100;
|
|
221
221
|
const highWatermark = Number(HIGHWATERMARK) || 100;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zone-capacity-bar.js","sourceRoot":"","sources":["../src/zone-capacity-bar.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ComponentNature, POSITION, Properties, sceneComponent } from '@hatiolab/things-scene'\nimport { themesColorRange } from '@fmsim/api'\nimport { LEGEND_CAPACITY } from './features/mcs-status-default'\nimport { safeRound } from './utils/safe-round'\nimport { getVaueOnRanges } from './utils/get-value-on-ranges'\nimport { MCSZoneMixin, MCSZoneMixinProperties } from './features/mcs-zone-mixin'\nimport { ParentObjectMixinProperties } from './features/parent-object-mixin'\nimport MCSUnit from './mcs-unit'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n ...MCSZoneMixinProperties,\n ...ParentObjectMixinProperties,\n {\n type: 'select',\n label: 'legend-name',\n name: 'legendName',\n property: {\n options: themesColorRange\n }\n },\n {\n type: 'number',\n name: 'currentUsage',\n label: 'current-usage'\n },\n {\n type: 'number',\n name: 'highWatermark',\n label: 'high-watermark'\n },\n {\n type: 'number',\n name: 'lowWatermark',\n label: 'low-watermark'\n },\n {\n type: 'number',\n name: 'maxCapacity',\n label: 'max-capacity'\n },\n {\n type: 'boolean',\n name: 'fullup',\n label: 'fullup'\n },\n {\n type: 'number',\n label: 'round',\n name: 'round',\n property: {\n min: 0\n }\n },\n {\n type: 'hidden',\n name: 'usage',\n label: 'usage'\n }\n ],\n 'value-property': 'usage'\n}\n\nvar controlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { left, top, width, height } = component.model\n\n var transcoorded = component.transcoordP2S(point.x, point.y)\n var round = ((transcoorded.x - left) / (width / 2)) * 100\n\n round = safeRound(round, width, height)\n\n component.set({\n round\n })\n }\n}\n\n@sceneComponent('ZoneCapacityBar')\nexport default class ZoneCapacityBar extends MCSZoneMixin(MCSUnit) {\n static get nature() {\n return NATURE\n }\n\n get controls() {\n var { left, top, width, round, height } = this.state\n round = round == undefined ? 0 : safeRound(round, width, height)\n\n return [\n {\n x: left + (width / 2) * (round / 100),\n y: top,\n handler: controlHandler\n }\n ]\n }\n\n getLegendFallback() {\n return (this.root as any).zoneCapacityLegendTheme || LEGEND_CAPACITY\n }\n\n get statusColor() {\n const { fullup } = this.state\n return fullup ? 'red' : getVaueOnRanges(this.usage, this.legend)\n }\n\n get text() {\n return this.usage + '%'\n }\n\n render(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n\n if (width >= height) {\n this.renderLandscape(context)\n } else {\n this.renderPortrait(context)\n }\n }\n\n renderLandscape(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n const { highWatermark, lowWatermark, lineWidth, strokeStyle, round, fillStyle = 'white' } = this.state\n\n context.save()\n context.translate(left, top)\n\n // gauge background\n context.beginPath()\n\n context.fillStyle = fillStyle\n context.roundRect(0, 0, width, height, round)\n\n context.fill()\n context.stroke()\n\n context.clip()\n\n // gauge foreground\n context.beginPath()\n\n context.fillStyle = this.statusColor!\n\n context.rect(0, 0, (width / 100) * this.usage, height)\n context.fill()\n\n // high-watermark level\n\n if (highWatermark && highWatermark > 0 && highWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const x = (width / 100) * highWatermark\n context.moveTo(x, 0)\n context.lineTo(x, height)\n\n context.stroke()\n }\n\n // low-watermark level\n\n if (lowWatermark && lowWatermark > 0 && lowWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const x = (width / 100) * lowWatermark\n context.moveTo(x, 0)\n context.lineTo(x, height)\n\n context.stroke()\n }\n\n // gauge outline\n context.beginPath()\n\n context.setLineDash([])\n context.strokeStyle = strokeStyle\n context.lineWidth = lineWidth\n context.roundRect(0, 0, width, height, round)\n context.stroke()\n\n context.beginPath()\n\n context.translate(-left, -top)\n context.restore()\n }\n\n renderPortrait(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n const { highWatermark, lowWatermark, lineWidth, strokeStyle, round, fillStyle = 'white' } = this.state\n\n context.save()\n context.translate(left, top)\n\n // gauge background\n context.beginPath()\n\n context.fillStyle = fillStyle\n context.roundRect(0, 0, width, height, round)\n\n context.fill()\n\n context.clip()\n\n // gauge foreground\n context.beginPath()\n\n context.fillStyle = this.statusColor!\n\n context.rect(0, height - (height / 100) * this.usage, width, (height / 100) * this.usage)\n context.fill()\n\n // high-watermark level\n\n if (highWatermark && highWatermark > 0 && highWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const y = height - (height / 100) * highWatermark\n context.moveTo(0, y)\n context.lineTo(width, y)\n\n context.stroke()\n }\n\n // low-watermark level\n\n if (lowWatermark && lowWatermark > 0 && lowWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const y = height - (height / 100) * lowWatermark\n context.moveTo(0, y)\n context.lineTo(width, y)\n\n context.stroke()\n }\n\n // gauge outline\n context.beginPath()\n\n context.setLineDash([])\n context.strokeStyle = strokeStyle\n context.lineWidth = lineWidth\n context.roundRect(0, 0, width, height, round)\n context.stroke()\n\n context.beginPath()\n\n context.translate(-left, -top)\n context.restore()\n }\n\n get usage() {\n const { currentUsage = 0, maxCapacity = 100 } = this.state\n return Math.round((currentUsage / maxCapacity) * 100)\n }\n\n set usage(usage: number) {\n // intentionally have done nothing\n }\n\n onchangeData(after: Record<string, any>, before: Record<string, any>): void {\n const {\n CURRENTCAPACITY = 0,\n MAXCAPACITY = 100,\n HIGHWATERMARK = 100,\n LOWWATERMARK = 0,\n FULLUP = 'F'\n } = typeof this.data == 'object' ? this.data : {}\n\n const currentUsage = Number(CURRENTCAPACITY) || 0\n const maxCapacity = Number(MAXCAPACITY) || 100\n const highWatermark = Number(HIGHWATERMARK) || 100\n const lowWatermark = Number(LOWWATERMARK) || 0\n\n this.setState({\n currentUsage,\n maxCapacity,\n highWatermark,\n lowWatermark,\n fullup: FULLUP == 'T',\n usage: Math.round((currentUsage / maxCapacity) * 100)\n })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"zone-capacity-bar.js","sourceRoot":"","sources":["../src/zone-capacity-bar.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ComponentNature, POSITION, Properties, sceneComponent } from '@hatiolab/things-scene'\nimport { themesColorRange } from '@fmsim/api'\nimport { LEGEND_CAPACITY } from './features/mcs-status-default'\nimport { safeRound } from './utils/safe-round'\nimport { getValueOnRanges } from './utils/get-value-on-ranges'\nimport { MCSZoneMixin, MCSZoneMixinProperties } from './features/mcs-zone-mixin'\nimport { ParentObjectMixinProperties } from './features/parent-object-mixin'\nimport MCSUnit from './mcs-unit'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n ...MCSZoneMixinProperties,\n ...ParentObjectMixinProperties,\n {\n type: 'select',\n label: 'legend-name',\n name: 'legendName',\n property: {\n options: themesColorRange\n }\n },\n {\n type: 'number',\n name: 'currentUsage',\n label: 'current-usage'\n },\n {\n type: 'number',\n name: 'highWatermark',\n label: 'high-watermark'\n },\n {\n type: 'number',\n name: 'lowWatermark',\n label: 'low-watermark'\n },\n {\n type: 'number',\n name: 'maxCapacity',\n label: 'max-capacity'\n },\n {\n type: 'boolean',\n name: 'fullup',\n label: 'fullup'\n },\n {\n type: 'number',\n label: 'round',\n name: 'round',\n property: {\n min: 0\n }\n },\n {\n type: 'hidden',\n name: 'usage',\n label: 'usage'\n }\n ],\n 'value-property': 'usage'\n}\n\nvar controlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { left, top, width, height } = component.model\n\n var transcoorded = component.transcoordP2S(point.x, point.y)\n var round = ((transcoorded.x - left) / (width / 2)) * 100\n\n round = safeRound(round, width, height)\n\n component.set({\n round\n })\n }\n}\n\n@sceneComponent('ZoneCapacityBar')\nexport default class ZoneCapacityBar extends MCSZoneMixin(MCSUnit) {\n static get nature() {\n return NATURE\n }\n\n get controls() {\n var { left, top, width, round, height } = this.state\n round = round == undefined ? 0 : safeRound(round, width, height)\n\n return [\n {\n x: left + (width / 2) * (round / 100),\n y: top,\n handler: controlHandler\n }\n ]\n }\n\n getLegendFallback() {\n return (this.root as any).zoneCapacityLegendTheme || LEGEND_CAPACITY\n }\n\n get statusColor() {\n const { fullup } = this.state\n return fullup ? 'red' : getValueOnRanges(this.usage, this.legend)\n }\n\n get text() {\n return this.usage + '%'\n }\n\n render(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n\n if (width >= height) {\n this.renderLandscape(context)\n } else {\n this.renderPortrait(context)\n }\n }\n\n renderLandscape(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n const { highWatermark, lowWatermark, lineWidth, strokeStyle, round, fillStyle = 'white' } = this.state\n\n context.save()\n context.translate(left, top)\n\n // gauge background\n context.beginPath()\n\n context.fillStyle = fillStyle\n context.roundRect(0, 0, width, height, round)\n\n context.fill()\n context.stroke()\n\n context.clip()\n\n // gauge foreground\n context.beginPath()\n\n context.fillStyle = this.statusColor!\n\n context.rect(0, 0, (width / 100) * this.usage, height)\n context.fill()\n\n // high-watermark level\n\n if (highWatermark && highWatermark > 0 && highWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const x = (width / 100) * highWatermark\n context.moveTo(x, 0)\n context.lineTo(x, height)\n\n context.stroke()\n }\n\n // low-watermark level\n\n if (lowWatermark && lowWatermark > 0 && lowWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const x = (width / 100) * lowWatermark\n context.moveTo(x, 0)\n context.lineTo(x, height)\n\n context.stroke()\n }\n\n // gauge outline\n context.beginPath()\n\n context.setLineDash([])\n context.strokeStyle = strokeStyle\n context.lineWidth = lineWidth\n context.roundRect(0, 0, width, height, round)\n context.stroke()\n\n context.beginPath()\n\n context.translate(-left, -top)\n context.restore()\n }\n\n renderPortrait(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n const { highWatermark, lowWatermark, lineWidth, strokeStyle, round, fillStyle = 'white' } = this.state\n\n context.save()\n context.translate(left, top)\n\n // gauge background\n context.beginPath()\n\n context.fillStyle = fillStyle\n context.roundRect(0, 0, width, height, round)\n\n context.fill()\n\n context.clip()\n\n // gauge foreground\n context.beginPath()\n\n context.fillStyle = this.statusColor!\n\n context.rect(0, height - (height / 100) * this.usage, width, (height / 100) * this.usage)\n context.fill()\n\n // high-watermark level\n\n if (highWatermark && highWatermark > 0 && highWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const y = height - (height / 100) * highWatermark\n context.moveTo(0, y)\n context.lineTo(width, y)\n\n context.stroke()\n }\n\n // low-watermark level\n\n if (lowWatermark && lowWatermark > 0 && lowWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const y = height - (height / 100) * lowWatermark\n context.moveTo(0, y)\n context.lineTo(width, y)\n\n context.stroke()\n }\n\n // gauge outline\n context.beginPath()\n\n context.setLineDash([])\n context.strokeStyle = strokeStyle\n context.lineWidth = lineWidth\n context.roundRect(0, 0, width, height, round)\n context.stroke()\n\n context.beginPath()\n\n context.translate(-left, -top)\n context.restore()\n }\n\n get usage() {\n const { currentUsage = 0, maxCapacity = 100 } = this.state\n return Math.round((currentUsage / maxCapacity) * 100)\n }\n\n set usage(usage: number) {\n // intentionally have done nothing\n }\n\n onchangeData(after: Record<string, any>, before: Record<string, any>): void {\n const {\n CURRENTCAPACITY = 0,\n MAXCAPACITY = 100,\n HIGHWATERMARK = 100,\n LOWWATERMARK = 0,\n FULLUP = 'F'\n } = this.data && typeof this.data == 'object' ? this.data : {}\n\n const currentUsage = Number(CURRENTCAPACITY) || 0\n const maxCapacity = Number(MAXCAPACITY) || 100\n const highWatermark = Number(HIGHWATERMARK) || 100\n const lowWatermark = Number(LOWWATERMARK) || 0\n\n this.setState({\n currentUsage,\n maxCapacity,\n highWatermark,\n lowWatermark,\n fullup: FULLUP == 'T',\n usage: Math.round((currentUsage / maxCapacity) * 100)\n })\n }\n}\n"]}
|
|
Binary file
|
package/icons/decal.png
ADDED
|
Binary file
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
rootDir: '../../',
|
|
3
|
+
roots: ['<rootDir>/packages/machine'],
|
|
4
|
+
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
|
5
|
+
transform: {
|
|
6
|
+
'^.+\\.tsx?$': 'babel-jest'
|
|
7
|
+
},
|
|
8
|
+
testRegex: 'packages/machine/.*\\.test\\.tsx?$',
|
|
9
|
+
testEnvironment: 'node'
|
|
10
|
+
}
|
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": "2.0.0-beta.
|
|
5
|
+
"version": "2.0.0-beta.100",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
8
8
|
"things-scene": true,
|
|
@@ -22,10 +22,11 @@
|
|
|
22
22
|
"prepublish": "tsc; exit 0",
|
|
23
23
|
"lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
|
|
24
24
|
"format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore",
|
|
25
|
+
"test": "jest --config jest.config.js",
|
|
25
26
|
"migration": "things-factory-migration"
|
|
26
27
|
},
|
|
27
28
|
"dependencies": {
|
|
28
|
-
"@fmsim/api": "^2.0.0-beta.
|
|
29
|
+
"@fmsim/api": "^2.0.0-beta.99",
|
|
29
30
|
"@hatiolab/things-scene": "^10.0.0-beta.1"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
@@ -54,5 +55,5 @@
|
|
|
54
55
|
"prettier --write"
|
|
55
56
|
]
|
|
56
57
|
},
|
|
57
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "332f5d01766a2621d1dc9ca745aa764acfd9c960"
|
|
58
59
|
}
|
package/src/agv.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ComponentNature, sceneComponent } from '@hatiolab/things-scene'
|
|
2
2
|
import { themesColorRange } from '@fmsim/api'
|
|
3
3
|
import MCSVehicle from './mcs-vehicle'
|
|
4
|
-
import {
|
|
4
|
+
import { getValueOnRanges } from './utils/get-value-on-ranges'
|
|
5
5
|
import { BATTERY_RATE_LEGEND } from './features/mcs-status-default'
|
|
6
6
|
|
|
7
7
|
const NATURE: ComponentNature = {
|
|
@@ -33,6 +33,11 @@ export default class AGV extends MCSVehicle {
|
|
|
33
33
|
return 'black'
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/** AGV 의 parentObject 는 AGVLine. */
|
|
37
|
+
get parentObjectTypes(): string[] {
|
|
38
|
+
return ['AGVLine']
|
|
39
|
+
}
|
|
40
|
+
|
|
36
41
|
getLegendFallback() {
|
|
37
42
|
return (this.root as any).agvLegendTheme || super.getLegendFallback()
|
|
38
43
|
}
|
|
@@ -50,7 +55,7 @@ export default class AGV extends MCSVehicle {
|
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
getBatteryColor(rate: number) {
|
|
53
|
-
return
|
|
58
|
+
return getValueOnRanges(rate, this.getBatteryLegendTheme() || this.getBatteryLegendFallback())
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
render(ctx: CanvasRenderingContext2D) {
|