Index: arms/html/analysisScope/content-container.html =================================================================== diff -u -r3373387f07025639254a07fd90d2c2909554a84d -rcf3bc3be60ad8e62d918be08a464de209fe5e645 --- arms/html/analysisScope/content-container.html (.../content-container.html) (revision 3373387f07025639254a07fd90d2c2909554a84d) +++ arms/html/analysisScope/content-container.html (.../content-container.html) (revision cf3bc3be60ad8e62d918be08a464de209fe5e645) @@ -1,21 +1,5 @@
- - +
@@ -65,7 +49,7 @@
- 선택한 제품(서비스)와 버전의 Scope별 요구사항 현황 + 선택한 제품(서비스)와 버전의 Scope 관점 요구사항 현황
- -
-
+
+
+
+
종합 진행 현황
+
+
+
+
+
+
+

- - 전체 남은 일자 중 남은 퍼센트 + + 범위(Scope) 현황

+
+
+
-
+
+ 작업 중 +
+
+
|
+
+
-
+
+ └ 작업 대상 ┘ +
+
+
+
+
+
+ 요구사항() 연결이슈 평균: -
+
+
+
-
- 종료까지 남은 진행률
- %

+
+ 총 요구사항
(미할당)
- 개 (-)

-
- 종료까지 남은 일자
-

+
+ 총 연결이슈
(미할당)
- 개 (-)

-
-
-
-

- - - 요구사항 현황 - -

-
+
+
+
+
일정(Time) 현황
+
-
-
-
-
+
+
+
-
- - 총 요구사항 + 【 일정 】
-
- - +
|
+
+
-
+
+ 【 경과 】 +
+
- -
-
+
+

- - 연결이슈 현황 + + 자원(Resource) 현황

-
-
-
+
+
-
- - 총 연결이슈 + + 투입 작업자 수
-
+
+ 작업 중 요구사항 평균 : -
- +
+
+
+ 생성한 연결이슈 평균 : -
+
+
+
-
Index: arms/js/analysisScope.js =================================================================== diff -u -r76a367fb3ee0cf801114583cb698a7534fc2083b -rcf3bc3be60ad8e62d918be08a464de209fe5e645 --- arms/js/analysisScope.js (.../analysisScope.js) (revision 76a367fb3ee0cf801114583cb698a7534fc2083b) +++ arms/js/analysisScope.js (.../analysisScope.js) (revision cf3bc3be60ad8e62d918be08a464de209fe5e645) @@ -1,11 +1,17 @@ +var selectedPdServiceId; // 제품(서비스) 아이디 +var selectedVersionId; // 선택된 버전 아이디 +var dataTableRef; +var mailAddressList; // 투입 작업자 메일 +var req_count, linkedIssue_subtask_count, resource_count, req_in_action; + var dashboardColor; -var selectedVersionId; var pdServiceData; var versionListData; //////////////////////////////////////////////////////////////////////////////////////// //Document Ready //////////////////////////////////////////////////////////////////////////////////////// + function execDocReady() { var pluginGroups = [ @@ -14,23 +20,17 @@ "../reference/light-blue/lib/vendor/http_blueimp.github.io_JavaScript-Load-Image_js_load-image.js", "../reference/light-blue/lib/vendor/http_blueimp.github.io_JavaScript-Canvas-to-Blob_js_canvas-to-blob.js", "../reference/light-blue/lib/jquery.iframe-transport.js", - "./js/common/colorPalette.js", - // donut chart - "../reference/jquery-plugins/c3/c3.min.css", - "../reference/jquery-plugins/c3/c3-custom.css", - "../reference/jquery-plugins/c3/c3.min.js", - // network chart - "./js/analysisTime/d3.v5.min.js", - + "../reference/light-blue/lib/jquery.fileupload.js", + "../reference/light-blue/lib/jquery.fileupload-fp.js", + "../reference/light-blue/lib/jquery.fileupload-ui.js", + //d3 + "../reference/jquery-plugins/d3-v4.13.0/d3.v4.min.js", + //chart Colors + "./js/dashboard/chart/colorPalette.js", + // Apache Echarts + "../reference/jquery-plugins/echarts-5.4.3/dist/echarts.min.js", ], - [ "../reference/lightblue4/docs/lib/slimScroll/jquery.slimscroll.min.js", - "../reference/jquery-plugins/unityping-0.1.0/dist/jquery.unityping.min.js", - "../reference/light-blue/lib/bootstrap-datepicker.js", - "../reference/jquery-plugins/datetimepicker-2.5.20/build/jquery.datetimepicker.min.css", - "../reference/jquery-plugins/datetimepicker-2.5.20/build/jquery.datetimepicker.full.min.js", - "../reference/lightblue4/docs/lib/widgster/widgster.js"], - [ "../reference/jquery-plugins/select2-4.0.2/dist/css/select2_lightblue4.css", "../reference/jquery-plugins/lou-multi-select-0.9.12/css/multiselect-lightblue4.css", "../reference/jquery-plugins/multiple-select-1.5.2/dist/multiple-select-bluelight.css", @@ -39,6 +39,23 @@ "../reference/jquery-plugins/lou-multi-select-0.9.12/js/jquery.multi-select.js", "../reference/jquery-plugins/multiple-select-1.5.2/dist/multiple-select.min.js"], + [ "../reference/jquery-plugins/datetimepicker-2.5.20/build/jquery.datetimepicker.min.css", + "../reference/light-blue/lib/bootstrap-datepicker.js", + "../reference/jquery-plugins/datetimepicker-2.5.20/build/jquery.datetimepicker.full.min.js", + "../reference/lightblue4/docs/lib/widgster/widgster.js", + "../reference/lightblue4/docs/lib/slimScroll/jquery.slimscroll.min.js", + // 투입 인력별 요구사항 관여 차트 + "../reference/jquery-plugins/Jit-2.0.1/jit.js", + "../reference/jquery-plugins/Jit-2.0.1/Examples/css/Treemap.css", + // 제품-버전-투입인력 차트 + "../reference/jquery-plugins/d3-sankey-v0.12.3/d3-sankey.min.js", + ], + [ // 생성한 차트 import + "js/common/table.js", + "js/analysis/api/resourceApi.js", + "js/analysis/table/workerStatusTable.js", + "js/analysis/resource/chart/basicRadar.js" + ], [ "../reference/jquery-plugins/dataTables-1.10.16/media/css/jquery.dataTables_lightblue4.css", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Responsive/css/responsive.dataTables_lightblue4.css", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Select/css/select.dataTables_lightblue4.css", @@ -50,7 +67,11 @@ "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/buttons.html5.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/buttons.print.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/jszip.min.js", - "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/pdfmake.min.js"] + "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/pdfmake.min.js", + "../arms/css/analysis/analysis.css", + "../arms/js/analysis/resource/sankey.js", + "../arms/js/analysis/resource/treemap.js" + ] // 추가적인 플러그인 그룹들을 이곳에 추가하면 됩니다. ]; @@ -105,29 +126,20 @@ }); - // $("#selected_pdService").on("select2:open", function () { - // //슬림스크롤 - // makeSlimScroll(".select2-results__options"); - // }); + $("#selected_pdService").on("select2:open", function () { + //슬림스크롤 + makeSlimScroll(".select2-results__options"); + }); // --- select2 ( 제품(서비스) 검색 및 선택 ) 이벤트 --- // $("#selected_pdService").on("select2:select", function (e) { + selectedPdServiceId = $("#selected_pdService").val(); + //refreshDetailChart(); 변수값_초기화(); // 제품( 서비스 ) 선택했으니까 자동으로 버전을 선택할 수 있게 유도 // 디폴트는 base version 을 선택하게 하고 ( select all ) //~> 이벤트 연계 함수 :: Version 표시 jsTree 빌드 bind_VersionData_By_PdService(); - var checked = $("#checkbox1").is(":checked"); - var endPointUrl = ""; - -// if (checked) { -// endPointUrl = "/T_ARMS_REQSTATUS_" + $("#selected_pdService").val() + "/getStatusMonitor.do?disable=true"; -// } else { -// endPointUrl = "/T_ARMS_REQSTATUS_" + $("#selected_pdService").val() + "/getStatusMonitor.do?disable=false"; -// } - - console.log("선택된 제품(서비스) c_id = " + $("#selected_pdService").val()); - }); } // end makePdServiceSelectBox() @@ -144,30 +156,16 @@ var checked = $("#checkbox1").is(":checked"); var endPointUrl = ""; var versionTag = $(".multiple-select").val(); - + selectedVersionId = versionTag.join(','); if (versionTag === null || versionTag == "") { alert("버전이 선택되지 않았습니다."); return; } - selectedVersionId = versionTag.join(','); + // 변수값_초기화 함수 넣기 refreshDetailChart(); 변수값_초기화(); - statisticsMonitor($("#selected_pdService").val(), selectedVersionId); - - donutChart($("#selected_pdService").val(), selectedVersionId); - combinationChart($("#selected_pdService").val(), selectedVersionId); - - getRelationJiraIssueByPdServiceAndVersions($("#selected_pdService").val(), selectedVersionId); - - if (checked) { - endPointUrl = - "/T_ARMS_REQSTATUS_" + $("#selected_pdService").val() + "/getStatusMonitor.do?disable=true&versionTag=" + versionTag; - //dataTableLoad($("#selected_pdService").val(), endPointUrl); - } else { - endPointUrl = - "/T_ARMS_REQSTATUS_" + $("#selected_pdService").val() + "/getStatusMonitor.do?disable=false&versionTag=" + versionTag; - //dataTableLoad($("#selected_pdService").val(), endPointUrl); - } + // 요구사항 및 연결이슈 통계 + getReqAndLinkedIssueData(selectedPdServiceId, selectedVersionId); } }); } @@ -184,29 +182,18 @@ 200: function (data) { ////////////////////////////////////////////////////////// // console.log(data.response); // versionData - - versionListData = data.response.reduce((obj, item) => { - obj[item.c_id] = item; - return obj; - }, {}); - var pdServiceVersionIds = []; for (var k in data.response) { var obj = data.response[k]; pdServiceVersionIds.push(obj.c_id); var newOption = new Option(obj.c_title, obj.c_id, true, false); $(".multiple-select").append(newOption); } - + 변수값_초기화(); selectedVersionId = pdServiceVersionIds.join(','); + // 요구사항 및 연결이슈 통계 + getReqAndLinkedIssueData(selectedPdServiceId, selectedVersionId); - statisticsMonitor($("#selected_pdService").val(), selectedVersionId); - - donutChart($("#selected_pdService").val(), selectedVersionId); - combinationChart($("#selected_pdService").val(), selectedVersionId); - - getRelationJiraIssueByPdServiceAndVersions($("#selected_pdService").val(), selectedVersionId); - if (data.length > 0) { console.log("display 재설정."); } @@ -797,3 +784,265 @@ /******** network graph create ********/ networkGraph.createGraph(); } + +//email에서 ID 만 가져오기 +function getIdFromMail (param) { + var full_str = param; + var indexOfAt = full_str.indexOf('@'); + return full_str.substring(0,indexOfAt); +} + +// 최상단 세팅 +function getReqAndLinkedIssueData(pdservice_id, pdServiceVersionLinks) { + $.ajax({ + url: "/auth-user/api/arms/analysis/resource/workerStatus/"+pdservice_id, + type: "GET", + data: { "서비스아이디" : pdservice_id, + "pdServiceVersionLinks" : pdServiceVersionLinks, + "메인그룹필드" : "isReq", + "하위그룹필드들": "assignee.assignee_emailAddress.keyword", + "컨텐츠보기여부" : true, + "크기" : 1000}, + contentType: "application/json;charset=UTF-8", + dataType: "json", + progress: true, + statusCode: { + 200: function (data) { + //전체 요구사항, 연결이슈 + 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; + + if (data["전체합계"] === 0) { + alert("작업자 업무 처리현황 데이터가 없습니다."); + } else { + 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["개수"]; + }); + 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["개수"]; + }); + 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); + }, + error: function (e) { + jError("Resource Status 조회에 실패했습니다. 나중에 다시 시도 바랍니다."); + } + } + }); +} + +function getAssigneeInfo(pdservice_id, pdServiceVersionLinks) { + mailAddressList = []; + $.ajax({ + 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) { + let assigneesArr = data["검색결과"]["group_by_assignee.assignee_emailAddress.keyword"]; + + //제품(서비스)에 투입된 총 인원수 + 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); + $('#avg_req_count').text((req_count/resource_count).toFixed(1)); + $('#avg_linkedIssue_count').text((linkedIssue_subtask_count/resource_count).toFixed(1)); + } + getReqInActionCount(pdservice_id,pdServiceVersionLinks); + //모든작업자 - 상세차트 + //drawDetailChartForAll(pdservice_id, pdServiceVersionLinks,mailAddressList); + }, + error: function (e) { + jError("Resource Status 조회에 실패했습니다. 나중에 다시 시도 바랍니다."); + } + } + }); +} + +function getReqInActionCount(pdService_id, pdServiceVersionLinks) { + $.ajax({ + url: "/auth-user/api/arms/analysis/resource/reqInAction/"+pdService_id, + type: "GET", + data: { "서비스아이디" : pdService_id, + "pdServiceVersionLinks" : pdServiceVersionLinks, + "isReq" : false, + "메인그룹필드" : "parentReqKey", + "컨텐츠보기여부" : true, + "크기" : 1000}, + contentType: "application/json;charset=UTF-8", + dataType: "json", + progress: true, + statusCode: { + 200: function (data) { + req_in_action = data["parentReqCount"]; + let req_in_wait_count = req_count-req_in_action; + if (req_in_action === "") { + $("#req_in_action_count").text("-"); + $('#linkedIssue_subtask_count_per_req_in_action').text("-"); + } else { + if(req_in_action === 0) { + $('#linkedIssue_subtask_count_per_req_in_action').text("-"); + } else { + $("#req_in_action_count").text(req_in_action); //진행중 요구사항 + $("#req_in_action_avg").text((resource_count !== 0 ? (req_in_action/resource_count).toFixed(1) : "-")); + $("#req_in_wait_count").text(req_in_wait_count); //작업대기 요구사항 + $("#req_in_wait_avg").text((resource_count !== 0 ? (req_in_wait_count/resource_count).toFixed(1) : "-")); + $('#linkedIssue_subtask_count_per_req_in_action').text((linkedIssue_subtask_count/req_in_action).toFixed(1)); + } + } + // 리소스-요구사항-일정 레이더차트 + getScheduleToDrawRadarChart(pdService_id,pdServiceVersionLinks); + }, + error: function (e) { + jError("Resource Status 조회에 실패했습니다. 나중에 다시 시도 바랍니다."); + } + } + }); +} + + +function getScheduleToDrawRadarChart(pdservice_id, pdServiceVersionLinks) { + + let 선택한_버전_세트 = new Set(); + pdServiceVersionLinks.split(",").forEach( e => 선택한_버전_세트.add({c_id:e})); + + if(선택한_버전_세트.size !== 0) { + $.ajax({ + url: "/auth-user/api/arms/pdService/getNodeWithVersionOrderByCidDesc.do", + data: { + c_id: pdservice_id, + pdServiceVersionEntities: 선택한_버전_세트 + }, + type: "GET", + contentType: "application/json;charset=UTF-8", + dataType: "json", + progress: true, + statusCode: { + 200: function (json) { + let 버전_세트 = json.pdServiceVersionEntities; + let earliestStartDate; let lastEndDate; + let versionArray= []; + 버전_세트.forEach(e => versionArray.push(e)); + + if(versionArray !== 0) { + for (let i=0; i lastEndDate) { + lastEndDate = versionArray[i]["c_pds_version_end_date"]; + } + } + } + } + + if(earliestStartDate ==="start") { earliestStartDate = new Date(); } + if(lastEndDate ==="end") {lastEndDate = new Date(); } + let objectiveDateDiff = getDateDiff(earliestStartDate, lastEndDate); + let currentDateDiff = getDateDiff(earliestStartDate, new Date()); + + let 목표데이터_배열 = [resource_count, req_count, objectiveDateDiff]; + let 현재진행데이터_배열 = [resource_count, req_in_action, currentDateDiff]; + let dateDiff = Math.abs(objectiveDateDiff - currentDateDiff).toFixed(0); + + $("#progressDateRate").text((currentDateDiff*100/(objectiveDateDiff === 0 ? 1 : objectiveDateDiff)).toFixed(0)+"%"); + if(objectiveDateDiff>= currentDateDiff) { + $("#remaining_days").text("D-"+dateDiff); + } else { + $("#remaining_days").text("D+"+dateDiff); + $("#remaining_days").css("color", "rgb(219,42,52)"); + } + drawBasicRadar("radarPart",목표데이터_배열, 현재진행데이터_배열); + + } + } + }); + } + +} + +const getDateDiff = (d1, d2) => { + const date1 = new Date(d1); + const date2 = new Date(d2); + + const diffDate = date1.getTime() - date2.getTime(); + + return +(Math.abs(diffDate / (1000 * 60 * 60 * 24)).toFixed(0)); // 밀리세컨 * 초 * 분 * 시 = 일 + +} + +function 변수값_초기화() { + req_count =0 + linkedIssue_subtask_count =0 + resource_count =0; + req_in_action =0; + $("#total_req_count").text("-"); // 총 요구사항 수(미할당포함) + $("#no_assigned_req_count").text("-"); // 미할당 요구사항 수 + $("#req_count").text("-"); // 작업 대상 요구사항 수 + $("#req_in_action_count").text("-"); // 작업중 요구사항 + + $("#total_linkedIssue_subtask_count").text("-"); //연결이슈 수 + $("#no_assigned_linkedIssue_subtask_count").text("-"); //미할당 연결이슈 수 + $("#linkedIssue_subtask_count_per_req_in_action").text("-"); // 작업중 요구사항에 대한 연결이슈 평균 + + $("#resource_count").text("-"); // 작업자수 + $("#req_in_action_avg").text("-"); // 작업중 요구사항 평균 + $("#avg_linkedIssue_count").text("-"); // 연결이슈 평균 + + let radarChart = echarts.getInstanceByDom(document.getElementById("radarPart")); + if(radarChart) { radarChart.dispose(); } +}