Index: arms/html/analysisResource/content-container.html =================================================================== diff -u -re54369317eccd233348a857109005cc3df7e1a26 -r552b263242bbc34ff17c3022bcaccc61b481049d --- arms/html/analysisResource/content-container.html (.../content-container.html) (revision e54369317eccd233348a857109005cc3df7e1a26) +++ arms/html/analysisResource/content-container.html (.../content-container.html) (revision 552b263242bbc34ff17c3022bcaccc61b481049d) @@ -49,7 +49,7 @@
- 선택한 제품(서비스)와 버전의 Time별 요구사항 현황 + 선택한 제품(서비스)와 버전의 작업자관점 요구사항 현황
+
+
+ 담당자 지정 요구사항 수
-

+
+
+ 담당자 지정 연결이슈 수
-

+
+
+
+
+ 담당자 미지정 요구사항 수
-

+
+
+ 담당자 미지정 연결이슈 수
-

+
+
@@ -159,7 +184,7 @@ -->
- 투입 작업자 수 : -
+ 투입 작업자 수 : -
@@ -178,15 +203,14 @@
-

- 두번째 박스 + 작업자 현황

@@ -225,8 +249,9 @@
+
-
+

@@ -238,109 +263,114 @@

-
+
-
-
-
-

- - - 작업자 별 요구사항 관여도 - -

-
-
-
-
-
-
-
-
-
+
+
+
+
+

+ + + 작업자 별 요구사항 관여도 + +

+
+
+
+
+
+
+
+
+

+ + + 작업자 별 업무 처리 현황 + +

+ +
+
+
+
+

+ 작업자별 항목 상세는 상세보기 열의 아이콘을 클릭하세요.
+ 복수 선택 시, 선택한 작업자를 함께 확인하실 수 있습니다. +

+
+ -
-
-
-

- - - 담당자 별 업무 처리 현황 - YHS - -

- -
-
-
- - +
+
+ +
+
+
+
+
- -
--> -
-
- -
-
@@ -354,8 +384,15 @@ - 네번째 박스 + 작업자별 요구사항 및 연결이슈 항목별 상세 +
-
+
-

이슈 상태 현황

+
요구사항 - Priority
-
+
-
+
-

요구사항 및 이슈 상태 누적 현황

+
요구사항 - Status
-
+
+
+
+
+
요구사항 - Type
+
+
+
+
+
+
+
+
요구사항 - Resolution
+
+
+
+
+
+
+
+
+
연결이슈 - Priority
+
+
+
+
+
+
+
+
연결이슈 - Status
+
+
+
+
+
+
+
+
연결이슈 - Type
+
+
+
+
+
+
+
+
연결이슈 - Resolution
+
+
+
+
+
@@ -465,11 +552,27 @@
-
+
-

담당자 별 이슈 상태 현황

+
작업자별 요구사항 비율
+
+
+
+
+
+
+
작업자별 연결이슈 비율
+
+
+
+
+
+
+
+
담당자 별 이슈 상태 현황
+
Index: arms/js/analysis/api/resourceApi.js =================================================================== diff -u -r126fb276ada1d9ccefb28c45df952d00a787f98a -r552b263242bbc34ff17c3022bcaccc61b481049d --- arms/js/analysis/api/resourceApi.js (.../resourceApi.js) (revision 126fb276ada1d9ccefb28c45df952d00a787f98a) +++ arms/js/analysis/api/resourceApi.js (.../resourceApi.js) (revision 552b263242bbc34ff17c3022bcaccc61b481049d) @@ -21,7 +21,6 @@ url: "/auth-user/api/arms/analysis/resource/workerStatus/"+pdservice_id, type: "GET", data: { "서비스아이디" : pdservice_id, - //"메인그룹필드" : "assignee.assignee_displayName.keyword", "메인그룹필드" : "assignee.assignee_emailAddress.keyword", "하위그룹필드들": "isReq,status.status_name.keyword", "컨텐츠보기여부" : true, @@ -60,7 +59,6 @@ url: "/auth-user/api/arms/analysis/resource/workerStatus/"+pdservice_id, type: "GET", data: { "서비스아이디" : pdservice_id, - //"메인그룹필드" : "assignee.assignee_displayName.keyword", "메인그룹필드" : "assignee.assignee_emailAddress.keyword", "하위그룹필드들": "isReq,status.status_name.keyword", "컨텐츠보기여부" : true, @@ -72,14 +70,7 @@ progress: true, statusCode: { 200: function (data) { - console.log("=== === === 작업자 상태 집계 시작=== === ===") - console.log(data); - let search_keys1 = data["검색결과"]["group_by_assignee.assignee_displayName.keyword"]; let search_keys2 = data["검색결과"]["group_by_assignee.assignee_emailAddress.keyword"]; - console.log(search_keys1); - console.log("=== === === 작업자 상태 집계 종료=== === ===") - - //fetchedResourceData = data["검색결과"]["group_by_assignee.assignee_displayName.keyword"]; fetchedResourceDetailData = search_keys2; deferred.resolve(fetchedResourceDetailData); }, Index: arms/js/analysis/resource/chart/horizontalBarChart.js =================================================================== diff -u -rcb16e41c214d9e54b2579a010cec1be0190dc199 -r552b263242bbc34ff17c3022bcaccc61b481049d --- arms/js/analysis/resource/chart/horizontalBarChart.js (.../horizontalBarChart.js) (revision cb16e41c214d9e54b2579a010cec1be0190dc199) +++ arms/js/analysis/resource/chart/horizontalBarChart.js (.../horizontalBarChart.js) (revision 552b263242bbc34ff17c3022bcaccc61b481049d) @@ -73,7 +73,7 @@ textStyle: { color: 'white', fontWeight: "", - fontSize: "13" + fontSize: "11" } }, grid: { @@ -89,7 +89,7 @@ textStyle: { color: 'white', fontWeight: "", - fontSize: "12" + fontSize: "11" } } }, @@ -99,8 +99,8 @@ axisLabel: { textStyle: { color: 'white', - fontWeight: "bold", - fontSize: "13" + fontWeight: "", + fontSize: "11" } } }, @@ -110,5 +110,4 @@ option && myChart.setOption(option,true); return myChart; -} - +} \ No newline at end of file Index: arms/js/analysis/resource/chart/simplePie.js =================================================================== diff -u -r169de6f6f8a287c268dab8090b8e2f8545e9ea6d -r552b263242bbc34ff17c3022bcaccc61b481049d --- arms/js/analysis/resource/chart/simplePie.js (.../simplePie.js) (revision 169de6f6f8a287c268dab8090b8e2f8545e9ea6d) +++ arms/js/analysis/resource/chart/simplePie.js (.../simplePie.js) (revision 552b263242bbc34ff17c3022bcaccc61b481049d) @@ -65,7 +65,7 @@ color: 'white', // 이름의 텍스트 색상 설정 fontStyle: 'normal', // 이름의 텍스트 스타일 설정 (예: italic, normal) fontWeight: '', // 이름의 텍스트 굵기 설정 (예: bold, normal) - fontSize: 13 // 이름의 텍스트 크기 설정 + fontSize: 11 // 이름의 텍스트 크기 설정 // 그 외 다른 텍스트 관련 속성들도 설정 가능합니다. } }, @@ -77,7 +77,7 @@ label: { textStyle: { color: 'white', // 데이터 전체의 이름 폰트 색상 설정 - fontSize: 12 // 데이터 전체의 이름 폰트 크기 설정 + fontSize: 11 // 데이터 전체의 이름 폰트 크기 설정 // 다른 텍스트 관련 속성들도 설정 가능합니다. } }, Index: arms/js/analysis/table/workerStatusTable.js =================================================================== diff -u -r126fb276ada1d9ccefb28c45df952d00a787f98a -r552b263242bbc34ff17c3022bcaccc61b481049d --- arms/js/analysis/table/workerStatusTable.js (.../workerStatusTable.js) (revision 126fb276ada1d9ccefb28c45df952d00a787f98a) +++ arms/js/analysis/table/workerStatusTable.js (.../workerStatusTable.js) (revision 552b263242bbc34ff17c3022bcaccc61b481049d) @@ -10,7 +10,7 @@ this.columns = [ { name: "필드명", - title: "담당자 이름", + title: "작업자 이름", data: "필드명", className: "dt-body-center", defaultContent: "-", @@ -24,7 +24,7 @@ }, { name: "필드명", - title: "담당자 메일", + title: "작업자 메일", data: "필드명", className: "dt-body-center", defaultContent: "-", @@ -60,9 +60,11 @@ visible: true, render: function (data, type, row, meta) { if (type === "display" && data["group_by_isReq"].length !== 0) { - if(data["group_by_isReq"][0]["필드명"] === "true") { + if (data["group_by_isReq"][0]["필드명"] === "true") { return '"; - } else { + } else if (data["group_by_isReq"].length === 2 && data["group_by_isReq"][1]["필드명"] === "true") { + return '"; + }else { return '"; } } @@ -106,6 +108,14 @@ return_status += '
'; }) return '"; + } else if (data["group_by_isReq"].length === 2 && data["group_by_isReq"][1]["필드명"] === "true") { // 요구사항 연결이슈 둘다 있고, 2번째 컬럼일 경우 + let status = data["group_by_isReq"][1]["하위검색결과"]["group_by_status.status_name.keyword"]; + let return_status = ""; + status.forEach((data, index) => { + return_status += data["필드명"] + " - " + data["개수"] + return_status += '
'; + }) + return '"; } else { return '"; } @@ -158,11 +168,13 @@ } else { var _render = '
' + - '
'; return _render; } - return data; }, } ]; Index: arms/js/analysisResource.js =================================================================== diff -u -re54369317eccd233348a857109005cc3df7e1a26 -r552b263242bbc34ff17c3022bcaccc61b481049d --- arms/js/analysisResource.js (.../analysisResource.js) (revision e54369317eccd233348a857109005cc3df7e1a26) +++ arms/js/analysisResource.js (.../analysisResource.js) (revision 552b263242bbc34ff17c3022bcaccc61b481049d) @@ -8,6 +8,9 @@ var dashboardColor; var req_count, linkedIssue_subtask_count, resource_count; var labelType, useGradients, nativeTextSupport, animate; //투입 인력별 요구사항 관여 차트 +var resourceSet = new Set(); // 담당자 set +var chartInstance = []; // 차트인스턴스를 담을 배열; + function execDocReady() { var pluginGroups = [ @@ -51,7 +54,8 @@ "js/common/table.js", "js/analysis/api/resourceApi.js", "js/analysis/table/workerStatusTable.js", - //"js/analysis/table/workerDetailInfoTable.js" + "js/analysis/resource/chart/horizontalBarChart.js", + "js/analysis/resource/chart/simplePie.js" ], [ "../reference/jquery-plugins/dataTables-1.10.16/media/css/jquery.dataTables_lightblue4.css", @@ -87,192 +91,159 @@ //버전 멀티 셀렉트 박스 이니시에이터 makeVersionMultiSelectBox(); - // 담당자 별 이슈 상태 차트(mock) - // https://echarts.apache.org/en/option.html#tooltip.formatter - echartExample(); }) .catch(function() { console.error('플러그인 로드 중 오류 발생'); }); } -function echartExample(){ - var myChart = echarts.init(document.getElementById('apache-echarts-stacked-horizontal-bar')); - var option; - option = { - tooltip: { - trigger: 'axis', - axisPointer: { - type: 'shadow' // 'line' or 'shadow'. 기본값은 'shadow' - }, - formatter: function (params) { - const tooltip = params.reduce((acc, param) => { - const { marker, seriesName, value } = param; - acc += `${marker}${seriesName}: ${value}
`; - return acc; - }, ''); - const totalCount = params.reduce((acc, param) => acc + param.value, 0); - const totalTooltip = `Total: ${totalCount}
`; - return totalTooltip + tooltip; + +function stackedHorizontalBar(){ + if (!selectedPdServiceId || !selectedVersionId) { + alert('제품(서비스)와 버전을 선택해주세요.'); + document.getElementById('apache-echarts-stacked-horizontal-bar').innerHTML = ''; + return; + } + + // 0 or "" + const defaultValue = 0; + + function getStatusCounts(data, statusTypes) { + let statusCounts = {}; + + data["검색결과"]["group_by_assignee.assignee_emailAddress.keyword"].forEach(item => { + let itemStatusCounts = {}; + if (item["하위검색결과"]["group_by_status.status_name.keyword"]) { + item["하위검색결과"]["group_by_status.status_name.keyword"].forEach(status => { + itemStatusCounts[status["필드명"]] = status["개수"]; + }); } - }, - legend: { - data: ['완료', 'Done', 'In Progress', 'Resolved', 'Backlog', '진행 중', '해야 할 일', '열기', '완료됨', 'Open'], - textStyle: { - color: 'white' + statusTypes.forEach(statusType => { + if (!itemStatusCounts[statusType]) { + itemStatusCounts[statusType] = defaultValue; + } + }); + + statusCounts[item["필드명"]] = itemStatusCounts; + }); + + return statusCounts; + } + function stackedBarChartInit(data) { + const sortedData = data["검색결과"]["group_by_assignee.assignee_emailAddress.keyword"].sort((a, b) => a.개수 - b.개수); + + const jiraIssueStatuses = sortedData.reduce((acc, item) => { + if (item["하위검색결과"]["group_by_status.status_name.keyword"]) { + item["하위검색결과"]["group_by_status.status_name.keyword"].forEach(status => { + acc.add(status["필드명"]); + }); } - }, - grid: { - left: '3%', - right: '4%', - bottom: '3%', - containLabel: true - }, - xAxis: { - type: 'value' - }, - yAxis: { - type: 'category', - data: ['dumbbelloper', '김찬호', 'admin', '최수현', 'hsyang', 'gkfn185'] // 담당자 이록 - }, + return acc; + }, new Set()); - series: [ - { - name: '완료', // 이슈 상태 - type: 'bar', - stack: 'total', - itemStyle: { - // color: '#FF0000' + const statusTypes = Array.from(jiraIssueStatuses); + + const statusCounts = getStatusCounts(data, statusTypes); + + const myChart = echarts.init(document.getElementById('apache-echarts-stacked-horizontal-bar')); + + const option = { + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow' // 'line' or 'shadow'. 기본값은 'shadow' }, - label: { - show: true, - // position: 'top' - }, - emphasis: { - focus: 'series' - }, - data: [320, 302, 301, 334, 390, 330] + formatter: function (params) { + const tooltip = params.reduce((acc, param) => { + const { marker, seriesName, value } = param; + acc += `${marker}${seriesName}: ${value}
`; + return acc; + }, ''); + + const totalCount = params.reduce((acc, param) => acc + param.value, 0); + const totalTooltip = `Total: ${totalCount}
`; + + return totalTooltip + tooltip; + } }, - { - name: 'Done', - type: 'bar', - stack: 'total', - label: { - show: true - }, - emphasis: { - focus: 'series' - }, - data: [120, 132, 101, 134, 90, 230] + legend: { + data: statusTypes, + textStyle: { + color: 'white', + fontSize: "11" + } }, - { - name: 'In Progress', - type: 'bar', - stack: 'total', - label: { - show: true - }, - emphasis: { - focus: 'series' - }, - data: [220, 182, 191, 234, 290, 330] + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true }, - { - name: 'Resolved', - type: 'bar', - stack: 'total', - label: { - show: true - }, - emphasis: { - focus: 'series' - }, - data: [150, 212, 201, 154, 190, 330] + xAxis: { + type: 'value' }, - { - name: 'Backlog', - type: 'bar', - stack: 'total', - label: { - show: true - }, - emphasis: { - focus: 'series' - }, - data: [820, 832, 901, 934, 1290, 1330] + yAxis: { + type: 'category', + data: sortedData.map(function(item) {return getIdFromMail(item["필드명"]);}), + axisLabel: { + textStyle: { + color: 'white', + fontWeight: "", + fontSize: "11" + } + } }, + series: statusTypes.map(statusType => { + const data = Object.values(statusCounts).map(statusCount => statusCount[statusType] || defaultValue); + return { + name: statusType, + type: 'bar', + stack: 'total', + label: { + show: true, + }, + emphasis: { + focus: 'series' + }, + data: data + }; + }) + }; - { - name: '진행 중', - type: 'bar', - stack: 'total', - label: { - show: true - }, - emphasis: { - focus: 'series' - }, - data: [820, 832, 901, 934, 1290, 1330] - }, - { - name: '해야 할 일', - type: 'bar', - stack: 'total', - label: { - show: true - }, - emphasis: { - focus: 'series' - }, - data: [820, 832, 901, 934, 1290, 1330] - }, - { - name: '열기', - type: 'bar', - stack: 'total', - label: { - show: true - }, - emphasis: { - focus: 'series' - }, - data: [820, 832, 901, 934, 1290, 1330] - }, - { - name: '완료됨', - type: 'bar', - stack: 'total', - label: { - show: true - }, - emphasis: { - focus: 'series' - }, - data: [820, 832, 901, 934, 1290, 1330] - },{ - name: 'Open', - type: 'bar', - stack: 'total', - label: { - show: true - }, - emphasis: { - focus: 'series' - }, - data: [119, 832, 901, 934, 1290, 1330] - }, - ] - }; + option && myChart.setOption(option); + } - option && myChart.setOption(option); + const url = new UrlBuilder() + .setBaseUrl(`/auth-user/api/arms/dashboard/aggregation/flat`) + .addQueryParam('pdServiceLink', selectedPdServiceId) + .addQueryParam('pdServiceVersionLinks', selectedVersionId) + .addQueryParam('메인그룹필드', "assignee.assignee_emailAddress.keyword") + .addQueryParam('하위그룹필드들', "status.status_name.keyword,assignee.assignee_displayName.keyword") + .addQueryParam('크기', 1000) + .addQueryParam('하위크기', 1000) + .addQueryParam('컨텐츠보기여부', true) + .addQueryParam("isReqType", "ISSUE") + .build(); + + $.ajax({ + url: url, + type: "GET", + contentType: "application/json;charset=UTF-8", + dataType: "json", + progress: true, + statusCode: { + 200: function (response) { + stackedBarChartInit(response); + } + } + }); } - /////////////////////// //제품 서비스 셀렉트 박스 ////////////////////// @@ -312,6 +283,7 @@ $("#selected_pdService").on("select2:select", function (e) { selectedPdServiceId = $("#selected_pdService").val(); initTable(); + refreshDetailChart(); // 제품( 서비스 ) 선택했으니까 자동으로 버전을 선택할 수 있게 유도 // 디폴트는 base version 을 선택하게 하고 ( select all ) //~> 이벤트 연계 함수 :: Version 표시 jsTree 빌드 @@ -347,14 +319,16 @@ var versionTag = $(".multiple-select").val(); selectedVersionId = versionTag.join(','); + refreshDetailChart(); + // 요구사항 및 연결이슈 통계 - getReqLinkedIssueData($("#selected_pdService").val(), selectedVersionId, true); - getReqLinkedIssueData($("#selected_pdService").val(), selectedVersionId, false); + getReqAndLinkedIssueData($("#selected_pdService").val(), selectedVersionId); // 작업자별 상태 drawResource($("#selected_pdService").val(), selectedVersionId); drawProductToManSankeyChart($("#selected_pdService").val(), selectedVersionId); drawManRequirementTreeMapChart($("#selected_pdService").val(), selectedVersionId); + stackedHorizontalBar(); } }); } @@ -376,17 +350,16 @@ var newOption = new Option(obj.c_title, obj.c_id, true, false); $(".multiple-select").append(newOption); } + refreshDetailChart(); selectedVersionId = pdServiceVersionIds.join(','); - // 요구사항 및 연결이슈 통계 - 리펙토링예정 - getReqLinkedIssueData($("#selected_pdService").val(), selectedVersionId, true); - getReqLinkedIssueData($("#selected_pdService").val(), selectedVersionId, false); - + // 요구사항 및 연결이슈 통계 + getReqAndLinkedIssueData($("#selected_pdService").val(), selectedVersionId); // 작업자별 상태 drawResource($("#selected_pdService").val(), selectedVersionId); drawProductToManSankeyChart($("#selected_pdService").val(), selectedVersionId); drawManRequirementTreeMapChart($("#selected_pdService").val(), selectedVersionId); - + stackedHorizontalBar(); if (data.length > 0) { console.log("display 재설정."); } @@ -417,64 +390,76 @@ .responsive.recalc();*/ } -function getReqLinkedIssueData(pdservice_id, pdServiceVersionLinks, isReq) { - console.log(pdServiceVersionLinks); - var _url = "/auth-user/api/arms/analysis/resource/normal-version/"+pdservice_id; +function getReqAndLinkedIssueData(pdservice_id, pdServiceVersionLinks) { $.ajax({ - url: _url, + url: "/auth-user/api/arms/analysis/resource/workerStatus/"+pdservice_id, type: "GET", data: { "서비스아이디" : pdservice_id, - "메인그룹필드" : "pdServiceVersion", - "isReq" : isReq, - "컨텐츠보기여부" : true, - "크기" : 1000, - "pdServiceVersionLinks" : pdServiceVersionLinks}, + "pdServiceVersionLinks" : pdServiceVersionLinks, + "메인그룹필드" : "isReq", + "하위그룹필드들": "assignee.assignee_emailAddress.keyword", + "컨텐츠보기여부" : true, + "크기" : 1000}, contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function (data) { - if(isReq == true) { - console.log("요구사항"); - req_count = data["전체합계"]; - $("#req_count").text(data["전체합계"]); - } else { - console.log("연결이슈"); - linkedIssue_subtask_count = data["전체합계"]; - $("#linkedIssue_subtask_count").text(data["전체합계"]); - } - // 작업자수 및 평균계산 - 수정예정 - getAssigneeInfo(pdservice_id,pdServiceVersionLinks); - } - }, - }); -} -function getWorkStatus(pdservice_id, pdServiceVersionLinks) { - var _url = "/auth-user/api/arms/analysis/resource/workerStatus/"+pdservice_id; - $.ajax({ - url: _url, - type: "GET", - data: { "서비스아이디" : pdservice_id, - "메인그룹필드" : "assignee.assignee_displayName.keyword", - "하위그룹필드들": "isReq,status.status_name.keyword", - "컨텐츠보기여부" : true, - "크기" : 1000, - "하위크기": 1000, - "pdServiceVersionLinks" : pdServiceVersionLinks}, - contentType: "application/json;charset=UTF-8", - dataType: "json", - progress: true, - statusCode: { - 200: function (data) { - console.log("=== === === 작업자 상태 집계 시작=== === ===") - console.log(data); - let search_keys1 = data["검색결과"]["group_by_assignee.assignee_displayName.keyword"]; - console.log(search_keys1); - console.log(data['검색결과']['group_by_assignee.assignee_displayName.keyword']['필드명']) - console.log("=== === === 작업자 상태 집계 종료=== === ===") + //전체 요구사항, 연결이슈 + let all_req_count = 0; + let all_linkedIssue_subtask_count = 0; + //담당자존재 요구사항, 연결이슈 + let assignedReqSum = 0; + let assignedSubtaskSum = 0; + //담당자 미지정 요구사항,연결이슈 + let no_assigned_req_count = 0; + let no_assigned_linkedIssue_subtask_count =0; + //요구사항,연결이슈 파이차트용 데이터배열 + let reqDataMapForPie = []; + let subtaskDataMapForPie = []; + let isReqGrpArr = data["검색결과"]["group_by_isReq"]; + isReqGrpArr.forEach((elementArr,index) => { + if(elementArr["필드명"] == "true") { + all_req_count = elementArr["개수"]; + let tempArrReq= elementArr["하위검색결과"]["group_by_assignee.assignee_emailAddress.keyword"]; + tempArrReq.forEach(e => { + assignedReqSum+=e["개수"]; + reqDataMapForPie.push({name: getIdFromMail(e["필드명"]), value: e["개수"]}); + }); + no_assigned_req_count = all_req_count - assignedReqSum; + } + if(elementArr["필드명"] == "false") { + all_linkedIssue_subtask_count = elementArr["개수"]; + let tempArrReq= elementArr["하위검색결과"]["group_by_assignee.assignee_emailAddress.keyword"]; + tempArrReq.forEach(e => { + assignedSubtaskSum+=e["개수"]; + subtaskDataMapForPie.push({name: getIdFromMail(e["필드명"]), value: e["개수"]}); + }); + no_assigned_linkedIssue_subtask_count = all_linkedIssue_subtask_count - assignedSubtaskSum; + } + }) + //요구사항 및 연결이슈 수 + $('#total_req_count').text(all_req_count); + $('#total_linkedIssue_subtask_count').text(all_linkedIssue_subtask_count); + req_count = assignedReqSum; + $('#req_count').text(assignedReqSum); + linkedIssue_subtask_count = assignedSubtaskSum; + $('#linkedIssue_subtask_count').text(assignedSubtaskSum); + $('#no_assigned_req_count').text(no_assigned_req_count); + $('#no_assigned_linkedIssue_subtask_count').text(no_assigned_linkedIssue_subtask_count); + + // 작업자수 및 평균계산 + getAssigneeInfo(pdservice_id,pdServiceVersionLinks); + + // 요구사항 및 연결이슈 파이차트 + drawSimplePieChart("req_pie","요구사항",reqDataMapForPie) + drawSimplePieChart("linkedIssue_subtask_pie","연결이슈 및 하위작업",subtaskDataMapForPie) + }, + error: function (e) { + jError("Resource Status 조회에 실패했습니다. 나중에 다시 시도 바랍니다."); } } }); @@ -529,33 +514,243 @@ //var workerDetailInfoTable = new $.fn.WorkerDetailInfoTable("#analysis_worker_detail_table"); //작업예정 }; -function getAssigneeInfo(pdservice_id, pdServiceVersionLinks) { //버전으로 추가해야함. +function getAssigneeInfo(pdservice_id, pdServiceVersionLinks) { $.ajax({ - url:"/auth-user/api/arms/dashboard/jira-issue-assignee", - type: "get", - data: {"pdServiceId" : pdservice_id}, + url: "/auth-user/api/arms/analysis/resource/workerStatus/"+pdservice_id, + type: "GET", + data: { "서비스아이디" : pdservice_id, + "pdServiceVersionLinks" : pdServiceVersionLinks, + "메인그룹필드" : "assignee.assignee_emailAddress.keyword", + "컨텐츠보기여부" : true, + "크기" : 1000}, contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function (data) { - //담당자 미지정 이슈 수 - $('#no_assigned_issue_count').text(data["담당자 미지정"]); - if (Object.keys(data).length !== "" || Object.keys(data).length !== undefined) { - //제품(서비스)에 투입된 총 인원수 - resource_count = +Object.keys(data).length-1; + + let assigneesArr = data["검색결과"]["group_by_assignee.assignee_emailAddress.keyword"]; + let mailAddressList = []; + //제품(서비스)에 투입된 총 인원수 + resource_count = assigneesArr.length; + if (data["전체합계"] === 0) { //담당자(작업자) 없음. + $('#resource_count').text("-"); + $('#avg_req_count').text("-"); + $('#avg_linkedIssue_count').text("-"); + refreshDetailChart(); //상세 바차트 초기화 + } else { + assigneesArr.forEach((element,idx) =>{ + mailAddressList.push(element["필드명"]); + }); $('#resource_count').text(resource_count); - if (resource_count == 0) { - $('#avg_req_count').text("-"); - $('#avg_linkedIssue_count').text("-"); - } else { - $('#avg_req_count').text((req_count/resource_count).toFixed(1)); - $('#avg_linkedIssue_count').text((linkedIssue_subtask_count/resource_count).toFixed(1)); + $('#avg_req_count').text((req_count/resource_count).toFixed(1)); + $('#avg_linkedIssue_count').text((linkedIssue_subtask_count/resource_count).toFixed(1)); + } + + drawDetailChartForAll(pdservice_id, pdServiceVersionLinks,mailAddressList); + }, + error: function (e) { + jError("Resource Status 조회에 실패했습니다. 나중에 다시 시도 바랍니다."); + } + } + }); +} +function refreshDetailChart() { // 차트8개 초기화 + chartInstance.forEach((chart) => chart.dispose()); + chartInstance =[]; + resourceSet.clear(); +} + +//공통코드-extract필요 +function drawDetailChartForAll(pdservice_id, pdServiceVersionLinks, mailAddressList) { + let mailList = []; + mailList = mailAddressList; + let mailStr =""; + let searchMap = [ + { "field" : "priority.priority_name.keyword", "reqId" : "req-priority-bar", "subId" :"subtask-priority-bar"}, + { "field" : "status.status_name.keyword", "reqId" : "req-status-bar", "subId" :"subtask-status-bar"}, + { "field" : "issuetype.issuetype_name.keyword", "reqId" : "req-issuetype-bar", "subId" :"subtask-issuetype-bar"}, + { "field" : "resolution.resolution_name.keyword", "reqId" : "req-resolution-bar", "subId" :"subtask-resolution-bar"} + ]; + + if(mailList.length == 1) { + mailStr = mailList[0]; + } else { + for (let cnt = 0; cnt < mailList.length; cnt++) { + if(cnt !== mailList.length-1) { + mailStr += mailList[cnt] +","; + } else { + mailStr += mailList[cnt]; + } + } + } + searchMap.forEach( + (target, index) => { + drawChartsPerPerson(pdservice_id,pdServiceVersionLinks,mailStr, target["field"], target["reqId"], target["subId"]); + } + ) +} + +function getDetailCharts(pdservice_id, pdServiceVersionLinks, mailAddressList) { + let mailList = []; + let mailStr =""; + let searchMap = [ + { "field" : "priority.priority_name.keyword", "reqId" : "req-priority-bar", "subId" :"subtask-priority-bar"}, + { "field" : "status.status_name.keyword", "reqId" : "req-status-bar", "subId" :"subtask-status-bar"}, + { "field" : "issuetype.issuetype_name.keyword", "reqId" : "req-issuetype-bar", "subId" :"subtask-issuetype-bar"}, + { "field" : "resolution.resolution_name.keyword", "reqId" : "req-resolution-bar", "subId" :"subtask-resolution-bar"} + ]; + resourceSet.add(mailAddressList); + + resourceSet.forEach((e)=>{mailList.push(e)}); + if(mailList.length == 1) { + mailStr = mailList[0]; + } else { + for (let cnt = 0; cnt < mailList.length; cnt++) { + if(cnt !== mailList.length-1) { + mailStr += mailList[cnt] +","; + } else { + mailStr += mailList[cnt]; + } + } + } + + searchMap.forEach( + (target, index) => { + drawChartsPerPerson(pdservice_id,pdServiceVersionLinks,mailStr, target["field"], target["reqId"], target["subId"]); + } + ) +} + + +function drawChartsPerPerson(pdservice_id, pdServiceVersionLinks, mailAddressList, targetField, targetReqId, targetSubtaskId) { + let _url = "/auth-user/api/arms/analysis/resource/normal-versionAndMail-filter/"+pdservice_id; + $.ajax({ + url: _url, + type: "GET", + data: { "서비스아이디" : pdservice_id, + "mailAddressList" : mailAddressList, + "메인그룹필드" : 'assignee.assignee_emailAddress.keyword', + "하위그룹필드들": 'isReq,'+targetField, + "컨텐츠보기여부" : true, + "크기" : 1000, + "하위크기": 1000, + "pdServiceVersionLinks" : pdServiceVersionLinks}, + contentType: "application/json;charset=UTF-8", + dataType: "json", + progress: true, + statusCode: { + 200: function (data) { + let set_req = new Set(); + let set_subtask = new Set(); + + //y축 좌표 + let yAxisDataArr_req =[]; + let yAxisDataArr_subtask = []; + //담당자 데이터 - 담당자별 name,type,data -> map 이 들어있는 배열 + let seriesArr_req = []; + let seriesArr_subtask = []; + + let totalMap_req = []; //담당자별 이슈항목의 필드(k)-개수(v) map 이 들어있는 배열 + let totalMap_subtask = []; + + let searchDepth1 = data["검색결과"]["group_by_assignee.assignee_emailAddress.keyword"]; + if (searchDepth1.length !== 0) { + for (let i = 0; i { + set_req.add(target["필드명"]); + map_req.set(target["필드명"],target["개수"]); + }); + } + } + + if (searchDepth1_sub[j]["필드명"] === "false") { //연결이슈 + let subTaskCnt = searchDepth1_sub[j]["개수"]; // 연결이슈 개수 + if (subTaskCnt !== 0) { + let priorityArr = searchDepth1_sub[j]["하위검색결과"]["group_by_"+targetField]; + priorityArr.forEach((target, index) => { + set_subtask.add(target["필드명"]); + map_subtask.set(target["필드명"],target["개수"]); + }); + } + } + } + } + seriesArr_req.push(seriesMap_req); + seriesArr_subtask.push(seriesMap_subtask); + totalMap_req.push(map_req); + totalMap_subtask.push(map_subtask); + }//per Person + + } + //setToList - 담당자별 이슈항목 필드의 중복제거 배열 + set_req.forEach((e)=>{yAxisDataArr_req.push(e)}); + set_subtask.forEach((e)=>{yAxisDataArr_subtask.push(e)}); + + //totalMap_req; + //seriesArr_req; // 담당자별 name,type,data -> map 이 들어있는 배열 + + // 차트에 넣을 담당자별 data 를 넣어주기 위해 사용. + for (var idx1 = 0; idx1 < totalMap_req.length; idx1++) { + let refinedDataFromYAxis_req = new Array(yAxisDataArr_req.length); // yAxis의 수로 배열만듦. + let refinedDataFromYAxis_subtask = new Array(yAxisDataArr_subtask.length); // yAxis의 수로 배열만듦. + + let personMap_req = totalMap_req[idx1]; + let personMap_subtask = totalMap_subtask[idx1]; + + for(let idx2 = 0; idx2