@fmsim/machine 1.0.41 → 1.0.43

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 CHANGED
@@ -14,6 +14,9 @@ export default class Carrier extends MCSStatusMixin(Shape) {
14
14
  return NATURE;
15
15
  }
16
16
  get path() {
17
+ if (!this.parent) {
18
+ return [];
19
+ }
17
20
  const { left, top, width, height } = this.calculateShrunkRectangle(this.parent.bounds);
18
21
  return [
19
22
  { x: left, y: top },
@@ -1 +1 @@
1
- {"version":3,"file":"carrier.js","sourceRoot":"","sources":["../src/carrier.ts"],"names":[],"mappings":"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","sourcesContent":["import JSON5 from 'json5'\nimport { getPopupData } from '@fmsim/api'\n\nimport { BOUNDS, Component, ComponentNature, Properties, Shape } from '@hatiolab/things-scene'\nimport { ANIMATION_DEFAULT, AnimationPreset, AnimationConfig } from './features/animation-default.js'\nimport { LEGEND_CARRIER, Legend } from './features/mcs-status-default.js'\nimport { MCSStatusMixin } from './features/mcs-status-mixin.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: false,\n rotatable: false\n}\n\nexport default class Carrier extends MCSStatusMixin(Shape) {\n static get nature() {\n return NATURE\n }\n\n get path() {\n const { left, top, width, height } = this.calculateShrunkRectangle(this.parent.bounds)\n\n return [\n { x: left, y: top },\n { x: left + width / 2, y: top },\n { x: left + width, y: top + height / 2 },\n { x: left + width, y: top + height },\n { x: left, y: top + height }\n ]\n }\n\n set path(path) {}\n\n onchangeData(after: Properties, before: Properties): void {\n const { CARRIERNAME, CARRIERTYPE = '', EMPTYTYPE, CARRIERSTATUS } = this.data || {}\n\n this.setState('id', CARRIERNAME)\n this.setState('EMPTYTYPE', EMPTYTYPE)\n this.setState('CARRIERTYPE', CARRIERTYPE)\n this.setState('CARRIERSTATUS', CARRIERSTATUS)\n\n // TODO carrierstatus에 따라서 매핑되는 애니메이션 테마 수행\n if (after.data.CARRIERSTATUS !== before.data?.CARRIERSTATUS) {\n const { CARRIERSTATUS: lastCarrierStatus } = before.data || {}\n const lastAnimationConfig = lastCarrierStatus && this.getAnimationConfig(lastCarrierStatus)\n\n if (lastAnimationConfig) {\n let { animation, decorator, border, arrow } = lastAnimationConfig\n if (animation) {\n this.resetAnimation()\n this.setState('animation', {\n oncreate: null\n })\n }\n\n if (decorator || border || arrow) {\n this.trigger('animatoroff')\n }\n }\n\n const animationConfig = this.getAnimationConfig(this.getState('CARRIERSTATUS'))\n\n if (animationConfig) {\n let { animation, decorator, border, arrow } = animationConfig\n if (animation) {\n this.resetAnimation()\n this.setState('animation', {\n oncreate: animation\n })\n this.started = true\n }\n\n if (decorator) {\n this.trigger('animatoroff')\n this.trigger('icon', decorator)\n }\n\n if (border) {\n this.trigger('animatoroff')\n this.trigger('border', border)\n }\n\n if (arrow) {\n this.trigger('animatoroff')\n this.trigger('bouncing', arrow)\n }\n }\n }\n }\n\n get status() {\n return this.getState('EMPTYTYPE')\n }\n\n get legend(): Legend {\n const { carrierLegendName } = this.parent?.state || {}\n\n if (carrierLegendName) {\n return this.root?.style[carrierLegendName]\n }\n\n return this.root?.carrierLegendTheme || LEGEND_CARRIER\n }\n\n getAnimationConfig(carrierStatus): AnimationConfig | null {\n const config = this.animationPreset[carrierStatus || 'default']\n\n if (config && typeof config == 'string') {\n try {\n return JSON5.parse(config)\n } catch (e) {\n console.error(e)\n }\n } else {\n return (config as AnimationConfig) || null\n }\n\n return null\n }\n\n get animationPreset(): AnimationPreset {\n const { carrierAnimationName } = this.parent?.state || {}\n\n if (carrierAnimationName) {\n return this.root?.style[carrierAnimationName] || this.root?.state.carrierAnimationTheme || ANIMATION_DEFAULT\n }\n\n return ANIMATION_DEFAULT\n }\n\n get hasTextProperty() {\n return this.getState('showText') || false\n }\n\n calculateShrunkRectangle(originalRect: BOUNDS): BOUNDS {\n const shrunkRect: BOUNDS = { ...originalRect }\n\n shrunkRect.left = originalRect.width * 0.1\n shrunkRect.width *= 0.8\n\n shrunkRect.top = originalRect.height * 0.1\n shrunkRect.height *= 0.8\n\n return shrunkRect\n }\n\n contains(x, y) {\n const EMPTYTYPE = this.getState('EMPTYTYPE')\n\n if (!EMPTYTYPE) {\n return false\n }\n\n const rect = this.bounds\n x -= rect.left\n y -= rect.top\n\n if (x < 0 || y < 0 || x > rect.width || y > rect.height) {\n return false\n }\n\n // 윗변 중앙 좌표\n const topCenterX = rect.width / 2\n const topCenterY = 0\n\n // 오른쪽 변 중앙 좌표\n const rightCenterX = rect.width\n const rightCenterY = rect.height / 2\n\n // 기울기 m = (y2 - y1) / (x2 - x1)\n const m = (rightCenterY - topCenterY) / (rightCenterX - topCenterX)\n\n // y 절편 b = y - mx\n const b = topCenterY - m * topCenterX\n\n // 점(px, py)이 선 아래(좌하부)에 있는지 확인\n return y > m * x + b\n }\n\n render(ctx: CanvasRenderingContext2D) {\n const { EMPTYTYPE, showText } = this.state\n\n if (!EMPTYTYPE) {\n return\n }\n\n const { width, height } = this.bounds\n const path = this.path\n const round = Math.round(Math.min(width, height) * 0.1)\n const lineWidth = round > 5 ? 1 : 0.5\n\n ctx.beginPath()\n ctx.moveTo(path[0].x, path[0].y)\n\n path.slice(1).forEach(({ x, y }) => {\n ctx.lineTo(x, y)\n })\n\n ctx.closePath()\n\n ctx.lineWidth = lineWidth\n ctx.fillStyle = this.statusColor || 'transparent'\n ctx.strokeStyle = this.auxColor || 'transparent'\n\n ctx.fill()\n ctx.stroke()\n\n if (showText) {\n const text = EMPTYTYPE == 'FULL' ? 'F' : EMPTYTYPE == 'EMPTY' ? 'E' : EMPTYTYPE == 'EMPTYEMPTY' ? 'X' : ''\n\n if (text) {\n const { x: cx, y: cy } = this.center\n\n ctx.fillStyle = 'black'\n ctx.font = `normal ${Math.round(round * 8)}px Arial`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n\n ctx.fillText(text, cx - width / 8, cy + height / 8)\n }\n }\n }\n\n async detailInfo() {\n const { type, id } = this.state\n\n if (!id) {\n return\n }\n\n return await getPopupData(type, id)\n }\n}\n\nComponent.register('Carrier', Carrier)\n"]}
1
+ {"version":3,"file":"carrier.js","sourceRoot":"","sources":["../src/carrier.ts"],"names":[],"mappings":"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","sourcesContent":["import JSON5 from 'json5'\nimport { getPopupData } from '@fmsim/api'\n\nimport { BOUNDS, Component, ComponentNature, Properties, Shape } from '@hatiolab/things-scene'\nimport { ANIMATION_DEFAULT, AnimationPreset, AnimationConfig } from './features/animation-default.js'\nimport { LEGEND_CARRIER, Legend } from './features/mcs-status-default.js'\nimport { MCSStatusMixin } from './features/mcs-status-mixin.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: false,\n rotatable: false\n}\n\nexport default class Carrier extends MCSStatusMixin(Shape) {\n static get nature() {\n return NATURE\n }\n\n get path() {\n if (!this.parent) {\n return []\n }\n\n const { left, top, width, height } = this.calculateShrunkRectangle(this.parent.bounds)\n\n return [\n { x: left, y: top },\n { x: left + width / 2, y: top },\n { x: left + width, y: top + height / 2 },\n { x: left + width, y: top + height },\n { x: left, y: top + height }\n ]\n }\n\n set path(path) {}\n\n onchangeData(after: Properties, before: Properties): void {\n const { CARRIERNAME, CARRIERTYPE = '', EMPTYTYPE, CARRIERSTATUS } = this.data || {}\n\n this.setState('id', CARRIERNAME)\n this.setState('EMPTYTYPE', EMPTYTYPE)\n this.setState('CARRIERTYPE', CARRIERTYPE)\n this.setState('CARRIERSTATUS', CARRIERSTATUS)\n\n // TODO carrierstatus에 따라서 매핑되는 애니메이션 테마 수행\n if (after.data.CARRIERSTATUS !== before.data?.CARRIERSTATUS) {\n const { CARRIERSTATUS: lastCarrierStatus } = before.data || {}\n const lastAnimationConfig = lastCarrierStatus && this.getAnimationConfig(lastCarrierStatus)\n\n if (lastAnimationConfig) {\n let { animation, decorator, border, arrow } = lastAnimationConfig\n if (animation) {\n this.resetAnimation()\n this.setState('animation', {\n oncreate: null\n })\n }\n\n if (decorator || border || arrow) {\n this.trigger('animatoroff')\n }\n }\n\n const animationConfig = this.getAnimationConfig(this.getState('CARRIERSTATUS'))\n\n if (animationConfig) {\n let { animation, decorator, border, arrow } = animationConfig\n if (animation) {\n this.resetAnimation()\n this.setState('animation', {\n oncreate: animation\n })\n this.started = true\n }\n\n if (decorator) {\n this.trigger('animatoroff')\n this.trigger('icon', decorator)\n }\n\n if (border) {\n this.trigger('animatoroff')\n this.trigger('border', border)\n }\n\n if (arrow) {\n this.trigger('animatoroff')\n this.trigger('bouncing', arrow)\n }\n }\n }\n }\n\n get status() {\n return this.getState('EMPTYTYPE')\n }\n\n get legend(): Legend {\n const { carrierLegendName } = this.parent?.state || {}\n\n if (carrierLegendName) {\n return this.root?.style[carrierLegendName]\n }\n\n return this.root?.carrierLegendTheme || LEGEND_CARRIER\n }\n\n getAnimationConfig(carrierStatus): AnimationConfig | null {\n const config = this.animationPreset[carrierStatus || 'default']\n\n if (config && typeof config == 'string') {\n try {\n return JSON5.parse(config)\n } catch (e) {\n console.error(e)\n }\n } else {\n return (config as AnimationConfig) || null\n }\n\n return null\n }\n\n get animationPreset(): AnimationPreset {\n const { carrierAnimationName } = this.parent?.state || {}\n\n if (carrierAnimationName) {\n return this.root?.style[carrierAnimationName] || this.root?.state.carrierAnimationTheme || ANIMATION_DEFAULT\n }\n\n return ANIMATION_DEFAULT\n }\n\n get hasTextProperty() {\n return this.getState('showText') || false\n }\n\n calculateShrunkRectangle(originalRect: BOUNDS): BOUNDS {\n const shrunkRect: BOUNDS = { ...originalRect }\n\n shrunkRect.left = originalRect.width * 0.1\n shrunkRect.width *= 0.8\n\n shrunkRect.top = originalRect.height * 0.1\n shrunkRect.height *= 0.8\n\n return shrunkRect\n }\n\n contains(x, y) {\n const EMPTYTYPE = this.getState('EMPTYTYPE')\n\n if (!EMPTYTYPE) {\n return false\n }\n\n const rect = this.bounds\n x -= rect.left\n y -= rect.top\n\n if (x < 0 || y < 0 || x > rect.width || y > rect.height) {\n return false\n }\n\n // 윗변 중앙 좌표\n const topCenterX = rect.width / 2\n const topCenterY = 0\n\n // 오른쪽 변 중앙 좌표\n const rightCenterX = rect.width\n const rightCenterY = rect.height / 2\n\n // 기울기 m = (y2 - y1) / (x2 - x1)\n const m = (rightCenterY - topCenterY) / (rightCenterX - topCenterX)\n\n // y 절편 b = y - mx\n const b = topCenterY - m * topCenterX\n\n // 점(px, py)이 선 아래(좌하부)에 있는지 확인\n return y > m * x + b\n }\n\n render(ctx: CanvasRenderingContext2D) {\n const { EMPTYTYPE, showText } = this.state\n\n if (!EMPTYTYPE) {\n return\n }\n\n const { width, height } = this.bounds\n const path = this.path\n const round = Math.round(Math.min(width, height) * 0.1)\n const lineWidth = round > 5 ? 1 : 0.5\n\n ctx.beginPath()\n ctx.moveTo(path[0].x, path[0].y)\n\n path.slice(1).forEach(({ x, y }) => {\n ctx.lineTo(x, y)\n })\n\n ctx.closePath()\n\n ctx.lineWidth = lineWidth\n ctx.fillStyle = this.statusColor || 'transparent'\n ctx.strokeStyle = this.auxColor || 'transparent'\n\n ctx.fill()\n ctx.stroke()\n\n if (showText) {\n const text = EMPTYTYPE == 'FULL' ? 'F' : EMPTYTYPE == 'EMPTY' ? 'E' : EMPTYTYPE == 'EMPTYEMPTY' ? 'X' : ''\n\n if (text) {\n const { x: cx, y: cy } = this.center\n\n ctx.fillStyle = 'black'\n ctx.font = `normal ${Math.round(round * 8)}px Arial`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n\n ctx.fillText(text, cx - width / 8, cy + height / 8)\n }\n }\n }\n\n async detailInfo() {\n const { type, id } = this.state\n\n if (!id) {\n return\n }\n\n return await getPopupData(type, id)\n }\n}\n\nComponent.register('Carrier', Carrier)\n"]}
@@ -1,2 +1,9 @@
1
- "use strict";
1
+ import './ox-input-nodes';
2
+ import './ox-property-editor-nodes';
3
+ export default [
4
+ {
5
+ type: 'nodes',
6
+ element: 'ox-property-editor-nodes'
7
+ }
8
+ ];
2
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/editors/index.ts"],"names":[],"mappings":"","sourcesContent":[""]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/editors/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAA;AACzB,OAAO,4BAA4B,CAAA;AAEnC,eAAe;IACb;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,0BAA0B;KACpC;CACF,CAAA","sourcesContent":["import './ox-input-nodes'\nimport './ox-property-editor-nodes'\n\nexport default [\n {\n type: 'nodes',\n element: 'ox-property-editor-nodes'\n }\n]\n"]}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+ import { __decorate, __metadata } from "tslib";
5
+ import '@material/web/icon/icon.js';
6
+ import { css, html } from 'lit';
7
+ import { customElement, state } from 'lit/decorators.js';
8
+ import { OxFormField } from '@operato/input';
9
+ let OxInputNodes = class OxInputNodes extends OxFormField {
10
+ constructor() {
11
+ super(...arguments);
12
+ this.value = [];
13
+ }
14
+ render() {
15
+ const nodes = this.value || [];
16
+ return html `
17
+ <fieldset>
18
+ <ul>
19
+ ${nodes.map(({ id, name }) => html `
20
+ <li @change=${this.onChange}>
21
+ <div data-id=${id}>${id}</div>
22
+ <input type="text" name="name" value=${name || ''} />
23
+ </li>
24
+ `)}
25
+ </ul>
26
+ </fieldset>
27
+ `;
28
+ }
29
+ onChange(e) {
30
+ e.stopPropagation();
31
+ const lis = this.renderRoot.querySelectorAll('li');
32
+ this.value = Array.from(lis).map(li => {
33
+ var _a, _b;
34
+ const id = (_a = li.querySelector('[data-id]')) === null || _a === void 0 ? void 0 : _a.getAttribute('data-id');
35
+ const name = (_b = li.querySelector('input')) === null || _b === void 0 ? void 0 : _b.value;
36
+ const node = this.value.find(node => node.id === id);
37
+ return Object.assign(Object.assign({}, node), { name });
38
+ });
39
+ this.dispatchEvent(new CustomEvent('change', {
40
+ bubbles: true,
41
+ composed: true,
42
+ detail: this.value
43
+ }));
44
+ }
45
+ };
46
+ OxInputNodes.styles = [
47
+ css `
48
+ :host {
49
+ display: flex;
50
+ --md-icon-size: 1.4em;
51
+ }
52
+
53
+ fieldset {
54
+ flex: 1;
55
+ font-size: 0.8em;
56
+ border: 0;
57
+ border-bottom: 1px solid;
58
+ background-color: var(--md-sys-color-surface-variant);
59
+ padding: var(--spacing-medium);
60
+ }
61
+
62
+ ul {
63
+ display: flex;
64
+ flex-direction: column;
65
+ gap: var(--spacing-small);
66
+
67
+ padding: 0;
68
+ margin: 0;
69
+ }
70
+
71
+ li {
72
+ display: flex;
73
+ flex-direction: row;
74
+ align-items: center;
75
+ gap: var(--spacing-large);
76
+ }
77
+
78
+ li > * {
79
+ flex: 1;
80
+ }
81
+
82
+ div[data-name] {
83
+ text-align: right;
84
+ }
85
+
86
+ div[data-value] {
87
+ display: flex;
88
+ justify-content: space-between;
89
+ }
90
+ `
91
+ ];
92
+ __decorate([
93
+ state(),
94
+ __metadata("design:type", Array)
95
+ ], OxInputNodes.prototype, "value", void 0);
96
+ OxInputNodes = __decorate([
97
+ customElement('ox-input-nodes')
98
+ ], OxInputNodes);
99
+ export { OxInputNodes };
100
+ //# sourceMappingURL=ox-input-nodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-input-nodes.js","sourceRoot":"","sources":["../../src/editors/ox-input-nodes.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,4BAA4B,CAAA;AAEnC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAIrC,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,WAAW;IAAtC;;QAgDI,UAAK,GAAW,EAAE,CAAA;IA0C7B,CAAC;IAxCC,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAK,EAAa,CAAA;QAE1C,OAAO,IAAI,CAAA;;;YAGH,KAAK,CAAC,GAAG,CACT,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAA;4BACN,IAAI,CAAC,QAAQ;+BACV,EAAE,IAAI,EAAE;uDACgB,IAAI,IAAI,EAAE;;aAEpD,CACF;;;KAGN,CAAA;IACH,CAAC;IAED,QAAQ,CAAC,CAAQ;QACf,CAAC,CAAC,eAAe,EAAE,CAAA;QAEnB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;QAElD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;;YACpC,MAAM,EAAE,GAAG,MAAA,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,0CAAE,YAAY,CAAC,SAAS,CAAC,CAAA;YACjE,MAAM,IAAI,GAAG,MAAA,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,0CAAE,KAAK,CAAA;YAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;YAEpD,uCAAY,IAAK,KAAE,IAAI,IAAE;QAC3B,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,QAAQ,EAAE;YACxB,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,IAAI,CAAC,KAAK;SACnB,CAAC,CACH,CAAA;IACH,CAAC;;AAxFM,mBAAM,GAAG;IACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2CF;CACF,AA7CY,CA6CZ;AAEQ;IAAR,KAAK,EAAE;;2CAAmB;AAhDhB,YAAY;IADxB,aAAa,CAAC,gBAAgB,CAAC;GACnB,YAAY,CA0FxB","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@material/web/icon/icon.js'\n\nimport { css, html } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\n\nimport { OxFormField } from '@operato/input'\nimport { Node } from '../types'\n\n@customElement('ox-input-nodes')\nexport class OxInputNodes extends OxFormField {\n static styles = [\n css`\n :host {\n display: flex;\n --md-icon-size: 1.4em;\n }\n\n fieldset {\n flex: 1;\n font-size: 0.8em;\n border: 0;\n border-bottom: 1px solid;\n background-color: var(--md-sys-color-surface-variant);\n padding: var(--spacing-medium);\n }\n\n ul {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-small);\n\n padding: 0;\n margin: 0;\n }\n\n li {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--spacing-large);\n }\n\n li > * {\n flex: 1;\n }\n\n div[data-name] {\n text-align: right;\n }\n\n div[data-value] {\n display: flex;\n justify-content: space-between;\n }\n `\n ]\n\n @state() value: Node[] = []\n\n render() {\n const nodes = this.value || ([] as Node[])\n\n return html`\n <fieldset>\n <ul>\n ${nodes.map(\n ({ id, name }) => html`\n <li @change=${this.onChange}>\n <div data-id=${id}>${id}</div>\n <input type=\"text\" name=\"name\" value=${name || ''} />\n </li>\n `\n )}\n </ul>\n </fieldset>\n `\n }\n\n onChange(e: Event) {\n e.stopPropagation()\n\n const lis = this.renderRoot.querySelectorAll('li')\n\n this.value = Array.from(lis).map(li => {\n const id = li.querySelector('[data-id]')?.getAttribute('data-id')\n const name = li.querySelector('input')?.value\n const node = this.value.find(node => node.id === id)\n\n return { ...node!, name }\n })\n\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: this.value\n })\n )\n }\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import { __decorate } from "tslib";
2
+ import './ox-input-nodes';
3
+ import { html } from 'lit';
4
+ import { customElement } from 'lit/decorators.js';
5
+ import { OxPropertyEditor } from '@operato/property-editor';
6
+ let PropertyEditorNodes = class PropertyEditorNodes extends OxPropertyEditor {
7
+ editorTemplate(value, spec) {
8
+ // const { defaultValue = [] } = spec
9
+ // value ||= []
10
+ // const valueProperty = defaultValue
11
+ // .map(({ name, ...others }) => {
12
+ // const node = value.find(v => v.name == name)
13
+ // if (node) {
14
+ // return { ...others, ...node }
15
+ // }
16
+ // })
17
+ // .filter(Boolean)
18
+ return html ` <ox-input-nodes .value=${value} fullwidth></ox-input-nodes> `;
19
+ }
20
+ };
21
+ PropertyEditorNodes = __decorate([
22
+ customElement('ox-property-editor-nodes')
23
+ ], PropertyEditorNodes);
24
+ export { PropertyEditorNodes };
25
+ //# sourceMappingURL=ox-property-editor-nodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-property-editor-nodes.js","sourceRoot":"","sources":["../../src/editors/ox-property-editor-nodes.ts"],"names":[],"mappings":";AAAA,OAAO,kBAAkB,CAAA;AAEzB,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,gBAAgB,EAAgB,MAAM,0BAA0B,CAAA;AAIlE,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,gBAAgB;IACvD,cAAc,CAAC,KAAa,EAAE,IAAkB;QAC9C,qCAAqC;QACrC,eAAe;QAEf,qCAAqC;QACrC,oCAAoC;QACpC,mDAAmD;QACnD,kBAAkB;QAClB,sCAAsC;QACtC,QAAQ;QACR,OAAO;QACP,qBAAqB;QAErB,OAAO,IAAI,CAAA,2BAA2B,KAAK,+BAA+B,CAAA;IAC5E,CAAC;CACF,CAAA;AAhBY,mBAAmB;IAD/B,aAAa,CAAC,0BAA0B,CAAC;GAC7B,mBAAmB,CAgB/B","sourcesContent":["import './ox-input-nodes'\n\nimport { html } from 'lit'\nimport { customElement } from 'lit/decorators.js'\n\nimport { OxPropertyEditor, PropertySpec } from '@operato/property-editor'\nimport { Node } from '../types'\n\n@customElement('ox-property-editor-nodes')\nexport class PropertyEditorNodes extends OxPropertyEditor {\n editorTemplate(value: Node[], spec: PropertySpec) {\n // const { defaultValue = [] } = spec\n // value ||= []\n\n // const valueProperty = defaultValue\n // .map(({ name, ...others }) => {\n // const node = value.find(v => v.name == name)\n // if (node) {\n // return { ...others, ...node }\n // }\n // })\n // .filter(Boolean)\n\n return html` <ox-input-nodes .value=${value} fullwidth></ox-input-nodes> `\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -22,4 +22,5 @@ export { default as Port } from './port';
22
22
  export { default as Crane } from './crane';
23
23
  export { default as Shelf } from './shelf';
24
24
  export { default as Carrier } from './carrier';
25
+ export { default as NodePath } from './node-path';
25
26
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,oCAAoC,CAAA;AAE3C,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,UAAU,CAAA;AAEnD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AACtE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEjD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAA","sourcesContent":["import './scene/root-container-override.js'\n\nexport { default as MachineGroups } from './groups'\n\nexport { default as MCSMachine } from './mcs-machine'\nexport { default as MCSUnit } from './mcs-unit'\nexport { default as MCSCarrierHolder } from './mcs-carrier-holder'\nexport { default as MCSVehicle } from './mcs-vehicle'\nexport { default as MCSTransport } from './mcs-transport'\nexport { default as ZoneCapacityBar } from './zone-capacity-bar'\nexport { default as StockerCapacityBar } from './stocker-capacity-bar'\nexport { default as PortFlow } from './port-flow'\n\nexport { default as AGVLine } from './agv-line'\nexport { default as Buffer } from './buffer'\nexport { default as Conveyor } from './conveyor'\nexport { default as ConveyorJoin } from './conveyor-join'\nexport { default as Equipment } from './equipment'\nexport { default as OHTLine } from './oht-line'\nexport { default as Stocker } from './stocker'\n\nexport { default as AGV } from './agv'\nexport { default as OHT } from './oht'\nexport { default as Shuttle } from './shuttle'\n\nexport { default as Port } from './port'\nexport { default as Crane } from './crane'\nexport { default as Shelf } from './shelf'\nexport { default as Carrier } from './carrier'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,oCAAoC,CAAA;AAE3C,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,UAAU,CAAA;AAEnD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AACtE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEjD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,aAAa,CAAA","sourcesContent":["import './scene/root-container-override.js'\n\nexport { default as MachineGroups } from './groups'\n\nexport { default as MCSMachine } from './mcs-machine'\nexport { default as MCSUnit } from './mcs-unit'\nexport { default as MCSCarrierHolder } from './mcs-carrier-holder'\nexport { default as MCSVehicle } from './mcs-vehicle'\nexport { default as MCSTransport } from './mcs-transport'\nexport { default as ZoneCapacityBar } from './zone-capacity-bar'\nexport { default as StockerCapacityBar } from './stocker-capacity-bar'\nexport { default as PortFlow } from './port-flow'\n\nexport { default as AGVLine } from './agv-line'\nexport { default as Buffer } from './buffer'\nexport { default as Conveyor } from './conveyor'\nexport { default as ConveyorJoin } from './conveyor-join'\nexport { default as Equipment } from './equipment'\nexport { default as OHTLine } from './oht-line'\nexport { default as Stocker } from './stocker'\n\nexport { default as AGV } from './agv'\nexport { default as OHT } from './oht'\nexport { default as Shuttle } from './shuttle'\n\nexport { default as Port } from './port'\nexport { default as Crane } from './crane'\nexport { default as Shelf } from './shelf'\nexport { default as Carrier } from './carrier'\n\nexport { default as NodePath } from './node-path'\n"]}
@@ -0,0 +1,233 @@
1
+ /*
2
+ * Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+ import { Component, Line } from '@hatiolab/things-scene';
5
+ var controlHandler = {
6
+ currentIndex: 0,
7
+ ondragstart: function (point, index, component) {
8
+ component.mutatePath(null, function (path) {
9
+ const nodes = component.state.nodes;
10
+ const control = component.controls[index];
11
+ const { from, to, id } = control;
12
+ const newId = `${Date.now()}`;
13
+ if (id) {
14
+ const fromNode = nodes.find(node => node.id === id);
15
+ const fromIndex = nodes.indexOf(fromNode);
16
+ controlHandler.currentIndex = fromIndex == 0 ? 0 : fromIndex + 1;
17
+ nodes.splice(controlHandler.currentIndex, 0, {
18
+ id: newId,
19
+ position: point,
20
+ name: '',
21
+ connections: []
22
+ });
23
+ fromNode.connections.push(newId);
24
+ path.splice(controlHandler.currentIndex, 0, point);
25
+ }
26
+ else {
27
+ const fromNode = nodes.find(node => node.id === from);
28
+ controlHandler.currentIndex = nodes.indexOf(fromNode) + 1;
29
+ nodes.splice(controlHandler.currentIndex, 0, {
30
+ id: newId,
31
+ position: point,
32
+ name: '',
33
+ connections: [to]
34
+ });
35
+ const connections = fromNode.connections;
36
+ connections.splice(connections.indexOf(to), 1, newId);
37
+ path.splice(controlHandler.currentIndex, 0, point);
38
+ }
39
+ });
40
+ },
41
+ ondragmove: function (point, index, component) {
42
+ component.mutatePath(null, function (path) {
43
+ path[controlHandler.currentIndex] = point;
44
+ });
45
+ },
46
+ ondragend: function (point, index, component) { }
47
+ };
48
+ const NATURE = {
49
+ mutable: false,
50
+ resizable: true,
51
+ rotatable: true,
52
+ properties: [
53
+ {
54
+ type: 'nodes',
55
+ label: 'nodes',
56
+ name: 'nodes'
57
+ }
58
+ ],
59
+ help: 'scene/component/node-path'
60
+ };
61
+ export default class NodePath extends Line {
62
+ static get nature() {
63
+ return NATURE;
64
+ }
65
+ get path() {
66
+ return this.state.nodes.map(node => node.position);
67
+ }
68
+ set path(path) {
69
+ const nodes = this.state.nodes || [];
70
+ this.set('nodes', nodes.map((node, index) => (Object.assign(Object.assign({}, node), { position: path[index] }))));
71
+ }
72
+ contains(x, y) {
73
+ var path = this.path;
74
+ var result = false;
75
+ path.forEach((p, idx) => {
76
+ let j = (idx + path.length + 1) % path.length;
77
+ let x1 = p.x;
78
+ let y1 = p.y;
79
+ let x2 = path[j].x;
80
+ let y2 = path[j].y;
81
+ if (y1 > y != y2 > y && x < ((x2 - x1) * (y - y1)) / (y2 - y1) + x1)
82
+ result = !result;
83
+ });
84
+ return result;
85
+ }
86
+ render(ctx) {
87
+ // 모든 연결 렌더링
88
+ this.renderConnections(ctx);
89
+ // 모든 노드 렌더링
90
+ this.renderNodes(ctx);
91
+ }
92
+ renderConnections(ctx) {
93
+ const { nodes = [], lineColor = '#000', lineWidth = 1 } = this.state;
94
+ nodes.forEach(node => {
95
+ const { x: x1, y: y1 } = node.position;
96
+ const connections = node.connections || [];
97
+ connections.forEach(targetId => {
98
+ const targetNode = this.findNodeById(targetId);
99
+ if (targetNode) {
100
+ const { x: x2, y: y2 } = targetNode.position;
101
+ ctx.beginPath();
102
+ ctx.moveTo(x1, y1);
103
+ ctx.lineTo(x2, y2);
104
+ ctx.strokeStyle = lineColor;
105
+ ctx.lineWidth = lineWidth;
106
+ ctx.stroke();
107
+ }
108
+ });
109
+ });
110
+ }
111
+ renderNodes(ctx) {
112
+ const { nodes = [], fillStyle = '#fff', strokeStyle = '#000' } = this.state;
113
+ nodes.forEach(node => {
114
+ const { x, y } = node.position;
115
+ ctx.beginPath();
116
+ ctx.arc(x, y, 10, 0, Math.PI * 2);
117
+ ctx.fillStyle = fillStyle;
118
+ ctx.strokeStyle = strokeStyle;
119
+ ctx.fill();
120
+ });
121
+ }
122
+ findNodeById(id) {
123
+ const nodes = this.state.nodes || [];
124
+ return nodes.find(node => node.id === id);
125
+ }
126
+ findNodeIndexById(id) {
127
+ const nodes = this.state.nodes || [];
128
+ return nodes.findIndex(node => node.id === id);
129
+ }
130
+ addNode(x, y, name = '', type = 'normal') {
131
+ const nodes = [...(this.state.nodes || [])];
132
+ const nodeId = `${Date.now()}`;
133
+ const node = {
134
+ id: nodeId,
135
+ position: { x, y },
136
+ name,
137
+ connections: []
138
+ };
139
+ nodes.push(node);
140
+ this.setState('nodes', nodes);
141
+ return nodeId;
142
+ }
143
+ moveNode(index, position) {
144
+ const nodes = [...(this.state.nodes || [])];
145
+ if (nodes[index]) {
146
+ nodes[index].position = position;
147
+ this.setState('nodes', nodes);
148
+ }
149
+ }
150
+ connectNodes(sourceId, targetId) {
151
+ if (sourceId === targetId)
152
+ return false;
153
+ const nodes = [...(this.state.nodes || [])];
154
+ const sourceIndex = this.findNodeIndexById(sourceId);
155
+ const targetIndex = this.findNodeIndexById(targetId);
156
+ if (sourceIndex >= 0 && targetIndex >= 0) {
157
+ // 이미 연결되어 있는지 확인
158
+ if (!nodes[sourceIndex].connections.includes(targetId)) {
159
+ nodes[sourceIndex].connections.push(targetId);
160
+ }
161
+ // 양방향 연결 (선택적)
162
+ // if (!nodes[targetIndex].connections.includes(sourceId)) {
163
+ // nodes[targetIndex].connections.push(sourceId)
164
+ // }
165
+ this.setState('nodes', nodes);
166
+ return true;
167
+ }
168
+ return false;
169
+ }
170
+ disconnectNodes(sourceId, targetId) {
171
+ const nodes = [...(this.state.nodes || [])];
172
+ const sourceIndex = this.findNodeIndexById(sourceId);
173
+ const targetIndex = this.findNodeIndexById(targetId);
174
+ if (sourceIndex >= 0) {
175
+ nodes[sourceIndex].connections = nodes[sourceIndex].connections.filter(id => id !== targetId);
176
+ }
177
+ // 양방향 연결 해제 (선택적)
178
+ // if (targetIndex >= 0) {
179
+ // nodes[targetIndex].connections = nodes[targetIndex].connections.filter(id => id !== sourceId)
180
+ // }
181
+ this.setState('nodes', nodes);
182
+ }
183
+ removeNode(nodeId) {
184
+ let nodes = [...(this.state.nodes || [])];
185
+ // 해당 노드 제거
186
+ nodes = nodes.filter(node => node.id !== nodeId);
187
+ // 다른 노드들의 연결에서도 제거
188
+ nodes.forEach(node => {
189
+ node.connections = node.connections.filter(id => id !== nodeId);
190
+ });
191
+ this.setState('nodes', nodes);
192
+ }
193
+ // 특정 노드 연결에 대한 속성 설정
194
+ setConnectionProperty(sourceId, targetId, propertyName, value) {
195
+ const nodes = [...(this.state.nodes || [])];
196
+ const sourceIndex = this.findNodeIndexById(sourceId);
197
+ if (sourceIndex >= 0 && nodes[sourceIndex].connections.includes(targetId)) {
198
+ this.setState('nodes', nodes);
199
+ return true;
200
+ }
201
+ return false;
202
+ }
203
+ get controls() {
204
+ var { nodes } = this.state;
205
+ var controls = [];
206
+ for (let i = 0; i < nodes.length; i++) {
207
+ const { id: sourceId, position: p1, connections = [] } = nodes[i];
208
+ controls.push({
209
+ x: p1.x,
210
+ y: p1.y,
211
+ //@ts-ignore
212
+ id: sourceId,
213
+ handler: controlHandler
214
+ });
215
+ connections.forEach(targetId => {
216
+ const targetNode = this.findNodeById(targetId);
217
+ const { position: p2 } = targetNode;
218
+ controls.push({
219
+ x: (p1.x + p2.x) / 2,
220
+ y: (p1.y + p2.y) / 2,
221
+ //@ts-ignore
222
+ from: sourceId,
223
+ //@ts-ignore
224
+ to: targetId,
225
+ handler: controlHandler
226
+ });
227
+ });
228
+ }
229
+ return controls;
230
+ }
231
+ }
232
+ Component.register('NodePath', NodePath);
233
+ //# sourceMappingURL=node-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-path.js","sourceRoot":"","sources":["../src/node-path.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { Component, Line, Control } from '@hatiolab/things-scene'\nimport { Node, Position } from './types'\n\nvar controlHandler = {\n currentIndex: 0,\n ondragstart: function (point, index, component) {\n component.mutatePath(null, function (path) {\n const nodes = component.state.nodes as Node[]\n const control = component.controls[index]\n const { from, to, id } = control as any\n const newId = `${Date.now()}`\n\n if (id) {\n const fromNode = nodes.find(node => node.id === id)\n const fromIndex = nodes.indexOf(fromNode!)\n controlHandler.currentIndex = fromIndex == 0 ? 0 : fromIndex + 1\n\n nodes.splice(controlHandler.currentIndex, 0, {\n id: newId,\n position: point,\n name: '',\n connections: []\n })\n\n fromNode!.connections.push(newId)\n path.splice(controlHandler.currentIndex, 0, point)\n } else {\n const fromNode = nodes.find(node => node.id === from)\n controlHandler.currentIndex = nodes.indexOf(fromNode!) + 1\n\n nodes.splice(controlHandler.currentIndex, 0, {\n id: newId,\n position: point,\n name: '',\n connections: [to]\n })\n\n const connections = fromNode!.connections\n connections.splice(connections.indexOf(to), 1, newId)\n\n path.splice(controlHandler.currentIndex, 0, point)\n }\n })\n },\n\n ondragmove: function (point, index, component) {\n component.mutatePath(null, function (path) {\n path[controlHandler.currentIndex] = point\n })\n },\n\n ondragend: function (point, index, component) {}\n}\n\nconst NATURE = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'nodes',\n label: 'nodes',\n name: 'nodes'\n }\n ],\n help: 'scene/component/node-path'\n}\n\nexport default class NodePath extends Line {\n static get nature() {\n return NATURE\n }\n\n get path(): Position[] {\n return this.state.nodes.map(node => node.position)\n }\n\n set path(path: Position[]) {\n const nodes = this.state.nodes || []\n\n this.set(\n 'nodes',\n nodes.map((node, index) => ({ ...node, position: path[index] }))\n )\n }\n\n contains(x: number, y: number): boolean {\n var path = this.path\n var result = false\n\n path.forEach((p, idx) => {\n let j = (idx + path.length + 1) % path.length\n\n let x1 = p.x\n let y1 = p.y\n let x2 = path[j].x\n let y2 = path[j].y\n\n if (y1 > y != y2 > y && x < ((x2 - x1) * (y - y1)) / (y2 - y1) + x1) result = !result\n })\n\n return result\n }\n\n render(ctx: CanvasRenderingContext2D): void {\n // 모든 연결 렌더링\n this.renderConnections(ctx)\n\n // 모든 노드 렌더링\n this.renderNodes(ctx)\n }\n\n renderConnections(ctx: CanvasRenderingContext2D): void {\n const { nodes = [], lineColor = '#000', lineWidth = 1 } = this.state\n\n nodes.forEach(node => {\n const { x: x1, y: y1 } = node.position\n const connections = node.connections || []\n\n connections.forEach(targetId => {\n const targetNode = this.findNodeById(targetId)\n if (targetNode) {\n const { x: x2, y: y2 } = targetNode.position\n\n ctx.beginPath()\n ctx.moveTo(x1, y1)\n ctx.lineTo(x2, y2)\n ctx.strokeStyle = lineColor\n ctx.lineWidth = lineWidth\n\n ctx.stroke()\n }\n })\n })\n }\n\n renderNodes(ctx: CanvasRenderingContext2D): void {\n const { nodes = [], fillStyle = '#fff', strokeStyle = '#000' } = this.state\n\n nodes.forEach(node => {\n const { x, y } = node.position\n\n ctx.beginPath()\n\n ctx.arc(x, y, 10, 0, Math.PI * 2)\n\n ctx.fillStyle = fillStyle\n ctx.strokeStyle = strokeStyle\n\n ctx.fill()\n })\n }\n\n findNodeById(id: string): Node | undefined {\n const nodes = this.state.nodes || []\n return nodes.find(node => node.id === id)\n }\n\n findNodeIndexById(id: string): number {\n const nodes = this.state.nodes || []\n return nodes.findIndex(node => node.id === id)\n }\n\n addNode(x: number, y: number, name: string = '', type: string = 'normal'): string {\n const nodes = [...(this.state.nodes || [])]\n const nodeId = `${Date.now()}`\n\n const node: Node = {\n id: nodeId,\n position: { x, y },\n name,\n connections: []\n }\n\n nodes.push(node)\n this.setState('nodes', nodes)\n\n return nodeId\n }\n\n moveNode(index: number, position: Position): void {\n const nodes = [...(this.state.nodes || [])]\n if (nodes[index]) {\n nodes[index].position = position\n this.setState('nodes', nodes)\n }\n }\n\n connectNodes(sourceId: string, targetId: string): boolean {\n if (sourceId === targetId) return false\n\n const nodes = [...(this.state.nodes || [])]\n const sourceIndex = this.findNodeIndexById(sourceId)\n const targetIndex = this.findNodeIndexById(targetId)\n\n if (sourceIndex >= 0 && targetIndex >= 0) {\n // 이미 연결되어 있는지 확인\n if (!nodes[sourceIndex].connections.includes(targetId)) {\n nodes[sourceIndex].connections.push(targetId)\n }\n\n // 양방향 연결 (선택적)\n // if (!nodes[targetIndex].connections.includes(sourceId)) {\n // nodes[targetIndex].connections.push(sourceId)\n // }\n\n this.setState('nodes', nodes)\n return true\n }\n\n return false\n }\n\n disconnectNodes(sourceId: string, targetId: string): void {\n const nodes = [...(this.state.nodes || [])]\n const sourceIndex = this.findNodeIndexById(sourceId)\n const targetIndex = this.findNodeIndexById(targetId)\n\n if (sourceIndex >= 0) {\n nodes[sourceIndex].connections = nodes[sourceIndex].connections.filter(id => id !== targetId)\n }\n\n // 양방향 연결 해제 (선택적)\n // if (targetIndex >= 0) {\n // nodes[targetIndex].connections = nodes[targetIndex].connections.filter(id => id !== sourceId)\n // }\n\n this.setState('nodes', nodes)\n }\n\n removeNode(nodeId: string): void {\n let nodes = [...(this.state.nodes || [])]\n\n // 해당 노드 제거\n nodes = nodes.filter(node => node.id !== nodeId)\n\n // 다른 노드들의 연결에서도 제거\n nodes.forEach(node => {\n node.connections = node.connections.filter(id => id !== nodeId)\n })\n\n this.setState('nodes', nodes)\n }\n\n // 특정 노드 연결에 대한 속성 설정\n setConnectionProperty(sourceId: string, targetId: string, propertyName: string, value: any): boolean {\n const nodes = [...(this.state.nodes || [])]\n const sourceIndex = this.findNodeIndexById(sourceId)\n\n if (sourceIndex >= 0 && nodes[sourceIndex].connections.includes(targetId)) {\n this.setState('nodes', nodes)\n return true\n }\n\n return false\n }\n\n get controls(): Control[] {\n var { nodes } = this.state\n var controls = [] as Control[]\n\n for (let i = 0; i < nodes.length; i++) {\n const { id: sourceId, position: p1, connections = [] } = nodes[i]\n controls.push({\n x: p1.x,\n y: p1.y,\n //@ts-ignore\n id: sourceId,\n handler: controlHandler\n })\n\n connections.forEach(targetId => {\n const targetNode = this.findNodeById(targetId)\n const { position: p2 } = targetNode!\n\n controls.push({\n x: (p1.x + p2.x) / 2,\n y: (p1.y + p2.y) / 2,\n //@ts-ignore\n from: sourceId,\n //@ts-ignore\n to: targetId,\n handler: controlHandler\n })\n })\n }\n\n return controls\n }\n}\n\nComponent.register('NodePath', NodePath)\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"data-subscription.js","sourceRoot":"","sources":["../../src/templates/data-subscription.js"],"names":[],"mappings":"AAAA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,wCAAwC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AAEpF,eAAe;IACb,IAAI,EAAE,mBAAmB;IACzB,WAAW,EAAE,mBAAmB;IAChC,KAAK,EAAE,KAAK;IACZ,IAAI;IACJ,KAAK,EAAE;QACL,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,EAAE;QACP,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;QACX,MAAM,EAAE,IAAI;KACb;CACF,CAAA","sourcesContent":["const icon = new URL('../../icons/icon-data-subscription.png', import.meta.url).href\n\nexport default {\n type: 'data-subscription',\n description: 'data-subscription',\n group: 'etc',\n icon,\n model: {\n type: 'data-subscription',\n left: 10,\n top: 10,\n width: 100,\n height: 100,\n hidden: true\n }\n}\n"]}
1
+ {"version":3,"file":"data-subscription.js","sourceRoot":"","sources":["../../src/templates/data-subscription.ts"],"names":[],"mappings":"AAAA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,wCAAwC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AAEpF,eAAe;IACb,IAAI,EAAE,mBAAmB;IACzB,WAAW,EAAE,mBAAmB;IAChC,KAAK,EAAE,KAAK;IACZ,IAAI;IACJ,KAAK,EAAE;QACL,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,EAAE;QACP,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;QACX,MAAM,EAAE,IAAI;KACb;CACF,CAAA","sourcesContent":["const icon = new URL('../../icons/icon-data-subscription.png', import.meta.url).href\n\nexport default {\n type: 'data-subscription',\n description: 'data-subscription',\n group: 'etc',\n icon,\n model: {\n type: 'data-subscription',\n left: 10,\n top: 10,\n width: 100,\n height: 100,\n hidden: true\n }\n}\n"]}
@@ -13,6 +13,7 @@ import Shelf from './shelf';
13
13
  import agvLine from './agv-line';
14
14
  import ohtLine from './oht-line';
15
15
  import conveyor from './conveyor';
16
+ import NodePath from './node-path';
16
17
  export default [
17
18
  StockerCapacityBar,
18
19
  ZoneCapacityBar,
@@ -28,6 +29,7 @@ export default [
28
29
  Shuttle,
29
30
  Crane,
30
31
  Shelf,
31
- Port
32
+ Port,
33
+ NodePath
32
34
  ];
33
35
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,wBAAwB,CAAA;AACvD,OAAO,eAAe,MAAM,qBAAqB,CAAA;AACjD,OAAO,QAAQ,MAAM,aAAa,CAAA;AAElC,OAAO,GAAG,MAAM,OAAO,CAAA;AACvB,OAAO,MAAM,MAAM,UAAU,CAAA;AAC7B,OAAO,SAAS,MAAM,aAAa,CAAA;AACnC,OAAO,GAAG,MAAM,OAAO,CAAA;AACvB,OAAO,OAAO,MAAM,WAAW,CAAA;AAE/B,OAAO,OAAO,MAAM,WAAW,CAAA;AAC/B,OAAO,IAAI,MAAM,QAAQ,CAAA;AACzB,OAAO,KAAK,MAAM,SAAS,CAAA;AAC3B,OAAO,KAAK,MAAM,SAAS,CAAA;AAE3B,OAAO,OAAO,MAAM,YAAY,CAAA;AAChC,OAAO,OAAO,MAAM,YAAY,CAAA;AAChC,OAAO,QAAQ,MAAM,YAAY,CAAA;AAEjC,eAAe;IACb,kBAAkB;IAClB,eAAe;IACf,QAAQ;IAER,MAAM;IACN,OAAO;IACP,SAAS;IAET,OAAO;IACP,OAAO;IACP,QAAQ;IAER,GAAG;IACH,GAAG;IACH,OAAO;IACP,KAAK;IACL,KAAK;IACL,IAAI;CACL,CAAA","sourcesContent":["import StockerCapacityBar from './stocker-capacity-bar'\nimport ZoneCapacityBar from './zone-capacity-bar'\nimport PortFlow from './port-flow'\n\nimport AGV from './agv'\nimport Buffer from './buffer'\nimport Equipment from './equipment'\nimport OHT from './oht'\nimport Stocker from './stocker'\n\nimport Shuttle from './shuttle'\nimport Port from './port'\nimport Crane from './crane'\nimport Shelf from './shelf'\n\nimport agvLine from './agv-line'\nimport ohtLine from './oht-line'\nimport conveyor from './conveyor'\n\nexport default [\n StockerCapacityBar,\n ZoneCapacityBar,\n PortFlow,\n\n Buffer,\n Stocker,\n Equipment,\n\n agvLine,\n ohtLine,\n conveyor,\n\n AGV,\n OHT,\n Shuttle,\n Crane,\n Shelf,\n Port\n]\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,wBAAwB,CAAA;AACvD,OAAO,eAAe,MAAM,qBAAqB,CAAA;AACjD,OAAO,QAAQ,MAAM,aAAa,CAAA;AAElC,OAAO,GAAG,MAAM,OAAO,CAAA;AACvB,OAAO,MAAM,MAAM,UAAU,CAAA;AAC7B,OAAO,SAAS,MAAM,aAAa,CAAA;AACnC,OAAO,GAAG,MAAM,OAAO,CAAA;AACvB,OAAO,OAAO,MAAM,WAAW,CAAA;AAE/B,OAAO,OAAO,MAAM,WAAW,CAAA;AAC/B,OAAO,IAAI,MAAM,QAAQ,CAAA;AACzB,OAAO,KAAK,MAAM,SAAS,CAAA;AAC3B,OAAO,KAAK,MAAM,SAAS,CAAA;AAE3B,OAAO,OAAO,MAAM,YAAY,CAAA;AAChC,OAAO,OAAO,MAAM,YAAY,CAAA;AAChC,OAAO,QAAQ,MAAM,YAAY,CAAA;AAEjC,OAAO,QAAQ,MAAM,aAAa,CAAA;AAElC,eAAe;IACb,kBAAkB;IAClB,eAAe;IACf,QAAQ;IAER,MAAM;IACN,OAAO;IACP,SAAS;IAET,OAAO;IACP,OAAO;IACP,QAAQ;IAER,GAAG;IACH,GAAG;IACH,OAAO;IACP,KAAK;IACL,KAAK;IACL,IAAI;IAEJ,QAAQ;CACT,CAAA","sourcesContent":["import StockerCapacityBar from './stocker-capacity-bar'\nimport ZoneCapacityBar from './zone-capacity-bar'\nimport PortFlow from './port-flow'\n\nimport AGV from './agv'\nimport Buffer from './buffer'\nimport Equipment from './equipment'\nimport OHT from './oht'\nimport Stocker from './stocker'\n\nimport Shuttle from './shuttle'\nimport Port from './port'\nimport Crane from './crane'\nimport Shelf from './shelf'\n\nimport agvLine from './agv-line'\nimport ohtLine from './oht-line'\nimport conveyor from './conveyor'\n\nimport NodePath from './node-path'\n\nexport default [\n StockerCapacityBar,\n ZoneCapacityBar,\n PortFlow,\n\n Buffer,\n Stocker,\n Equipment,\n\n agvLine,\n ohtLine,\n conveyor,\n\n AGV,\n OHT,\n Shuttle,\n Crane,\n Shelf,\n Port,\n\n NodePath\n]\n"]}
@@ -0,0 +1,48 @@
1
+ const nodePath = new URL('../../icons/node-path.png', import.meta.url).href;
2
+ export default {
3
+ type: 'NodePath',
4
+ description: 'node path',
5
+ icon: nodePath,
6
+ group: ['etc'],
7
+ model: {
8
+ type: 'NodePath',
9
+ left: 100,
10
+ top: 100,
11
+ width: 20,
12
+ height: 20,
13
+ fillStyle: '#fff',
14
+ strokeStyle: 'rgb(0, 0, 0, 0.2)',
15
+ alpha: 0.2,
16
+ lineWidth: 12,
17
+ lineDash: 'solid',
18
+ lineCap: 'round',
19
+ joinStyle: 'round',
20
+ nodes: [
21
+ {
22
+ id: '1',
23
+ position: { x: 100, y: 100 },
24
+ name: 'Node 1',
25
+ connections: ['2']
26
+ },
27
+ {
28
+ id: '2',
29
+ position: { x: 200, y: 100 },
30
+ name: 'Node 2',
31
+ connections: ['3']
32
+ },
33
+ {
34
+ id: '3',
35
+ position: { x: 200, y: 200 },
36
+ name: 'Node 2',
37
+ connections: ['4']
38
+ },
39
+ {
40
+ id: '4',
41
+ position: { x: 100, y: 200 },
42
+ name: 'Node 2',
43
+ connections: []
44
+ }
45
+ ]
46
+ }
47
+ };
48
+ //# sourceMappingURL=node-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-path.js","sourceRoot":"","sources":["../../src/templates/node-path.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AAE3E,eAAe;IACb,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,WAAW;IACxB,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,CAAC,KAAK,CAAC;IACd,KAAK,EAAE;QACL,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,GAAG;QACT,GAAG,EAAE,GAAG;QACR,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,EAAE;QACV,SAAS,EAAE,MAAM;QACjB,WAAW,EAAE,mBAAmB;QAChC,KAAK,EAAE,GAAG;QACV,SAAS,EAAE,EAAE;QACb,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,OAAO;QAClB,KAAK,EAAE;YACL;gBACE,EAAE,EAAE,GAAG;gBACP,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;gBAC5B,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,CAAC,GAAG,CAAC;aACnB;YACD;gBACE,EAAE,EAAE,GAAG;gBACP,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;gBAC5B,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,CAAC,GAAG,CAAC;aACnB;YACD;gBACE,EAAE,EAAE,GAAG;gBACP,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;gBAC5B,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,CAAC,GAAG,CAAC;aACnB;YACD;gBACE,EAAE,EAAE,GAAG;gBACP,QAAQ,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;gBAC5B,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE;aAChB;SACF;KACF;CACF,CAAA","sourcesContent":["const nodePath = new URL('../../icons/node-path.png', import.meta.url).href\n\nexport default {\n type: 'NodePath',\n description: 'node path',\n icon: nodePath,\n group: ['etc'],\n model: {\n type: 'NodePath',\n left: 100,\n top: 100,\n width: 20,\n height: 20,\n fillStyle: '#fff',\n strokeStyle: 'rgb(0, 0, 0, 0.2)',\n alpha: 0.2,\n lineWidth: 12,\n lineDash: 'solid',\n lineCap: 'round',\n joinStyle: 'round',\n nodes: [\n {\n id: '1',\n position: { x: 100, y: 100 },\n name: 'Node 1',\n connections: ['2']\n },\n {\n id: '2',\n position: { x: 200, y: 100 },\n name: 'Node 2',\n connections: ['3']\n },\n {\n id: '3',\n position: { x: 200, y: 200 },\n name: 'Node 2',\n connections: ['4']\n },\n {\n id: '4',\n position: { x: 100, y: 200 },\n name: 'Node 2',\n connections: []\n }\n ]\n }\n}\n"]}