@fmsim/machine 0.0.97 → 0.0.99

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.
@@ -1,91 +0,0 @@
1
- import { Component, Ellipse } from '@hatiolab/things-scene';
2
- import { getVaueOnRanges } from './utils/get-value-on-ranges';
3
- import { MCSStatusMixin } from './features/mcs-status-mixin';
4
- import { LEGEND_CAPACITY } from './features/mcs-status-default';
5
- const NATURE = {
6
- mutable: false,
7
- resizable: true,
8
- rotatable: true,
9
- properties: [
10
- {
11
- type: 'number',
12
- name: 'currentUsage',
13
- label: 'current-usage'
14
- },
15
- {
16
- type: 'number',
17
- name: 'highWatermark',
18
- label: 'high-watermark'
19
- },
20
- {
21
- type: 'number',
22
- name: 'maxCapacity',
23
- label: 'max-capacity'
24
- },
25
- {
26
- type: 'hidden',
27
- name: 'usage',
28
- label: 'usage'
29
- }
30
- ],
31
- 'value-property': 'usage'
32
- };
33
- export default class MCSGaugeCapacityCircle extends MCSStatusMixin(Ellipse) {
34
- static get nature() {
35
- return NATURE;
36
- }
37
- getTheme() {
38
- var _a, _b;
39
- const { legendName } = this.state;
40
- if (legendName) {
41
- return (_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b[legendName];
42
- }
43
- }
44
- get legend() {
45
- return this.getTheme() || this.getLegendFallback();
46
- }
47
- getLegendFallback() {
48
- return LEGEND_CAPACITY;
49
- }
50
- get statusColor() {
51
- return getVaueOnRanges(this.usage, this.legend);
52
- }
53
- render(context) {
54
- var { cx, cy, rx, ry } = this.state;
55
- const radius = Math.min(rx, ry);
56
- context.beginPath();
57
- context.arc(cx, cy, radius, 0, Math.PI * 2);
58
- context.fillStyle = 'gray';
59
- context.fill();
60
- this.drawStroke(context);
61
- const startAngle = Math.PI * -0.5;
62
- const endAngle = startAngle + Math.PI * 2 * (this.value / 100);
63
- context.beginPath();
64
- context.moveTo(cx, cy);
65
- context.arc(cx, cy, radius, startAngle, endAngle);
66
- context.lineTo(cx, cy);
67
- context.fillStyle = this.statusColor;
68
- context.fill();
69
- }
70
- get usage() {
71
- const { currentUsage = 0, maxCapacity = 100 } = this.state;
72
- return Math.round((currentUsage / maxCapacity) * 100);
73
- }
74
- set usage(usage) {
75
- // intentionally have done nothing
76
- }
77
- onchangeData(after, before) {
78
- const { CURRENTCAPACITY = 0, MAXCAPACITY = 100, HIGHWATERMARK = 100 } = typeof this.data == 'object' ? this.data : {};
79
- const currentUsage = Number(CURRENTCAPACITY) || 0;
80
- const maxCapacity = Number(MAXCAPACITY) || 100;
81
- const highWatermark = Number(HIGHWATERMARK) || 100;
82
- this.setState({
83
- currentUsage,
84
- maxCapacity,
85
- highWatermark,
86
- usage: Math.round((currentUsage / maxCapacity) * 100)
87
- });
88
- }
89
- }
90
- Component.register('MCSGaugeCapacityCircle', MCSGaugeCapacityCircle);
91
- //# sourceMappingURL=mcs-gauge-capacity-circle.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcs-gauge-capacity-circle.js","sourceRoot":"","sources":["../src/mcs-gauge-capacity-circle.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ComponentNature, Ellipse, Properties } from '@hatiolab/things-scene'\nimport { getVaueOnRanges } from './utils/get-value-on-ranges'\nimport { MCSStatusMixin } from './features/mcs-status-mixin'\nimport { LEGEND_CAPACITY, Legend } from './features/mcs-status-default'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\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: 'maxCapacity',\n label: 'max-capacity'\n },\n {\n type: 'hidden',\n name: 'usage',\n label: 'usage'\n }\n ],\n 'value-property': 'usage'\n}\n\nexport default class MCSGaugeCapacityCircle extends MCSStatusMixin(Ellipse) {\n static get nature() {\n return NATURE\n }\n\n getTheme() {\n const { legendName } = this.state\n\n if (legendName) {\n return (this.root as any)?.style?.[legendName]\n }\n }\n\n get legend(): Legend {\n return this.getTheme() || this.getLegendFallback()\n }\n\n getLegendFallback() {\n return LEGEND_CAPACITY\n }\n\n get statusColor() {\n return getVaueOnRanges(this.usage, this.legend)\n }\n\n render(context: CanvasRenderingContext2D) {\n var { cx, cy, rx, ry } = this.state\n const radius = Math.min(rx, ry)\n\n context.beginPath()\n\n context.arc(cx, cy, radius, 0, Math.PI * 2)\n context.fillStyle = 'gray'\n context.fill()\n this.drawStroke(context)\n\n const startAngle = Math.PI * -0.5\n const endAngle = startAngle + Math.PI * 2 * (this.value / 100)\n\n context.beginPath()\n\n context.moveTo(cx, cy)\n context.arc(cx, cy, radius, startAngle, endAngle)\n context.lineTo(cx, cy)\n context.fillStyle = this.statusColor!\n\n context.fill()\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: Properties, before: Properties): void {\n const {\n CURRENTCAPACITY = 0,\n MAXCAPACITY = 100,\n HIGHWATERMARK = 100\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\n this.setState({\n currentUsage,\n maxCapacity,\n highWatermark,\n usage: Math.round((currentUsage / maxCapacity) * 100)\n })\n }\n}\n\nComponent.register('MCSGaugeCapacityCircle', MCSGaugeCapacityCircle)\n"]}
package/dist/mcs-popup.js DELETED
@@ -1,73 +0,0 @@
1
- import { Component, RectPath, Shape } from '@hatiolab/things-scene';
2
- import { safeRound } from './utils/safe-round';
3
- const NATURE = {
4
- mutable: false,
5
- resizable: true,
6
- rotatable: true,
7
- properties: []
8
- };
9
- export default class MCSPopup extends RectPath(Shape) {
10
- static get nature() {
11
- return NATURE;
12
- }
13
- dispose() {
14
- super.dispose();
15
- }
16
- render(ctx) {
17
- var { round = 0 } = this.model;
18
- var { left, top, width, height } = this.bounds;
19
- drawPopup(ctx, left, top, width, height);
20
- ctx.beginPath();
21
- ctx.translate(left, top);
22
- round = safeRound(round, width, height);
23
- ctx.moveTo(round, 0);
24
- ctx.arcTo(width, 0, width, height, round);
25
- ctx.arcTo(width, height, 0, height, round);
26
- ctx.arcTo(0, height, 0, 0, round);
27
- ctx.arcTo(0, 0, width, 0, round);
28
- ctx.translate(-left, -top);
29
- }
30
- }
31
- Component.register('MCSPOPUP', MCSPopup);
32
- export function drawPopup(ctx, left, top, width, height) {
33
- drawPopupBottom(ctx, left, top, width, height);
34
- }
35
- function drawPopupBottom(ctx, left, top, width, height) {
36
- /* popup1 전체 frame */
37
- // const left = 10
38
- // const top = 10
39
- // const width = 180
40
- // let height = 135
41
- height -= height / 12.25; // 꼬리 영역까지 포함시키려 height를 일부러 크게 잡았으니, 실제로 그릴때는 popup의 몸통 height로 맞춰준다
42
- let radius = 10;
43
- //시작
44
- ctx.beginPath();
45
- ctx.moveTo(left + radius, top);
46
- ctx.strokeStyle = '#afafaf';
47
- //우측 상단 모서리
48
- ctx.lineTo(left + width - radius, top);
49
- ctx.quadraticCurveTo(left + width, top, left + width, top + radius);
50
- //우측 하단 모서리
51
- ctx.lineTo(left + width, top + height - radius);
52
- ctx.quadraticCurveTo(left + width, top + height, left + width - radius, top + height);
53
- //화살표 꼬리 그리기
54
- const arrowWidth = width / 8.95;
55
- const arrowHeight = height / 12.25;
56
- const arrowPx = left + width / 2 + arrowWidth / 2; // start point x
57
- const arrowPy = top + height; // start point y
58
- ctx.lineTo(arrowPx, arrowPy);
59
- ctx.lineTo(arrowPx - arrowWidth / 2, arrowPy + arrowHeight);
60
- ctx.lineTo(arrowPx - arrowWidth, arrowPy);
61
- //좌측 하단 모서리
62
- ctx.lineTo(left + radius, top + height);
63
- ctx.quadraticCurveTo(left, top + height, left, top + height - radius);
64
- //좌측 상단 모서리
65
- ctx.lineTo(left, top + radius);
66
- ctx.quadraticCurveTo(left, top, left + radius, top);
67
- ctx.stroke();
68
- ctx.closePath();
69
- //도형 색칠하기
70
- ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';
71
- ctx.fill();
72
- }
73
- //# sourceMappingURL=mcs-popup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcs-popup.js","sourceRoot":"","sources":["../src/mcs-popup.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ComponentNature, RectPath, Shape, error } from '@hatiolab/things-scene'\nimport { safeRound } from './utils/safe-round'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: []\n}\n\nexport default class MCSPopup extends RectPath(Shape) {\n static get nature() {\n return NATURE\n }\n\n dispose() {\n super.dispose()\n }\n\n render(ctx) {\n var { round = 0 } = this.model\n\n var { left, top, width, height } = this.bounds\n\n drawPopup(ctx, left, top, width, height)\n\n ctx.beginPath()\n\n ctx.translate(left, top)\n\n round = safeRound(round, width, height)\n\n ctx.moveTo(round, 0)\n\n ctx.arcTo(width, 0, width, height, round)\n ctx.arcTo(width, height, 0, height, round)\n ctx.arcTo(0, height, 0, 0, round)\n ctx.arcTo(0, 0, width, 0, round)\n\n ctx.translate(-left, -top)\n }\n}\n\nComponent.register('MCSPOPUP', MCSPopup)\n\nexport function drawPopup(ctx, left, top, width, height) {\n drawPopupBottom(ctx, left, top, width, height)\n}\n\nfunction drawPopupBottom(ctx, left, top, width, height) {\n /* popup1 전체 frame */\n // const left = 10\n // const top = 10\n // const width = 180\n // let height = 135\n height -= height / 12.25 // 꼬리 영역까지 포함시키려 height를 일부러 크게 잡았으니, 실제로 그릴때는 popup의 몸통 height로 맞춰준다\n let radius = 10\n\n //시작\n ctx.beginPath()\n ctx.moveTo(left + radius, top)\n ctx.strokeStyle = '#afafaf'\n //우측 상단 모서리\n ctx.lineTo(left + width - radius, top)\n ctx.quadraticCurveTo(left + width, top, left + width, top + radius)\n //우측 하단 모서리\n ctx.lineTo(left + width, top + height - radius)\n ctx.quadraticCurveTo(left + width, top + height, left + width - radius, top + height)\n //화살표 꼬리 그리기\n const arrowWidth = width / 8.95\n const arrowHeight = height / 12.25\n const arrowPx = left + width / 2 + arrowWidth / 2 // start point x\n const arrowPy = top + height // start point y\n ctx.lineTo(arrowPx, arrowPy)\n ctx.lineTo(arrowPx - arrowWidth / 2, arrowPy + arrowHeight)\n ctx.lineTo(arrowPx - arrowWidth, arrowPy)\n //좌측 하단 모서리\n ctx.lineTo(left + radius, top + height)\n ctx.quadraticCurveTo(left, top + height, left, top + height - radius)\n //좌측 상단 모서리\n ctx.lineTo(left, top + radius)\n ctx.quadraticCurveTo(left, top, left + radius, top)\n ctx.stroke()\n ctx.closePath()\n //도형 색칠하기\n ctx.fillStyle = 'rgba(0, 0, 0, 0.8)'\n ctx.fill()\n}\n"]}