@dssp/dkpi 1.0.0-alpha.86 → 1.0.0-alpha.88
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/_index.html +4 -4
- package/assets/helps/index.md +1 -1
- package/assets/manifest.json +2 -2
- package/dist-client/components/kpi-boxplot-chart.d.ts +7 -0
- package/dist-client/components/kpi-boxplot-chart.js +20 -5
- package/dist-client/components/kpi-boxplot-chart.js.map +1 -1
- package/dist-client/components/kpi-lookup-chart.js +1 -17
- package/dist-client/components/kpi-lookup-chart.js.map +1 -1
- package/dist-client/components/kpi-radar-chart.js +2 -2
- package/dist-client/components/kpi-radar-chart.js.map +1 -1
- package/dist-client/components/kpi-single-boxplot-chart.d.ts +7 -0
- package/dist-client/components/kpi-single-boxplot-chart.js +27 -26
- package/dist-client/components/kpi-single-boxplot-chart.js.map +1 -1
- package/dist-client/components/kpi-step-lookup-chart.d.ts +33 -0
- package/dist-client/components/kpi-step-lookup-chart.js +181 -0
- package/dist-client/components/kpi-step-lookup-chart.js.map +1 -0
- package/dist-client/components/kpi-trend-chart.js +2 -12
- package/dist-client/components/kpi-trend-chart.js.map +1 -1
- package/dist-client/google-map/common-google-map.js +5 -1
- package/dist-client/google-map/common-google-map.js.map +1 -1
- package/dist-client/pages/kpi-admin/dssp-kpi-overview.d.ts +2 -1
- package/dist-client/pages/kpi-admin/dssp-kpi-overview.js +24 -9
- package/dist-client/pages/kpi-admin/dssp-kpi-overview.js.map +1 -1
- package/dist-client/pages/kpi-admin/kpi-system-guide.js +311 -158
- package/dist-client/pages/kpi-admin/kpi-system-guide.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.d.ts +6 -0
- package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js +110 -50
- package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.d.ts +0 -9
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js +6 -91
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.d.ts +2 -0
- package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js +148 -68
- package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js +85 -41
- package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/kpi-dashboard.js +15 -7
- package/dist-client/pages/kpi-dashboard/kpi-dashboard.js.map +1 -1
- package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js +16 -25
- package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js.map +1 -1
- package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js +9 -13
- package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js.map +1 -1
- package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js +9 -15
- package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js.map +1 -1
- package/dist-client/pages/sv-project-complete.js +7 -11
- package/dist-client/pages/sv-project-complete.js.map +1 -1
- package/dist-client/pages/sv-project-completed-list.js +4 -4
- package/dist-client/pages/sv-project-completed-list.js.map +1 -1
- package/dist-client/pages/sv-project-detail.d.ts +1 -0
- package/dist-client/pages/sv-project-detail.js +94 -82
- package/dist-client/pages/sv-project-detail.js.map +1 -1
- package/dist-client/pages/sv-project-list.js +15 -12
- package/dist-client/pages/sv-project-list.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/viewparts/menu-tools.js +17 -3
- package/dist-client/viewparts/menu-tools.js.map +1 -1
- package/dist-server/service/kpi-stat/kpi-stat-query.js +20 -19
- package/dist-server/service/kpi-stat/kpi-stat-query.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/openapi/unstable.yaml +2 -2
- package/package.json +3 -3
- package/schema.graphql +20 -0
- package/translations/ko.json +2 -2
- package/views/auth-page.html +4 -4
- package/views/public/home.html +5 -5
|
@@ -13,6 +13,7 @@ import '../components/kpi-boxplot-chart';
|
|
|
13
13
|
import '../components/kpi-single-boxplot-chart';
|
|
14
14
|
import '../components/kpi-radar-chart';
|
|
15
15
|
import '../components/kpi-lookup-chart';
|
|
16
|
+
import '../components/kpi-step-lookup-chart';
|
|
16
17
|
import '../components/kpi-2d-lookup-chart';
|
|
17
18
|
let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(PageView) {
|
|
18
19
|
constructor() {
|
|
@@ -31,13 +32,11 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
31
32
|
get context() {
|
|
32
33
|
var _a;
|
|
33
34
|
return {
|
|
34
|
-
title: !isProjectTypeDomain() && this.project
|
|
35
|
-
? `프로젝트 상세 정보 - ${(_a = this.project) === null || _a === void 0 ? void 0 : _a.name}`
|
|
36
|
-
: '프로젝트 상세 정보'
|
|
35
|
+
title: !isProjectTypeDomain() && this.project ? `프로젝트 상세 정보 - ${(_a = this.project) === null || _a === void 0 ? void 0 : _a.name}` : '프로젝트 상세 정보'
|
|
37
36
|
};
|
|
38
37
|
}
|
|
39
38
|
render() {
|
|
40
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
39
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
41
40
|
return html `
|
|
42
41
|
<div content>
|
|
43
42
|
<div left>
|
|
@@ -59,7 +58,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
59
58
|
<div class="value">${this.project.startDate} ~ ${this.project.endDate}</div>
|
|
60
59
|
</div>
|
|
61
60
|
<div class="row">
|
|
62
|
-
<div class="label">•
|
|
61
|
+
<div class="label">• 프로젝트 상태</div>
|
|
63
62
|
<div class="value status-value">${PROJECT_STATE[this.project.state]}</div>
|
|
64
63
|
</div>
|
|
65
64
|
<div class="row">
|
|
@@ -96,15 +95,11 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
96
95
|
</div>
|
|
97
96
|
<div class="grid-item row">
|
|
98
97
|
<div class="label">• 용적률</div>
|
|
99
|
-
<div class="value">
|
|
100
|
-
${((_h = (_g = this.project.buildingComplex) === null || _g === void 0 ? void 0 : _g.floorAreaRatio) === null || _h === void 0 ? void 0 : _h.toLocaleString()) || '-'} %
|
|
101
|
-
</div>
|
|
98
|
+
<div class="value">${((_h = (_g = this.project.buildingComplex) === null || _g === void 0 ? void 0 : _g.floorAreaRatio) === null || _h === void 0 ? void 0 : _h.toLocaleString()) || '-'} %</div>
|
|
102
99
|
</div>
|
|
103
100
|
<div class="grid-item row">
|
|
104
|
-
<div class="label">•
|
|
105
|
-
<div class="value">
|
|
106
|
-
${((_k = (_j = this.project.buildingComplex) === null || _j === void 0 ? void 0 : _j.workerCount) === null || _k === void 0 ? void 0 : _k.toLocaleString()) || '-'} 명
|
|
107
|
-
</div>
|
|
101
|
+
<div class="label">• 총 투입인력(M/M)</div>
|
|
102
|
+
<div class="value">${((_k = (_j = this.project.buildingComplex) === null || _j === void 0 ? void 0 : _j.workerCount) === null || _k === void 0 ? void 0 : _k.toLocaleString()) || '-'} 명</div>
|
|
108
103
|
</div>
|
|
109
104
|
</div>
|
|
110
105
|
</div>
|
|
@@ -214,14 +209,13 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
214
209
|
<div class="card group-box">
|
|
215
210
|
<div class="kpi-header">
|
|
216
211
|
<div>
|
|
217
|
-
<div
|
|
212
|
+
<div>성과영역별 KPI</div>
|
|
218
213
|
<div class="triangle"></div>
|
|
219
214
|
</div>
|
|
220
215
|
</div>
|
|
221
216
|
<div class="desc">
|
|
222
|
-
Boxplot(박스플롯)은
|
|
223
|
-
|
|
224
|
-
이 프로젝트의 값은 진한 오렌지색 원으로 별도 강조되어 표시되며, 중앙값/평균과 다를 수 있습니다.
|
|
217
|
+
Boxplot(박스플롯)은 박스는 중앙 50% 구간, 수염은 전체 범위, 굵은 파란색 가로선은 중앙값(median), 초록색 원은
|
|
218
|
+
평균값(Mean)을 의미합니다. 당해 프로젝트의 값은 붉은색 원으로 표시됩니다.
|
|
225
219
|
</div>
|
|
226
220
|
<div class="group-chart">
|
|
227
221
|
<sv-kpi-boxplot-chart .data=${this.getYKpiBoxplotData()}></sv-kpi-boxplot-chart>
|
|
@@ -231,7 +225,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
231
225
|
<div class="metrics-card">
|
|
232
226
|
<div class="metrics-header">
|
|
233
227
|
<div class="title">
|
|
234
|
-
<span
|
|
228
|
+
<span>성과영역별 KPI 측정값</span>
|
|
235
229
|
<div class="triangle"></div>
|
|
236
230
|
</div>
|
|
237
231
|
</div>
|
|
@@ -276,38 +270,48 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
276
270
|
${this.selectedKpi.score !== undefined && this.selectedKpi.score !== null
|
|
277
271
|
? html `
|
|
278
272
|
<div class="popup-score">
|
|
279
|
-
<span class="score-value">${parseFloat(Number(this.selectedKpi.score).toFixed(
|
|
280
|
-
<span class="score-label">점</span>
|
|
273
|
+
<span class="score-value">${parseFloat(Number(this.selectedKpi.score).toFixed(2))}</span>
|
|
281
274
|
</div>
|
|
282
275
|
`
|
|
283
276
|
: ''}
|
|
284
277
|
<button class="popup-close" @click=${this._closePopup}>×</button>
|
|
285
278
|
</div>
|
|
286
279
|
<div class="popup-chart-container">
|
|
287
|
-
${ /*
|
|
288
|
-
* scoreType 기반 차트 분기:
|
|
289
|
-
*
|
|
290
|
-
* CUSTOM (X13 등): 2D 룩업 히트맵 — 단, 증강데이터에서는 value가
|
|
291
|
-
* 이미 1~5 정수(룩업 결과)이므로 히트맵 대신 게이지로 폴백.
|
|
292
|
-
* 실제 프로젝트에서는 value가 편차율(소수점)이므로 히트맵 표시.
|
|
293
|
-
*
|
|
294
|
-
* LOOKUP: 성과 분포 커브 (kpi-lookup-chart)
|
|
295
|
-
* ASSESSMENT: 5단계 게이지 (kpi-lookup-chart 자동 감지)
|
|
296
|
-
*/''}
|
|
297
280
|
${
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
281
|
+
/*
|
|
282
|
+
* scoreType 기반 차트 분기:
|
|
283
|
+
*
|
|
284
|
+
* CUSTOM (X13 등): 2D 룩업 히트맵 — 단, 증강데이터에서는 value가
|
|
285
|
+
* 이미 1~5 정수(룩업 결과)이므로 히트맵 대신 게이지로 폴백.
|
|
286
|
+
* 실제 프로젝트에서는 value가 편차율(소수점)이므로 히트맵 표시.
|
|
287
|
+
*
|
|
288
|
+
* LOOKUP: 성과 분포 커브 (kpi-lookup-chart)
|
|
289
|
+
* ASSESSMENT: 5단계 게이지 (kpi-lookup-chart 자동 감지)
|
|
290
|
+
*/ ''}
|
|
291
|
+
${
|
|
292
|
+
// SL-PA 결과(X34 품질, X43 안전) 만 계단형 등급 분포 차트로 표시.
|
|
293
|
+
// (다른 KPI 차트 경로에는 영향 없음)
|
|
294
|
+
this.selectedKpi.pattern === 'X34' || this.selectedKpi.pattern === 'X43'
|
|
295
|
+
? html `
|
|
296
|
+
<kpi-step-lookup-chart
|
|
297
|
+
.grades=${this.selectedKpi.grades || []}
|
|
298
|
+
.value=${this.selectedKpi.value}
|
|
299
|
+
.score=${(_l = this.selectedKpi.score) !== null && _l !== void 0 ? _l : null}
|
|
300
|
+
unit=${this.selectedKpi.unit || ''}
|
|
301
|
+
></kpi-step-lookup-chart>
|
|
302
|
+
`
|
|
303
|
+
: // 2D lookup KPI (X13 등) 는 항상 등급 기준 + 히트맵 함께 표시 (value 가
|
|
304
|
+
// 정수든 소수든 일관). _renderAssessmentGrades 안의 is2D 분기가 히트맵
|
|
305
|
+
// 같이 그림. 그 외 ASSESSMENT 도 등급 기준, LOOKUP 은 분포 커브.
|
|
306
|
+
this.selectedKpi.scoreType === 'CUSTOM' || ((_m = this.selectedKpi.grades) === null || _m === void 0 ? void 0 : _m.type) === 'PROGRESS_DEVIATION_LOOKUP'
|
|
307
|
+
? this._renderAssessmentGrades()
|
|
308
|
+
: this._isAssessmentOrIntegerScore()
|
|
309
|
+
? this._renderAssessmentGrades()
|
|
310
|
+
: html `
|
|
307
311
|
<kpi-lookup-chart
|
|
308
312
|
.grades=${this.selectedKpi.grades || []}
|
|
309
313
|
.value=${this.selectedKpi.value}
|
|
310
|
-
.score=${(
|
|
314
|
+
.score=${(_o = this.selectedKpi.score) !== null && _o !== void 0 ? _o : null}
|
|
311
315
|
.scoreType=${this.selectedKpi.scoreType || ''}
|
|
312
316
|
.valueType=${this.selectedKpi.valueType || ''}
|
|
313
317
|
unit=${this.selectedKpi.unit || ''}
|
|
@@ -520,10 +524,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
520
524
|
const hasValid = (v) => v.value !== null && v.value !== undefined;
|
|
521
525
|
this.pendingMetrics = targets.filter((m) => {
|
|
522
526
|
if (m.periodType === 'MONTH') {
|
|
523
|
-
return !values.some(v => v.metricId === m.id &&
|
|
524
|
-
v.periodType === 'MONTH' &&
|
|
525
|
-
(v.valueDate || '').startsWith(lastMonthYm) &&
|
|
526
|
-
hasValid(v));
|
|
527
|
+
return !values.some(v => v.metricId === m.id && v.periodType === 'MONTH' && (v.valueDate || '').startsWith(lastMonthYm) && hasValid(v));
|
|
527
528
|
}
|
|
528
529
|
return !values.some(v => v.metricId === m.id && v.periodType === m.periodType && hasValid(v));
|
|
529
530
|
});
|
|
@@ -662,6 +663,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
662
663
|
}
|
|
663
664
|
this.selectedKpi = {
|
|
664
665
|
kpiName: displayName,
|
|
666
|
+
pattern: kpiNamePattern, // X34/X43 등 — 계단형 차트 라우팅용
|
|
665
667
|
grades: kpi.grades || [],
|
|
666
668
|
scoreType: kpi.scoreType || '',
|
|
667
669
|
valueType: kpi.valueType || '',
|
|
@@ -709,8 +711,12 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
709
711
|
const currentScore = (kpi === null || kpi === void 0 ? void 0 : kpi.score) != null ? Math.round(kpi.score) : 0;
|
|
710
712
|
const grades = Array.isArray(kpi === null || kpi === void 0 ? void 0 : kpi.grades) ? kpi.grades : [];
|
|
711
713
|
const colors = ['#e53935', '#ff9800', '#ffca28', '#66bb6a', '#2e7d32'];
|
|
712
|
-
const is2D = (kpi === null || kpi === void 0 ? void 0 : kpi.scoreType) === 'CUSTOM' ||
|
|
713
|
-
(
|
|
714
|
+
const is2D = (kpi === null || kpi === void 0 ? void 0 : kpi.scoreType) === 'CUSTOM' ||
|
|
715
|
+
(kpi === null || kpi === void 0 ? void 0 : kpi.valueType) === 'COMPOSITE' ||
|
|
716
|
+
((kpi === null || kpi === void 0 ? void 0 : kpi.grades) &&
|
|
717
|
+
typeof kpi.grades === 'object' &&
|
|
718
|
+
!Array.isArray(kpi.grades) &&
|
|
719
|
+
kpi.grades.type === 'PROGRESS_DEVIATION_LOOKUP');
|
|
714
720
|
// grades가 있으면 description 사용, 없으면 기본 라벨
|
|
715
721
|
const defaultLabels = ['매우 미흡', '미흡', '보통', '양호', '우수'];
|
|
716
722
|
const items = [1, 2, 3, 4, 5].map(score => {
|
|
@@ -730,8 +736,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
730
736
|
return html `
|
|
731
737
|
<div style="padding: 20px; display: flex; flex-direction: column; height: 100%;">
|
|
732
738
|
${hasDescriptions
|
|
733
|
-
? items.map(item => html `
|
|
734
|
-
<div
|
|
739
|
+
? items.map(item => html ` <div
|
|
735
740
|
style="
|
|
736
741
|
display: flex; align-items: center; gap: 10px;
|
|
737
742
|
padding: 10px 14px; margin-bottom: 6px;
|
|
@@ -749,13 +754,17 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
749
754
|
display: flex; align-items: center; justify-content: center;
|
|
750
755
|
font-weight: 700; font-size: 14px; flex-shrink: 0;
|
|
751
756
|
"
|
|
752
|
-
|
|
753
|
-
|
|
757
|
+
>${item.score}</span
|
|
758
|
+
>
|
|
759
|
+
<span
|
|
760
|
+
style="font-size: 0.9rem; color: ${item.active ? '#333' : '#666'}; font-weight: ${item.active
|
|
761
|
+
? '600'
|
|
762
|
+
: '400'};"
|
|
763
|
+
>
|
|
754
764
|
${item.desc}
|
|
755
765
|
</span>
|
|
756
766
|
</div>`)
|
|
757
767
|
: ''}
|
|
758
|
-
|
|
759
768
|
${is2D && ((_a = kpi === null || kpi === void 0 ? void 0 : kpi.grades) === null || _a === void 0 ? void 0 : _a.rows)
|
|
760
769
|
? html `
|
|
761
770
|
<div style="flex: 1; display: flex; flex-direction: column; min-height: 0;">
|
|
@@ -800,30 +809,30 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
800
809
|
return {
|
|
801
810
|
Y1: {
|
|
802
811
|
name: '일정성과 (Y1)',
|
|
803
|
-
score: this.getYKpiScoreFormatted('Y1
|
|
812
|
+
score: this.getYKpiScoreFormatted('일정성과(Y1)'),
|
|
804
813
|
metrics: [
|
|
805
814
|
{ label: '연면적 대비 공사기간', pattern: 'X11', value: this.getMetricValue('X11') },
|
|
806
815
|
{ label: '설계변경 공기 증감률', pattern: 'X12', value: this.getMetricValue('X12') },
|
|
807
816
|
{ label: '일정 이탈 수준', pattern: 'X13', value: this.getMetricValue('X13') },
|
|
808
|
-
{ label: '일정성과
|
|
817
|
+
{ label: '일정성과 정성 평가', pattern: 'X14', value: this.getMetricValue('X14') }
|
|
809
818
|
]
|
|
810
819
|
},
|
|
811
820
|
Y2: {
|
|
812
821
|
name: '비용성과 (Y2)',
|
|
813
|
-
score: this.getYKpiScoreFormatted('Y2
|
|
822
|
+
score: this.getYKpiScoreFormatted('비용성과(Y2)'),
|
|
814
823
|
metrics: [
|
|
815
824
|
{ label: '연면적 대비 공사비', pattern: 'X21', value: this.getMetricValue('X21') },
|
|
816
|
-
{ label: '설계변경 공사비
|
|
817
|
-
{ label: '
|
|
825
|
+
{ label: '설계변경 공사비 증감률', pattern: 'X22', value: this.getMetricValue('X22') },
|
|
826
|
+
{ label: '비용성과 정성 평가', pattern: 'X23', value: this.getMetricValue('X23') }
|
|
818
827
|
]
|
|
819
828
|
},
|
|
820
829
|
Y3: {
|
|
821
830
|
name: '품질성과 (Y3)',
|
|
822
|
-
score: this.getYKpiScoreFormatted('Y3
|
|
831
|
+
score: this.getYKpiScoreFormatted('품질성과(Y3)'),
|
|
823
832
|
metrics: [
|
|
824
833
|
{ label: '검측 불합격률', pattern: 'X33', value: this.getMetricValue('X33') },
|
|
825
834
|
{ label: '품질 SL-PA 결과', pattern: 'X34', value: this.getMetricValue('X34') },
|
|
826
|
-
{ label: '품질성과
|
|
835
|
+
{ label: '품질성과 정성 평가', pattern: 'X35', value: this.getMetricValue('X35') }
|
|
827
836
|
]
|
|
828
837
|
},
|
|
829
838
|
Y4: {
|
|
@@ -833,41 +842,43 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
833
842
|
{ label: '재해율', pattern: 'X41', value: this.getMetricValue('X41') },
|
|
834
843
|
{ label: '재해강도율', pattern: 'X42', value: this.getMetricValue('X42') },
|
|
835
844
|
{ label: '안전 SL-PA 결과', pattern: 'X43', value: this.getMetricValue('X43') },
|
|
836
|
-
{ label: '안전성과
|
|
845
|
+
{ label: '안전성과 정성 평가', pattern: 'X44', value: this.getMetricValue('X44') }
|
|
837
846
|
]
|
|
838
847
|
},
|
|
839
848
|
Y5: {
|
|
840
849
|
name: '환경성과 (Y5)',
|
|
841
|
-
score: this.getYKpiScoreFormatted('Y5
|
|
850
|
+
score: this.getYKpiScoreFormatted('환경성과(Y5)'),
|
|
842
851
|
metrics: [
|
|
843
852
|
{ label: '건설폐기물 발생량', pattern: 'X51', value: this.getMetricValue('X51') },
|
|
844
|
-
{ label: '환경성과
|
|
853
|
+
{ label: '환경성과 정성 평가', pattern: 'X52', value: this.getMetricValue('X52') }
|
|
845
854
|
]
|
|
846
855
|
},
|
|
847
856
|
Y6: {
|
|
848
857
|
name: '생산성 성과 (Y6)',
|
|
849
|
-
score: this.getYKpiScoreFormatted('Y6
|
|
858
|
+
score: this.getYKpiScoreFormatted('생산성성과(Y6)'),
|
|
850
859
|
metrics: [
|
|
851
|
-
{ label: '투입인력 생산성', pattern: 'X61', value: this.getMetricValue('X61') },
|
|
852
|
-
{ label: '생산성성과
|
|
860
|
+
{ label: '총 투입인력(M/M) 생산성', pattern: 'X61', value: this.getMetricValue('X61') },
|
|
861
|
+
{ label: '생산성성과 정성 평가', pattern: 'X62', value: this.getMetricValue('X62') }
|
|
853
862
|
]
|
|
854
863
|
}
|
|
855
864
|
};
|
|
856
865
|
}
|
|
857
866
|
getYKpiBoxplotData() {
|
|
858
|
-
//
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
867
|
+
// kpiName 표기가 환경마다 다양('Y1. 일정성과' / 'Y1. 일정' / '일정성과(Y1)' 등)하므로
|
|
868
|
+
// Y1~Y6 코드만 추출해 짧은 X축 라벨로 매핑 — 전체 문자열에 의존하지 않아 견고함.
|
|
869
|
+
const yLabelByCode = {
|
|
870
|
+
Y1: '일정',
|
|
871
|
+
Y2: '비용',
|
|
872
|
+
Y3: '품질',
|
|
873
|
+
Y4: '안전',
|
|
874
|
+
Y5: '환경',
|
|
875
|
+
Y6: '생산성'
|
|
866
876
|
};
|
|
867
877
|
const data = [];
|
|
868
878
|
// Y-KPI 카테고리별로 통합된 통계 생성
|
|
869
879
|
this.kpiYComprehensiveStats.forEach(stat => {
|
|
870
|
-
|
|
880
|
+
var _a, _b;
|
|
881
|
+
const category = yLabelByCode[(_b = (_a = (stat.kpiName || '').match(/Y[1-6]/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : ''] || stat.kpiName;
|
|
871
882
|
data.push({
|
|
872
883
|
org: category, // org 필드 사용 (boxplot 차트가 기대하는 필드명)
|
|
873
884
|
min: stat.minVal * 100,
|
|
@@ -914,20 +925,21 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
914
925
|
return (kpiValue === null || kpiValue === void 0 ? void 0 : kpiValue.value) || 0;
|
|
915
926
|
}
|
|
916
927
|
getRadarChartData() {
|
|
917
|
-
//
|
|
918
|
-
const
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
928
|
+
// kpiName 표기가 다양하므로 Y1~Y6 코드만 추출해 짧은 라벨로 매핑 (박스플롯과 동일 방식).
|
|
929
|
+
const yLabelByCode = {
|
|
930
|
+
Y1: '일정',
|
|
931
|
+
Y2: '비용',
|
|
932
|
+
Y3: '품질',
|
|
933
|
+
Y4: '안전',
|
|
934
|
+
Y5: '환경',
|
|
935
|
+
Y6: '생산성'
|
|
925
936
|
};
|
|
926
937
|
const data = [];
|
|
927
938
|
const categories = [];
|
|
928
939
|
// Create baseline data from comprehensive stats (using avgVal as baseline)
|
|
929
940
|
this.kpiYComprehensiveStats.forEach(stat => {
|
|
930
|
-
|
|
941
|
+
var _a, _b;
|
|
942
|
+
const category = yLabelByCode[(_b = (_a = (stat.kpiName || '').match(/Y[1-6]/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : ''] || stat.kpiName;
|
|
931
943
|
if (!categories.includes(category)) {
|
|
932
944
|
categories.push(category);
|
|
933
945
|
}
|
|
@@ -948,7 +960,7 @@ let SvProjectDetailPage = class SvProjectDetailPage extends ScopedElementsMixin(
|
|
|
948
960
|
data,
|
|
949
961
|
categories: categories.length > 0
|
|
950
962
|
? categories
|
|
951
|
-
: ['
|
|
963
|
+
: ['일정', '비용', '품질', '안전', '환경', '생산성']
|
|
952
964
|
};
|
|
953
965
|
}
|
|
954
966
|
getBoxPlotDataForProject(project) {
|