@things-factory/spc 7.0.0-alpha.6
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/CHANGELOG.md +8 -0
- package/client/bootstrap.ts +1 -0
- package/client/index.ts +0 -0
- package/client/pages/spc-chart-page.ts +118 -0
- package/client/route.ts +7 -0
- package/client/tsconfig.json +13 -0
- package/dist-client/bootstrap.d.ts +1 -0
- package/dist-client/bootstrap.js +2 -0
- package/dist-client/bootstrap.js.map +1 -0
- package/dist-client/index.d.ts +0 -0
- package/dist-client/index.js +2 -0
- package/dist-client/index.js.map +1 -0
- package/dist-client/pages/spc-chart-page.d.ts +26 -0
- package/dist-client/pages/spc-chart-page.js +121 -0
- package/dist-client/pages/spc-chart-page.js.map +1 -0
- package/dist-client/route.d.ts +1 -0
- package/dist-client/route.js +8 -0
- package/dist-client/route.js.map +1 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -0
- package/dist-server/controllers/data-use-case-spc.js +40 -0
- package/dist-server/controllers/data-use-case-spc.js.map +1 -0
- package/dist-server/controllers/index.js +5 -0
- package/dist-server/controllers/index.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/c.js +21 -0
- package/dist-server/controllers/spc-/bchart/c.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/histogram.js +27 -0
- package/dist-server/controllers/spc-/bchart/histogram.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/i.js +23 -0
- package/dist-server/controllers/spc-/bchart/i.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/index.js +172 -0
- package/dist-server/controllers/spc-/bchart/index.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/mr.js +24 -0
- package/dist-server/controllers/spc-/bchart/mr.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/np.js +23 -0
- package/dist-server/controllers/spc-/bchart/np.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/p.js +22 -0
- package/dist-server/controllers/spc-/bchart/p.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/pareto.js +25 -0
- package/dist-server/controllers/spc-/bchart/pareto.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/r.js +27 -0
- package/dist-server/controllers/spc-/bchart/r.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/u.js +24 -0
- package/dist-server/controllers/spc-/bchart/u.js.map +1 -0
- package/dist-server/controllers/spc-/bchart/x-bar.js +50 -0
- package/dist-server/controllers/spc-/bchart/x-bar.js.map +1 -0
- package/dist-server/index.js +11 -0
- package/dist-server/index.js.map +1 -0
- package/dist-server/service/index.js +21 -0
- package/dist-server/service/index.js.map +1 -0
- package/dist-server/service/spc-chart/index.js +8 -0
- package/dist-server/service/spc-chart/index.js.map +1 -0
- package/dist-server/service/spc-chart/spc-chart-query.js +198 -0
- package/dist-server/service/spc-chart/spc-chart-query.js.map +1 -0
- package/dist-server/service/spc-chart/spc-chart-type.js +148 -0
- package/dist-server/service/spc-chart/spc-chart-type.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -0
- package/helps/spc/spc-chart-concept.md +59 -0
- package/helps/spc/spc-chart.md +68 -0
- package/package.json +36 -0
- package/server/controllers/data-use-case-spc.ts +44 -0
- package/server/controllers/index.ts +1 -0
- package/server/controllers/spc-/bchart/c.ts +31 -0
- package/server/controllers/spc-/bchart/histogram.ts +40 -0
- package/server/controllers/spc-/bchart/i.ts +35 -0
- package/server/controllers/spc-/bchart/index.ts +171 -0
- package/server/controllers/spc-/bchart/mr.ts +37 -0
- package/server/controllers/spc-/bchart/np.ts +35 -0
- package/server/controllers/spc-/bchart/p.ts +34 -0
- package/server/controllers/spc-/bchart/pareto.ts +34 -0
- package/server/controllers/spc-/bchart/r.ts +40 -0
- package/server/controllers/spc-/bchart/u.ts +36 -0
- package/server/controllers/spc-/bchart/x-bar.ts +70 -0
- package/server/index.ts +10 -0
- package/server/service/index.ts +21 -0
- package/server/service/spc-chart/index.ts +5 -0
- package/server/service/spc-chart/spc-chart-query.ts +192 -0
- package/server/service/spc-chart/spc-chart-type.ts +103 -0
- package/server/tsconfig.json +10 -0
- package/things-factory.config.js +11 -0
- package/translations/en.json +1 -0
- package/translations/ja.json +1 -0
- package/translations/ko.json +1 -0
- package/translations/ms.json +1 -0
- package/translations/zh.json +1 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
## 품질 통계 제어 차트 (SPC) - 기본 이해
|
|
2
|
+
|
|
3
|
+
### 개요
|
|
4
|
+
|
|
5
|
+
품질 통계 제어 차트(SPC)는 제조 및 공정에서 제품 또는 서비스의 품질을 모니터링하고 제어하는 데 사용되는 강력한 도구입니다. SPC는 데이터를 수집하고 분석하여 공정 불안정성, 불규칙성 및 변동성을 식별하며 품질을 개선하는 데 도움이 됩니다.
|
|
6
|
+
|
|
7
|
+
### SPC의 목적
|
|
8
|
+
|
|
9
|
+
1. **품질 향상**: SPC는 제품 또는 서비스의 일관된 품질을 유지하고 개선하는 데 사용됩니다.
|
|
10
|
+
|
|
11
|
+
2. **불량 감소**: 불량품의 생산을 방지하고 불량율을 줄입니다.
|
|
12
|
+
|
|
13
|
+
3. **비용 절감**: 품질을 모니터링하고 개선함으로써 리워크 및 반송을 줄이고 생산 비용을 절감합니다.
|
|
14
|
+
|
|
15
|
+
### SPC 차트 종류
|
|
16
|
+
|
|
17
|
+
1. **X-Bar 및 R 차트**: 공정에서 나온 제품 또는 샘플의 평균 (X-Bar) 및 범위 (R)를 추적하여 공정의 안정성을 확인합니다. 이러한 차트는 연속 데이터에 사용됩니다.
|
|
18
|
+
|
|
19
|
+
2. **P 차트**: 비율 또는 비율 데이터의 불량률을 모니터링하는 데 사용됩니다.
|
|
20
|
+
|
|
21
|
+
3. **NP 차트**: 개별 항목의 불량 또는 불량이 아닌 개수를 추적하는 데 사용됩니다.
|
|
22
|
+
|
|
23
|
+
4. **C 차트**: 개별 항목의 불량 수를 추적하는 데 사용되며, 항목 수가 일정할 때 적합합니다.
|
|
24
|
+
|
|
25
|
+
5. **U 차트**: 개별 항목의 단위당 불량 수를 추적하는 데 사용됩니다.
|
|
26
|
+
|
|
27
|
+
6. **I 차트 (Individuals Chart)**: 개별 항목의 변동성을 추적하는 데 사용됩니다.
|
|
28
|
+
|
|
29
|
+
7. **MR 차트 (Moving Range Chart)**: 변동성이 불규칙하거나 시간에 따라 변할 때 개별 항목 간의 이동 범위를 추적합니다.
|
|
30
|
+
|
|
31
|
+
8. **Histogram 차트**: 데이터 분포를 히스토그램으로 표시하여 데이터의 분포 및 주요 특성을 시각화합니다.
|
|
32
|
+
|
|
33
|
+
9. **Pareto 차트**: 주요 원인 또는 카테고리를 중요도에 따라 시각화하여 가장 중요한 문제를 식별합니다.
|
|
34
|
+
|
|
35
|
+
### SPC의 주요 단계
|
|
36
|
+
|
|
37
|
+
1. **데이터 수집**: 공정 또는 제조과정에서 데이터를 수집하고 기록합니다.
|
|
38
|
+
|
|
39
|
+
2. **데이터 분석**: 수집한 데이터를 분석하여 통계적 특성을 확인하고 이상 현상을 탐지합니다.
|
|
40
|
+
|
|
41
|
+
3. **차트 작성**: 적절한 SPC 차트를 선택하고 데이터를 차트에 입력하여 표시합니다.
|
|
42
|
+
|
|
43
|
+
4. **관리 및 대응**: 차트를 모니터링하고 통계적 이상 현상 또는 규칙 위반을 식별하면 조치를 취하여 공정을 안정화하고 품질을 향상시킵니다.
|
|
44
|
+
|
|
45
|
+
### SPC의 이점
|
|
46
|
+
|
|
47
|
+
1. **품질 개선**: 불량품의 생산을 줄이고 제품 또는 서비스의 일관된 품질을 유지합니다.
|
|
48
|
+
|
|
49
|
+
2. **비용 절감**: 리워크 및 반송 비용을 감소시키며 생산 효율성을 높입니다.
|
|
50
|
+
|
|
51
|
+
3. **문제 식별**: 통계적 규칙을 통해 문제를 신속하게 식별하고 조치를 취할 수 있습니다.
|
|
52
|
+
|
|
53
|
+
4. **결정 기반**: 데이터에 기반한 의사 결정을 내릴 수 있으며, 과학적인 방법으로 문제를 해결합니다.
|
|
54
|
+
|
|
55
|
+
5. **고객 만족도 향상**: 일관된 품질로 인해 고객 만족도가 향상됩니다.
|
|
56
|
+
|
|
57
|
+
### 마무리
|
|
58
|
+
|
|
59
|
+
품질 통계 제어 차트(SPC)는 제조 및 공정에서 품질을 모니터링하고 제어하는 데 필수적인 도구입니다. 적절한 SPC 차트를 사용하고 데이터를 분석하여 품질 문제를 식별하고 해결함으로써 품질을 개선하고 비용을 절감할 수 있습니다. SPC는 효율적인 생산 및 고객 만족도 향상을 위한 중요한 도구 중 하나입니다.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
각각의 SPC(통계적 공정 통제) 차트는 다양한 특성을 가지고 있으며, 그 특성에 맞게 적절한 차트를 사용하여야 합니다.
|
|
2
|
+
|
|
3
|
+
1. **X-bar (X-막대) 차트**:
|
|
4
|
+
|
|
5
|
+
- **목적**: 공정에서 발생하는 평균값의 변화를 모니터링하고 제어합니다.
|
|
6
|
+
- **특성**: 평균값의 변화를 추적하며 중심 경향성을 확인합니다.
|
|
7
|
+
- **측정값**: 연속적인 데이터 (예: 제품 무게, 길이 등)
|
|
8
|
+
- **제어 한계선**: UCL(Upper Control Limit), LCL(Lower Control Limit)로 평균값의 허용 범위 설정
|
|
9
|
+
|
|
10
|
+
2. **R (범위) 차트**:
|
|
11
|
+
|
|
12
|
+
- **목적**: 공정의 변동성을 추적하고 제어합니다.
|
|
13
|
+
- **특성**: 데이터 범위의 변화를 확인하여 불규칙한 변동성을 감지합니다.
|
|
14
|
+
- **측정값**: 연속적인 데이터 (예: 제품 두께, 길이 등)
|
|
15
|
+
- **제어 한계선**: UCL, LCL로 범위의 허용 범위 설정
|
|
16
|
+
|
|
17
|
+
3. **P 차트**:
|
|
18
|
+
|
|
19
|
+
- **목적**: 이항 데이터(성공 또는 실패)에서 비율을 추적하고 제어합니다.
|
|
20
|
+
- **특성**: 비율의 변화를 확인하여 불량품 비율의 변화를 감지합니다.
|
|
21
|
+
- **측정값**: 이항 데이터 (예: 제품 불량 여부)
|
|
22
|
+
- **제어 한계선**: UCL, LCL로 비율의 허용 범위 설정
|
|
23
|
+
|
|
24
|
+
4. **NP 차트**:
|
|
25
|
+
|
|
26
|
+
- **목적**: 이항 데이터에서 표본 크기를 고려하여 비율을 추적하고 제어합니다.
|
|
27
|
+
- **특성**: 표본 크기를 고려한 비율의 변화를 확인하여 불량품 수의 변화를 감지합니다.
|
|
28
|
+
- **측정값**: 이항 데이터 및 표본 크기 (예: 제품 불량 여부 및 표본 크기)
|
|
29
|
+
- **제어 한계선**: UCL, LCL로 비율의 허용 범위 설정
|
|
30
|
+
|
|
31
|
+
5. **C 차트**:
|
|
32
|
+
|
|
33
|
+
- **목적**: 개수 데이터에서 불량 수를 추적하고 제어합니다.
|
|
34
|
+
- **특성**: 불량품 수의 변화를 확인하여 불량품 수의 변화를 감지합니다.
|
|
35
|
+
- **측정값**: 개수 데이터 (예: 결함 수)
|
|
36
|
+
- **제어 한계선**: UCL, LCL로 불량품 수의 허용 범위 설정
|
|
37
|
+
|
|
38
|
+
6. **U 차트**:
|
|
39
|
+
|
|
40
|
+
- **목적**: 개수 데이터에서 단위당 불량률을 추적하고 제어합니다.
|
|
41
|
+
- **특성**: 단위당 불량률의 변화를 확인하여 단위당 불량률의 변화를 감지합니다.
|
|
42
|
+
- **측정값**: 개수 데이터 (예: 결함 수) 및 단위 수
|
|
43
|
+
- **제어 한계선**: UCL, LCL로 단위당 불량률의 허용 범위 설정
|
|
44
|
+
|
|
45
|
+
7. **I 차트**:
|
|
46
|
+
|
|
47
|
+
- **목적**: 개별 항목의 품질을 추적하고 제어합니다.
|
|
48
|
+
- **특성**: 개별 항목의 변화를 확인하여 개별 항목의 품질 변화를 감지합니다.
|
|
49
|
+
- **측정값**: 연속적인 데이터 (예: 길이, 무게)
|
|
50
|
+
- **제어 한계선**: UCL, LCL로 개별 항목의 품질의 허용 범위 설정
|
|
51
|
+
|
|
52
|
+
8. **MR (이동 범위) 차트**:
|
|
53
|
+
|
|
54
|
+
- **목적**: 개별 항목의 이동 범위를 추적하고 제어합니다.
|
|
55
|
+
- **특성**: 이동 범위의 변화를 확인하여 개별 항목의 변동성 변화를 감지합니다.
|
|
56
|
+
- **측정값**: 연속적인 데이터 (예: 길이, 무게)
|
|
57
|
+
- **제어 한계선**: UCL, LCL로 이동 범위의 허용 범위 설정
|
|
58
|
+
|
|
59
|
+
9. **Histogram (히스토그램) 차트**:
|
|
60
|
+
|
|
61
|
+
- **목적**: 데이터 분포를 시각화하여 데이터의 분포를 이해하고 품질 문제를 발견하는 데 도움을 줍니다.
|
|
62
|
+
- **특성**: 데이터 분포를 막대 그래프로 표현하여 주요 특성을 확인합니다.
|
|
63
|
+
- **측정값**: 연속적인 데이터 (예: 제품 무게, 길이 등)
|
|
64
|
+
|
|
65
|
+
10. **Pareto (파레토) 차트**:
|
|
66
|
+
- **목적**: 주요 원인을 식별하고 우선 순위를 정하기 위한 도구로 사용됩니다.
|
|
67
|
+
- **특성**: 가장 중요한 원인부터 우선 순위대로 나열하여 시각화합니다.
|
|
68
|
+
- **측정값**: 주로 불량 종류 또는 문제 유형에 대한 데이터 (예: 불량 종류, 문제 유형)
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@things-factory/spc",
|
|
3
|
+
"version": "7.0.0-alpha.6",
|
|
4
|
+
"main": "dist-server/index.js",
|
|
5
|
+
"browser": "dist-client/index.js",
|
|
6
|
+
"things-factory": true,
|
|
7
|
+
"author": "heartyoh <heartyoh@hatiolab.com>",
|
|
8
|
+
"description": "module for handling SPC (Statistical Process Control)",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public",
|
|
12
|
+
"@things-factory:registry": "https://registry.npmjs.org"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/hatiolab/things-factory.git",
|
|
17
|
+
"directory": "packages/spc"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "npm run build:server && npm run build:client",
|
|
21
|
+
"copy:files": "copyfiles -e \"./client/**/*.{ts,js,json}\" -u 1 \"./client/**/*\" dist-client",
|
|
22
|
+
"build:client": "npm run copy:files && npx tsc --p ./client/tsconfig.json",
|
|
23
|
+
"build:server": "npx tsc --p ./server/tsconfig.json",
|
|
24
|
+
"clean:client": "npx rimraf dist-client",
|
|
25
|
+
"clean:server": "npx rimraf dist-server",
|
|
26
|
+
"clean": "npm run clean:server && npm run clean:client",
|
|
27
|
+
"migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@operato/dataset": "^2.0.0-alpha.0",
|
|
31
|
+
"@operato/spc": "^2.0.0-alpha.0",
|
|
32
|
+
"@things-factory/dataset": "^7.0.0-alpha.6",
|
|
33
|
+
"@things-factory/shell": "^7.0.0-alpha.6"
|
|
34
|
+
},
|
|
35
|
+
"gitHead": "cf46b4e03d6312f7ccb366a3c9fc2df16c68b7fa"
|
|
36
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { DataItemSpecSet, DataUseCase, EvaluationResult } from '@things-factory/dataset'
|
|
2
|
+
|
|
3
|
+
export class DataUseCaseSPC implements DataUseCase {
|
|
4
|
+
getSpecification(): DataItemSpecSet {
|
|
5
|
+
return {
|
|
6
|
+
name: 'SPC',
|
|
7
|
+
description: 'Statistical Process Control Data Spec',
|
|
8
|
+
help: '',
|
|
9
|
+
specs: [
|
|
10
|
+
{
|
|
11
|
+
type: 'spc-limits' /* 'A value which seperates acceptability from unacceptability' */,
|
|
12
|
+
label: 'control limits',
|
|
13
|
+
name: 'controlLimits'
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
evaluate(spec: any, values: any | any[]): EvaluationResult {
|
|
20
|
+
const { minimum, maximum, acceptables } = spec['controlLimits']
|
|
21
|
+
|
|
22
|
+
if (!(values instanceof Array)) {
|
|
23
|
+
values = [values]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < values.length; i++) {
|
|
27
|
+
const value = values[i]
|
|
28
|
+
|
|
29
|
+
if (minimum != null && value < minimum) {
|
|
30
|
+
return { oos: true, ooc: true }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (maximum != null && value > maximum) {
|
|
34
|
+
return { oos: true, ooc: true }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (acceptables != null && !acceptables.includes(value)) {
|
|
38
|
+
return { oos: true, ooc: true }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return { oos: false, ooc: false }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './data-use-case-spc'
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
interface CChartData {
|
|
2
|
+
period: string // 샘플 기간 또는 단위 식별자
|
|
3
|
+
defects: number // 해당 기간 또는 단위에서 발생한 결함 수
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
interface CChartResult {
|
|
7
|
+
CBar: number // 평균 결함 수
|
|
8
|
+
UCL: number // 상한 제어선
|
|
9
|
+
LCL: number // 하한 제어선
|
|
10
|
+
data: CChartData[] // 입력된 결함 데이터
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function calculateCChart(data: CChartData[]): CChartResult {
|
|
14
|
+
// 총 결함 수를 계산합니다.
|
|
15
|
+
const totalDefects = data.reduce((sum, { defects }) => sum + defects, 0)
|
|
16
|
+
|
|
17
|
+
// 평균 결함 수(C-bar)를 계산합니다.
|
|
18
|
+
const CBar = totalDefects / data.length
|
|
19
|
+
|
|
20
|
+
// 상한 제어선(UCL)과 하한 제어선(LCL)을 계산합니다.
|
|
21
|
+
// 포아송 분포를 가정할 때, UCL = C-bar + 3*sqrt(C-bar), LCL = C-bar - 3*sqrt(C-bar) (단, LCL이 음수인 경우 0으로 설정)
|
|
22
|
+
const UCL = CBar + 3 * Math.sqrt(CBar)
|
|
23
|
+
const LCL = Math.max(CBar - 3 * Math.sqrt(CBar), 0)
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
CBar,
|
|
27
|
+
UCL,
|
|
28
|
+
LCL,
|
|
29
|
+
data
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
interface HistogramSample {
|
|
2
|
+
value: number
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
interface HistogramBin {
|
|
6
|
+
binRange: string // 구간을 나타내는 문자열, 예: "0-1"
|
|
7
|
+
count: number // 해당 구간에 속하는 데이터의 개수
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface HistogramResult {
|
|
11
|
+
chartType: 'Histogram'
|
|
12
|
+
variableName: string // 분석 대상 변수 이름
|
|
13
|
+
bins: HistogramBin[] // 히스토그램의 각 구간과 해당 구간의 데이터 개수
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function calculateHistogram(samples: HistogramSample[], variableName: string, numBins: number): HistogramResult {
|
|
17
|
+
const values = samples.map(sample => sample.value)
|
|
18
|
+
const minValue = Math.min(...values)
|
|
19
|
+
const maxValue = Math.max(...values)
|
|
20
|
+
const range = maxValue - minValue
|
|
21
|
+
const binWidth = range / numBins
|
|
22
|
+
|
|
23
|
+
// 초기화된 구간 배열 생성
|
|
24
|
+
const bins: HistogramBin[] = Array.from({ length: numBins }, (_, i) => ({
|
|
25
|
+
binRange: `${(minValue + i * binWidth).toFixed(2)}-${(minValue + (i + 1) * binWidth).toFixed(2)}`,
|
|
26
|
+
count: 0
|
|
27
|
+
}))
|
|
28
|
+
|
|
29
|
+
// 각 샘플을 적절한 구간에 할당하고 개수를 세어 구간의 개수를 업데이트합니다.
|
|
30
|
+
samples.forEach(sample => {
|
|
31
|
+
const binIndex = Math.min(numBins - 1, Math.floor((sample.value - minValue) / binWidth))
|
|
32
|
+
bins[binIndex].count++
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
chartType: 'Histogram',
|
|
37
|
+
variableName,
|
|
38
|
+
bins
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
interface ISample {
|
|
2
|
+
sampleId: string
|
|
3
|
+
value: number // 개별 측정값
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
interface IChartResult {
|
|
7
|
+
chartType: 'I'
|
|
8
|
+
variableName: string
|
|
9
|
+
CL: number // 중심선
|
|
10
|
+
UCL: number // 상한 제어선
|
|
11
|
+
LCL: number // 하한 제어선
|
|
12
|
+
samples: ISample[] // 개별 측정값 배열
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function calculateIChartAnalysisResult(samples: ISample[], variableName: string): IChartResult {
|
|
16
|
+
// 개별 측정값의 평균을 계산하여 중심선(CL)을 구합니다.
|
|
17
|
+
const CL = samples.reduce((acc, sample) => acc + sample.value, 0) / samples.length
|
|
18
|
+
|
|
19
|
+
// 개별 측정값의 표준편차를 계산합니다.
|
|
20
|
+
const standardDeviation = Math.sqrt(samples.reduce((acc, sample) => acc + Math.pow(sample.value - CL, 2), 0) / samples.length)
|
|
21
|
+
|
|
22
|
+
// 공정 변동을 고려하여 상한 제어선(UCL)과 하한 제어선(LCL)을 계산합니다.
|
|
23
|
+
// 여기서는 3시그마(3 * 표준편차)를 사용합니다. 상황에 따라 적절한 시그마 수준을 조정할 수 있습니다.
|
|
24
|
+
const UCL = CL + 3 * standardDeviation
|
|
25
|
+
const LCL = CL - 3 * standardDeviation
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
chartType: 'I',
|
|
29
|
+
variableName,
|
|
30
|
+
CL,
|
|
31
|
+
UCL,
|
|
32
|
+
LCL,
|
|
33
|
+
samples
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
const result = {
|
|
2
|
+
dataset: {
|
|
3
|
+
id: 'aaa',
|
|
4
|
+
name: 'bbb'
|
|
5
|
+
},
|
|
6
|
+
query: {},
|
|
7
|
+
analysisResults: [
|
|
8
|
+
{
|
|
9
|
+
chartType: 'X-bar',
|
|
10
|
+
variables: [
|
|
11
|
+
{
|
|
12
|
+
name: 'variable1',
|
|
13
|
+
stats: {
|
|
14
|
+
mean: 22,
|
|
15
|
+
UCL: 25,
|
|
16
|
+
LCL: 19,
|
|
17
|
+
CL: 22
|
|
18
|
+
},
|
|
19
|
+
samples: [
|
|
20
|
+
{ sampleId: '1', value: 22 },
|
|
21
|
+
{ sampleId: '2', value: 23 }
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
chartType: 'R',
|
|
28
|
+
variables: [
|
|
29
|
+
{
|
|
30
|
+
name: 'variable2',
|
|
31
|
+
stats: {
|
|
32
|
+
range: 1.3,
|
|
33
|
+
UCL: 2.1,
|
|
34
|
+
LCL: 0.5,
|
|
35
|
+
CL: 1.3
|
|
36
|
+
},
|
|
37
|
+
samples: [
|
|
38
|
+
{ sampleId: '1', value: 1.2 },
|
|
39
|
+
{ sampleId: '2', value: 1.3 }
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
chartType: 'p',
|
|
46
|
+
variables: [
|
|
47
|
+
{
|
|
48
|
+
name: 'variable3',
|
|
49
|
+
stats: {
|
|
50
|
+
proportion: 0.05,
|
|
51
|
+
UCL: 0.1,
|
|
52
|
+
LCL: 0.01
|
|
53
|
+
},
|
|
54
|
+
samples: [
|
|
55
|
+
{ sampleId: '1', value: 0.05 },
|
|
56
|
+
{ sampleId: '2', value: 0.06 }
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
chartType: 'np',
|
|
63
|
+
variables: [
|
|
64
|
+
{
|
|
65
|
+
name: 'variable4',
|
|
66
|
+
stats: {
|
|
67
|
+
nonconforming: 5,
|
|
68
|
+
UCL: 10,
|
|
69
|
+
LCL: 1
|
|
70
|
+
},
|
|
71
|
+
samples: [
|
|
72
|
+
{ sampleId: '1', value: 5 },
|
|
73
|
+
{ sampleId: '2', value: 4 }
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
chartType: 'c',
|
|
80
|
+
variables: [
|
|
81
|
+
{
|
|
82
|
+
name: 'variable5',
|
|
83
|
+
stats: {
|
|
84
|
+
count: 20,
|
|
85
|
+
UCL: 25,
|
|
86
|
+
LCL: 15
|
|
87
|
+
},
|
|
88
|
+
samples: [
|
|
89
|
+
{ sampleId: '1', value: 20 },
|
|
90
|
+
{ sampleId: '2', value: 21 }
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
chartType: 'u',
|
|
97
|
+
variables: [
|
|
98
|
+
{
|
|
99
|
+
name: 'variable6',
|
|
100
|
+
stats: {
|
|
101
|
+
defectsPerUnit: 1.2,
|
|
102
|
+
UCL: 1.5,
|
|
103
|
+
LCL: 0.9
|
|
104
|
+
},
|
|
105
|
+
samples: [
|
|
106
|
+
{ sampleId: '1', value: 1.2 },
|
|
107
|
+
{ sampleId: '2', value: 1.1 }
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
chartType: 'I',
|
|
114
|
+
variables: [
|
|
115
|
+
{
|
|
116
|
+
name: 'variable7',
|
|
117
|
+
stats: {
|
|
118
|
+
individualValue: 10,
|
|
119
|
+
UCL: 12,
|
|
120
|
+
LCL: 8
|
|
121
|
+
},
|
|
122
|
+
samples: [
|
|
123
|
+
{ sampleId: '1', value: 10 },
|
|
124
|
+
{ sampleId: '2', value: 11 }
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
chartType: 'MR',
|
|
131
|
+
variables: [
|
|
132
|
+
{
|
|
133
|
+
name: 'variable8',
|
|
134
|
+
stats: {
|
|
135
|
+
movingRange: 2,
|
|
136
|
+
UCL: 3,
|
|
137
|
+
LCL: 1
|
|
138
|
+
},
|
|
139
|
+
samples: [
|
|
140
|
+
{ sampleId: '1', value: 2 },
|
|
141
|
+
{ sampleId: '2', value: 2.5 }
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
chartType: 'Histogram',
|
|
148
|
+
variables: [
|
|
149
|
+
{
|
|
150
|
+
name: 'variable9',
|
|
151
|
+
bins: [
|
|
152
|
+
{ binRange: '0-1', count: 5 },
|
|
153
|
+
{ binRange: '1-2', count: 10 }
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
chartType: 'Pareto',
|
|
160
|
+
variables: [
|
|
161
|
+
{
|
|
162
|
+
name: 'defectType',
|
|
163
|
+
categories: [
|
|
164
|
+
{ category: 'Scratch', count: 20 },
|
|
165
|
+
{ category: 'Dent', count: 15 }
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
interface MRSample {
|
|
2
|
+
sampleId: string
|
|
3
|
+
value: number // 측정값
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
interface MRChartResult {
|
|
7
|
+
chartType: 'MR'
|
|
8
|
+
variableName: string
|
|
9
|
+
CL: number // 중심선
|
|
10
|
+
UCL: number // 상한 제어선
|
|
11
|
+
LCL: number // 하한 제어선 (MR 차트에서는 일반적으로 0으로 설정됩니다)
|
|
12
|
+
movingRanges: number[] // 연속된 측정값 간의 변동 범위
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function calculateMRChartAnalysisResult(samples: MRSample[], variableName: string): MRChartResult {
|
|
16
|
+
// 연속된 측정값 간의 변동 범위를 계산합니다.
|
|
17
|
+
const movingRanges = samples.slice(1).map((sample, index) => Math.abs(sample.value - samples[index].value))
|
|
18
|
+
|
|
19
|
+
// 변동 범위의 평균을 계산하여 중심선(CL)을 구합니다.
|
|
20
|
+
const CL = movingRanges.reduce((acc, range) => acc + range, 0) / movingRanges.length
|
|
21
|
+
|
|
22
|
+
// 공정 변동을 고려하여 상한 제어선(UCL)을 계산합니다.
|
|
23
|
+
// MR 차트에서는 3.267 * MR-Bar을 사용합니다 (2개의 측정값을 사용하는 경우).
|
|
24
|
+
const UCL = 3.267 * CL
|
|
25
|
+
|
|
26
|
+
// MR 차트에서 하한 제어선(LCL)은 일반적으로 사용되지 않거나 0으로 설정됩니다.
|
|
27
|
+
const LCL = 0 // 하한 제어선
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
chartType: 'MR',
|
|
31
|
+
variableName,
|
|
32
|
+
CL,
|
|
33
|
+
UCL,
|
|
34
|
+
LCL,
|
|
35
|
+
movingRanges
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
interface NPSampleGroup {
|
|
2
|
+
groupId: string
|
|
3
|
+
nonConforming: number // 각 샘플 그룹의 불량품 수
|
|
4
|
+
totalUnits: number // 샘플 그룹의 총 단위 수
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface NPChartResult {
|
|
8
|
+
chartType: 'NP'
|
|
9
|
+
variableName: string
|
|
10
|
+
NPBar: number // 샘플 그룹의 평균 불량품 수
|
|
11
|
+
UCL: number
|
|
12
|
+
LCL: number
|
|
13
|
+
sampleGroups: NPSampleGroup[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function calculateNPChartAnalysisResult(sampleGroups: NPSampleGroup[], variableName: string): NPChartResult {
|
|
17
|
+
const totalNonConforming = sampleGroups.reduce((acc, group) => acc + group.nonConforming, 0)
|
|
18
|
+
const totalUnits = sampleGroups.reduce((acc, group) => acc + group.totalUnits, 0)
|
|
19
|
+
const NPBar = totalNonConforming / sampleGroups.length // 평균 불량품 수
|
|
20
|
+
|
|
21
|
+
// p 차트 공식을 사용하여 UCL과 LCL을 계산합니다.
|
|
22
|
+
const pBar = totalNonConforming / totalUnits // 전체 불량품 비율
|
|
23
|
+
const UCL = NPBar + 3 * Math.sqrt(NPBar * (1 - pBar))
|
|
24
|
+
let LCL = NPBar - 3 * Math.sqrt(NPBar * (1 - pBar))
|
|
25
|
+
LCL = LCL < 0 ? 0 : LCL // LCL이 음수인 경우 0으로 설정
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
chartType: 'NP',
|
|
29
|
+
variableName,
|
|
30
|
+
NPBar,
|
|
31
|
+
UCL,
|
|
32
|
+
LCL,
|
|
33
|
+
sampleGroups
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
interface PSampleGroup {
|
|
2
|
+
groupId: string // 샘플 그룹 ID
|
|
3
|
+
defectiveUnits: number // 그룹 내 결함 있는 단위 수
|
|
4
|
+
totalUnits: number // 그룹 내 총 단위 수
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface PChartResult {
|
|
8
|
+
chartType: 'P'
|
|
9
|
+
variableName: string
|
|
10
|
+
PBar: number // 결함 있는 단위의 평균 비율
|
|
11
|
+
UCL: number // 상한 제어선
|
|
12
|
+
LCL: number // 하한 제어선
|
|
13
|
+
sampleGroups: PSampleGroup[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function calculatePChartAnalysisResult(sampleGroups: PSampleGroup[], variableName: string): PChartResult {
|
|
17
|
+
// 결함 있는 단위의 평균 비율(PBar)을 계산합니다.
|
|
18
|
+
const totalDefectiveUnits = sampleGroups.reduce((acc, group) => acc + group.defectiveUnits, 0)
|
|
19
|
+
const totalUnits = sampleGroups.reduce((acc, group) => acc + group.totalUnits, 0)
|
|
20
|
+
const PBar = totalDefectiveUnits / totalUnits
|
|
21
|
+
|
|
22
|
+
// 샘플 그룹의 크기(n)에 따라 UCL과 LCL을 계산합니다.
|
|
23
|
+
const UCL = PBar + 3 * Math.sqrt((PBar * (1 - PBar)) / totalUnits)
|
|
24
|
+
const LCL = PBar - 3 * Math.sqrt((PBar * (1 - PBar)) / totalUnits) < 0 ? 0 : PBar - 3 * Math.sqrt((PBar * (1 - PBar)) / totalUnits) // LCL이 음수가 되지 않도록 처리
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
chartType: 'P',
|
|
28
|
+
variableName,
|
|
29
|
+
PBar,
|
|
30
|
+
UCL,
|
|
31
|
+
LCL,
|
|
32
|
+
sampleGroups
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
interface ParetoCategory {
|
|
2
|
+
category: string // 카테고리 이름
|
|
3
|
+
count: number // 해당 카테고리의 데이터 개수 또는 중요도
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
interface ParetoResult {
|
|
7
|
+
chartType: 'Pareto'
|
|
8
|
+
variableName: string // 분석 대상 변수 이름
|
|
9
|
+
categories: ParetoCategory[] // Pareto 차트에 표시될 카테고리 및 중요도 정보
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function calculatePareto(data: { category: string }[], variableName: string): ParetoResult {
|
|
13
|
+
// 각 카테고리별 데이터 개수 계산
|
|
14
|
+
const categoryCounts: { [category: string]: number } = {}
|
|
15
|
+
data.forEach(item => {
|
|
16
|
+
const category = item.category
|
|
17
|
+
categoryCounts[category] = (categoryCounts[category] || 0) + 1
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
// 카테고리와 데이터 개수를 배열로 변환
|
|
21
|
+
const categories: ParetoCategory[] = Object.keys(categoryCounts).map(category => ({
|
|
22
|
+
category,
|
|
23
|
+
count: categoryCounts[category]
|
|
24
|
+
}))
|
|
25
|
+
|
|
26
|
+
// 데이터 개수에 따라 내림차순으로 정렬
|
|
27
|
+
categories.sort((a, b) => b.count - a.count)
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
chartType: 'Pareto',
|
|
31
|
+
variableName,
|
|
32
|
+
categories
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
interface SampleGroup {
|
|
2
|
+
groupId: string
|
|
3
|
+
values: number[]
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
interface RChartResult {
|
|
7
|
+
chartType: 'R'
|
|
8
|
+
variableName: string
|
|
9
|
+
RBar: number
|
|
10
|
+
UCL: number
|
|
11
|
+
LCL: number
|
|
12
|
+
sampleGroups: SampleGroup[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function calculateRChartAnalysisResult(sampleGroups: SampleGroup[], variableName: string): RChartResult {
|
|
16
|
+
// 각 샘플 그룹의 범위를 계산합니다.
|
|
17
|
+
const ranges = sampleGroups.map(group => Math.max(...group.values) - Math.min(...group.values))
|
|
18
|
+
|
|
19
|
+
// 모든 샘플 그룹의 범위의 평균값(R-bar)을 계산합니다.
|
|
20
|
+
const RBar = ranges.reduce((acc, cur) => acc + cur, 0) / ranges.length
|
|
21
|
+
|
|
22
|
+
// 샘플 그룹의 크기(n)에 따라 D3와 D4 값을 설정합니다.
|
|
23
|
+
// 예시에서는 n=5인 경우의 D3와 D4 값을 사용합니다. 실제 구현에서는 샘플 크기에 맞는 값을 사용해야 합니다.
|
|
24
|
+
const n = sampleGroups[0].values.length // 가정: 모든 샘플 그룹의 크기가 동일합니다.
|
|
25
|
+
const D3 = 0 // n=5에 대한 D3 값
|
|
26
|
+
const D4 = 2.114 // n=5에 대한 D4 값
|
|
27
|
+
|
|
28
|
+
// UCL과 LCL을 계산합니다.
|
|
29
|
+
const UCL = D4 * RBar
|
|
30
|
+
const LCL = D3 * RBar // D3가 0인 경우, LCL은 0이 됩니다.
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
chartType: 'R',
|
|
34
|
+
variableName,
|
|
35
|
+
RBar,
|
|
36
|
+
UCL,
|
|
37
|
+
LCL,
|
|
38
|
+
sampleGroups
|
|
39
|
+
}
|
|
40
|
+
}
|