////////////////// //Document Ready ////////////////// var selectedPdServiceId; // 제품(서비스) 아이디 var selectedVersionId; // 선택된 버전 아이디 var dataTableRef; var req_state, resource_info, issue_info, period_info, total_days_progress; var labelType, useGradients, nativeTextSupport, animate; //투입 인력별 요구사항 관여 차트 var chartColorMap; var usedColorSet = new Set(); var usedColors = []; var currentDate; function execDocReady() { var pluginGroups = [ [ "../reference/light-blue/lib/vendor/jquery.ui.widget.js", "../reference/light-blue/lib/vendor/http_blueimp.github.io_JavaScript-Templates_js_tmpl.js", "../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", "../reference/lightblue4/docs/lib/widgster/widgster.js", "../reference/lightblue4/docs/lib/slimScroll/jquery.slimscroll.min.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", "../reference/jquery-plugins/select2-4.0.2/dist/js/select2.min.js", "../reference/jquery-plugins/lou-multi-select-0.9.12/js/jquery.quicksearch.js", "../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", // jspreadsheet "../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/jsuites.js", "../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/jsuites.css", "../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/index.js", "../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/jspreadsheet.css", "../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/jspreadsheet.theme.css" ], [ //d3 "../reference/jquery-plugins/d3-5.16.0/d3.min.js", //chart Colors "./js/common/colorPalette.js", // Apache Echarts "../reference/jquery-plugins/echarts-5.4.3/dist/echarts.min.js", // 투입 인력별 요구사항 관여 차트 "../reference/jquery-plugins/Jit-2.0.1/jit.js", "../reference/jquery-plugins/Jit-2.0.1/Examples/css/Treemap.css", "./css/analysis/analysis.css", "./js/common/chart/others/treemap.js", // 제품-버전-투입인력 차트 "../reference/jquery-plugins/d3-sankey-v0.12.3/d3-sankey.min.js", "./js/common/chart/d3/sankey.js", // 최상단 메뉴 "./js/analysis/topmenu/topMenuApi.js", "./js/common/chart/eCharts/basicRadar.js", "./js/analysis/api/resourceApi.js", "./js/common/chart/eCharts/horizontalBarChart.js", "./js/common/chart/eCharts/simplePie.js", //table_new "./js/common/table_new.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", "../reference/jquery-plugins/dataTables-1.10.16/media/js/jquery.dataTables.min.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Responsive/js/dataTables.responsive.min.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Select/js/dataTables.select.min.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/RowGroup/js/dataTables.rowsGroup.min.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/dataTables.buttons.min.js", "../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/vfs_fonts.js", // word-cloud(tag-cloud) "../reference/jquery-plugins/jQCloud-2.0.3/dist/jqcloud.js", "../reference/jquery-plugins/jQCloud-2.0.3/dist/jqcloud.css" ] // 추가적인 플러그인 그룹들을 이곳에 추가하면 됩니다. ]; loadPluginGroupsParallelAndSequential(pluginGroups) .then(function () { //vfs_fonts 파일이 커서 defer 처리 함. setTimeout(function () { var script = document.createElement("script"); script.src = "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/vfs_fonts.js"; script.defer = true; // defer 속성 설정 document.head.appendChild(script); }, 5000); // 5초 후에 실행됩니다. //pdfmake 파일이 커서 defer 처리 함. setTimeout(function () { var script = document.createElement("script"); script.src = "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/pdfmake.min.js"; script.defer = true; // defer 속성 설정 document.head.appendChild(script); }, 5000); // 5초 후에 실행됩니다. // 사이드 메뉴 색상 설정 $(".widget").widgster(); setSideMenu("sidebar_menu_insight", "sidebar_menu_analysis", "sidebar_menu_analysis_resource"); //제품(서비스) 셀렉트 박스 이니시에이터 makePdServiceSelectBox(); //버전 멀티 셀렉트 박스 이니시에이터 makeVersionMultiSelectBox(); // 차트색상 맵 초기화 chartColorMap = new Map(); //데이터테이블초기화 $("#workerStatusTable").trigger($.Event("init.workerStatusTable")); // 오늘 날짜 설정 currentDate = getCurrentDate(); // 높이 조정 $(".top-menu-div").matchHeight({ target: $(".top-menu-div-scope") }); $(".workerStatusTableSection").matchHeight({ target: $(".sankeySection") }); }) .catch(function () { console.error("플러그인 로드 중 오류 발생"); }); } ////////////////////////////////////////////// // 우하단 StackedHorizontalBar ////////////////////////////////////////////// function stackedHorizontalBar() { function stackedHorizontalBarChartInit(yAxis, seriesData) { let chartDom = document.getElementById("apache-echarts-stacked-horizontal-bar"); let myChart = echarts.init(chartDom); const 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; } }, legend: { left: "left", // data: statusTypes, textStyle: { color: "white", fontSize: 11 } }, grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true }, xAxis: { type: "value", axisLabel: { textStyle: { color: "white", fontWeight: "", fontSize: "11" } }, splitLine: { lineStyle: { type: "dashed", color: "white", width: 0.2, opacity: 0.5 } } }, yAxis: { type: yAxis["type"], data: yAxis["data"], axisLabel: { textStyle: { color: "white", fontWeight: "", fontSize: "11" }, formatter: function (value) { if (value.length > 15) { // 길이가 15보다 크면 생략 return value.substr(0, 15) + "..."; // 일부만 표시하고 "..." 추가 } else { return value; } } } }, series: seriesData.map((element) => { return { name: element.name, type: element.type, stack: "total", label: { show: true }, emphasis: { focus: "series" }, data: element.data }; }) }; option && myChart.setOption(option); window.addEventListener("resize", function () { myChart.resize(); }); } $.ajax({ url: "/auth-admin/api/arms/analysis/resource/issue-status-stacked-bar", type: "GET", data: { "pdServiceAndIsReq.pdServiceLink": selectedPdServiceId, "pdServiceAndIsReq.pdServiceVersionLinks": selectedVersionId }, contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function (result) { console.log("[analysisResource :: issue-status-stacked-bar] :: 결과 "); let apiResponse = result.response; stackedHorizontalBarChartInit(apiResponse.yaxisVO, apiResponse.series); } } }); } /////////////////////// //제품 서비스 셀렉트 박스 ////////////////////// function makePdServiceSelectBox() { //제품 서비스 셀렉트 박스 이니시에이터 $(".chzn-select").each(function () { $(this).select2($(this).data()); }); //제품 서비스 셀렉트 박스 데이터 바인딩 $.ajax({ url: "/auth-user/api/arms/pdServicePure/getPdServiceMonitor.do", type: "GET", contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, async: false, statusCode: { 200: function (data) { ////////////////////////////////////////////////////////// for (var k in data.response) { var obj = data.response[k]; var newOption = new Option(obj.c_title, obj.c_id, false, false); $("#selected_pdService").append(newOption).trigger("change"); } ////////////////////////////////////////////////////////// } } }); $("#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(); }); } // end makePdServiceSelectBox() //////////////////////////////////////////////////////////// //버전 멀티 셀렉트 박스 (버전 옵션 선택 시) //////////////////////////////////////////////////////////// function makeVersionMultiSelectBox() { //버전 선택시 셀렉트 박스 이니시에이터 $(".multiple-select").multipleSelect({ filter: true, onClose: function () { console.log("onOpen event fire!\n"); var checked = $("#checkbox1").is(":checked"); var endPointUrl = ""; var versionTag = $(".multiple-select").val(); console.log("[ analysisResource :: makeVersionMultiSelectBox ] :: versionTag"); console.log(versionTag); if (versionTag === null || versionTag == "") { jError("버전이 선택되지 않았습니다."); $(".ms-parent").css("z-index", 1000); return; } selectedVersionId = versionTag.join(","); // 최상단 메뉴 세팅 TopMenuApi.톱메뉴_초기화(); TopMenuApi.톱메뉴_세팅(); refreshDetailChart(); 레이더_스택바_초기화(); // 요구사항 및 연결이슈 통계 issueContributorPie(selectedPdServiceId, selectedVersionId); // 작업자별 상태 - dataTable drawResource(selectedPdServiceId, selectedVersionId); // 샌키 versionAssigneesSankeyChart($("#selected_pdService").val(), selectedVersionId, "chart-product-manpower"); $("#btn_modal_sankey").click(); drawManRequirementTreeMapChart($("#selected_pdService").val(), selectedVersionId, 1000,"chart-manpower-requirement"); // word-cloud wordCloud(); // horizontalStackedBar stackedHorizontalBar(); $(".ms-parent").css("z-index", 1000); }, onOpen: function () { console.log("open event"); $(".ms-parent").css("z-index", 9999); } }); } //////////////////////////////////////////////////////////// // 제품서비스 - 버전 데이터 바인딩 (제품 선택 시) //////////////////////////////////////////////////////////// function bind_VersionData_By_PdService() { $(".multiple-select option").remove(); $.ajax({ url: "/auth-user/api/arms/pdService/getVersionList?c_id=" + $("#selected_pdService").val(), type: "GET", dataType: "json", progress: true, statusCode: { 200: function (data) { ////////////////////////////////////////////////////////// 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); } refreshDetailChart(); 레이더_스택바_초기화(); selectedVersionId = pdServiceVersionIds.join(","); // 최상단 메뉴 세팅 TopMenuApi.톱메뉴_초기화(); TopMenuApi.톱메뉴_세팅(); // 요구사항 및 연결이슈 통계 issueContributorPie(selectedPdServiceId, selectedVersionId); // 작업자별 상태 - dataTable drawResource(selectedPdServiceId, selectedVersionId); versionAssigneesSankeyChart(selectedPdServiceId, selectedVersionId, "chart-product-manpower"); drawManRequirementTreeMapChart(selectedPdServiceId, selectedVersionId, 1000, "chart-manpower-requirement"); stackedHorizontalBar(); wordCloud(); if (data.length > 0) { console.log("display 재설정."); } $(".multiple-select").multipleSelect("refresh"); ////////////////////////////////////////////////////////// } } }); } ///////////////////////////////////////// // wordCloud ///////////////////////////////////////// function wordCloud() { $("#tag-cloud").jQCloud("destroy"); $.ajax({ url: "/auth-admin/api/arms/analysis/resource/word-cloud-data", type: "GET", data: { "pdServiceAndIsReq.pdServiceLink": selectedPdServiceId, "pdServiceAndIsReq.pdServiceVersionLinks": selectedVersionId }, contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, async: false, statusCode: { 200: function (apiResponse) { console.log("[analysisResource :: wordCloud] :: 결과 => ", apiResponse); $("#tag-cloud").jQCloud(apiResponse, { colors: ColorPalette.otherChartLib.goldWightColors }); } } }); } // 데이터 테이블 구성 이후 꼭 구현해야 할 메소드 : 열 클릭시 이벤트 function dataTableClick(tempDataTable, selectedData) { console.log(selectedData); } //데이터 테이블 그리고 난 후 시퀀스 이벤트 function dataTableCallBack(settings, json) { console.log("dataTableCallBack"); } //데이터 테이블 그리고 난 후 시퀀스 이벤트 function dataTableDrawCallback(tableInfo) { console.log("dataTableDrawCallback"); } function issueContributorPie(pdServiceLink, pdServiceVersionLinks, isReq, size) { return new Promise((resolve, reject) => { $.ajax({ url: "/auth-admin/api/arms/analysis/resource/top-contributors/pie", type: "GET", data: { "pdServiceAndIsReq.pdServiceLink": pdServiceLink, "pdServiceAndIsReq.pdServiceVersionLinks": pdServiceVersionLinks, "pdServiceAndIsReq.isReq": isReq, numSize: size ? size : 5 }, contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function (data) { let reqPie = data.reqPieChartVO; let notReqPie = data.notReqPieChartVO; let rTotalIssueCount = reqPie.totalIssueCount; let nrTotalIssueCount = notReqPie.totalIssueCount; let rTop5IssueTotal = 0; let nrTop5IssueTotal = 0; let assigneeDTOs_r = []; let assigneeDTOs_nr = []; let dataMapForPieChart_r = []; let dataMapForPieChart_nr = []; if (rTotalIssueCount == null || rTotalIssueCount === 0) { drawSimplePieChart("req_pie", "요구사항 이슈", []); } if (nrTotalIssueCount == null || nrTotalIssueCount === 0) { drawSimplePieChart("linkedIssue_subtask_pie", "하위작업 및 연결이슈", []); } // req reqPie.assigneeAndIssueCounts.forEach((element, index) => { var assigneeDTO = { name: "", serverId: "", accountId: "", emailAddress: "" }; assigneeDTO.name = element.name; assigneeDTO.serverId = element.serverId; assigneeDTO.accountId = element.accountId; if (element.emailAddress) { let idFromMail = getIdFromMail(element.emailAddress); element.name = element.name + " (" + idFromMail + ")"; assigneeDTO.emailAddress = element.emailAddress; } // 차트컬러 Map 에 key 가 있음 if (chartColorMap.has(element.name)) { let colorIdx = chartColorMap.get(element.name); element.itemStyle = { color: ColorPalette.eCharts.pieChart[colorIdx] }; usedColors.push(ColorPalette.eCharts.pieChart[colorIdx]); // 사용된 색상 기록 } // 차트컬러 Map 에 key 가 없음 else { // 색상이 중복되면 다른 색상 찾기 let colorIdx = index; while (usedColors.includes(ColorPalette.eCharts.pieChart[colorIdx])) { colorIdx = (colorIdx + 1) % ColorPalette.eCharts.pieChart.length; // 색상 범위를 벗어나지 않게 함 } chartColorMap.set(element.name, colorIdx); element.itemStyle = { color: ColorPalette.eCharts.pieChart[colorIdx] }; usedColors.push(ColorPalette.eCharts.pieChart[colorIdx]); // 사용된 색상 기록 } assigneeDTOs_r.push(assigneeDTO); dataMapForPieChart_r.push(element); if (index <= 4) { rTop5IssueTotal += element.value; } }); if (rTotalIssueCount !== rTop5IssueTotal) { dataMapForPieChart_r.push({ name: "etc.", value: rTotalIssueCount - rTop5IssueTotal, itemStyle: { color: "rgba(245, 160, 220, 0.7)" } }); } // notReq notReqPie.assigneeAndIssueCounts.forEach((element, index) => { var assigneeDTO = { name: "", serverId: "", accountId: "", emailAddress: "" }; assigneeDTO.name = element.name; assigneeDTO.serverId = element.serverId; assigneeDTO.accountId = element.accountId; if (element.emailAddress) { let idFromMail = getIdFromMail(element.emailAddress); element.name = element.name + " (" + idFromMail + ")"; assigneeDTO.emailAddress = element.emailAddress; } // 차트컬러 Map 에 key 가 있음 if (chartColorMap.has(element.name)) { let colorIdx = chartColorMap.get(element.name); element.itemStyle = { color: ColorPalette.eCharts.pieChart[colorIdx] }; usedColors.push(ColorPalette.eCharts.pieChart[colorIdx]); // 사용된 색상 기록 } // 차트컬러 Map 에 key 가 없음 else { // 색상이 중복되면 다른 색상 찾기 let colorIdx = index; while (usedColors.includes(ColorPalette.eCharts.pieChart[colorIdx])) { colorIdx = (colorIdx + 1) % ColorPalette.eCharts.pieChart.length; // 색상 범위를 벗어나지 않게 함 } chartColorMap.set(element.name, colorIdx); element.itemStyle = { color: ColorPalette.eCharts.pieChart[colorIdx] }; usedColors.push(ColorPalette.eCharts.pieChart[colorIdx]); // 사용된 색상 기록 } assigneeDTOs_nr.push(assigneeDTO); dataMapForPieChart_nr.push(element); if (index <= 4) { nrTop5IssueTotal += element.value; } }); if (nrTotalIssueCount !== nrTop5IssueTotal) { dataMapForPieChart_nr.push({ name: "etc.", value: nrTotalIssueCount - nrTop5IssueTotal, itemStyle: { color: "rgba(245, 160, 220, 0.7)" } }); } drawSimplePieChart("req_pie", "요구사항 이슈", dataMapForPieChart_r); drawSimplePieChart("linkedIssue_subtask_pie", "하위작업 및 연결이슈", dataMapForPieChart_nr); let accounts_r = []; if (assigneeDTOs_r.length > 0) { assigneeDTOs_r.forEach((e) => { accounts_r.push(btoa(e.accountId)); }); issueContributorHorizontalBarChart(pdServiceLink, pdServiceVersionLinks, accounts_r,true); } let accounts_nr = []; if (assigneeDTOs_nr.length > 0) { assigneeDTOs_nr.forEach((e) => { accounts_nr.push(btoa(e.accountId)); }); issueContributorHorizontalBarChart(pdServiceLink, pdServiceVersionLinks, accounts_nr,false); } // req, notReq 또는 rAccount, nrAccount resolve(); }, error: function (e) { jError("작업자_이슈_집계 데이터 Status 조회에 실패했습니다. 나중에 다시 시도 바랍니다."); } } }); }); } // 수평바 차트 데이터 조회 (r, nr 같은 account) function issueContributorHorizontalBarChartAtOnce(pdServiceLink, pdServiceVersionLinks, accounts, isReq) { $.ajax({ url: "/auth-admin/api/arms/analysis/resource/top-contributors/horizontal-bar-at-once", type: "POST", data: JSON.stringify({ pdServiceAndIsReq: { pdServiceLink: pdServiceLink, pdServiceVersionLinks: pdServiceVersionLinks.split(",").map(Number), isReq: null }, accounts: accounts }), contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function (data) { let rResult = data.reqChartYAxisAndSeriesVOList; let nrResult = data.notReqChartYAxisAndSeriesVOList; let $rTargetId, $nrTargetId; if (isReq && isReq === true) { rResult.forEach((e) => { if (e.name === "status") { console.log("rResult e.name => status"); $rTargetId = "req-status-bar"; } else if (e.name === "priority") { console.log("rResult e.name => priority"); $rTargetId = "req-priority-bar"; } else if (e.name === "issuetype") { console.log("rResult e.name => issuetype"); $rTargetId = "req-issuetype-bar"; } e.series.forEach((element) => { if (element.emailAddress) { let idFromMail = getIdFromMail(element.emailAddress); element.name = element.name + " (" + idFromMail + ")"; } if (chartColorMap.has(element.name)) { // 해당 name에 해당하는 색상 인덱스를 chartColorMap에서 가져옴 let colorIdx = chartColorMap.get(element.name); // itemStyle에 color를 설정 element.itemStyle = { color: ColorPalette.eCharts.pieChart[colorIdx] }; } }); drawHorizontalBarChart($rTargetId, e.yaxisVO["data"], e.series); }); } else if (isReq && isReq === false) { nrResult.forEach((e) => { if (e.name === "status") { console.log("nrResult e.name => status"); $nrTargetId = "subtask-status-bar"; } else if (e.name === "priority") { console.log("nrResult e.name => priority"); $nrTargetId = "subtask-priority-bar"; } else if (e.name === "issuetype") { console.log("nrResult e.name => issuetype"); $nrTargetId = "subtask-issuetype-bar"; } e.series.forEach((element) => { if (element.emailAddress) { let idFromMail = getIdFromMail(element.emailAddress); element.name = element.name + " (" + idFromMail + ")"; } if (chartColorMap.has(element.name)) { // 해당 name에 해당하는 색상 인덱스를 chartColorMap에서 가져옴 let colorIdx = chartColorMap.get(element.name); // itemStyle에 color를 설정 element.itemStyle = { color: ColorPalette.eCharts.pieChart[colorIdx] }; } }); drawHorizontalBarChart($nrTargetId, e.yaxisVO["data"], e.series); }); } else { rResult.forEach((e) => { if (e.name === "status") { console.log("rResult e.name => status"); $rTargetId = "req-status-bar"; } else if (e.name === "priority") { console.log("rResult e.name => priority"); $rTargetId = "req-priority-bar"; } else if (e.name === "issuetype") { console.log("rResult e.name => issuetype"); $rTargetId = "req-issuetype-bar"; } e.series.forEach((element) => { if (element.emailAddress) { let idFromMail = getIdFromMail(element.emailAddress); element.name = element.name + " (" + idFromMail + ")"; } if (chartColorMap.has(element.name)) { // 해당 name에 해당하는 색상 인덱스를 chartColorMap에서 가져옴 let colorIdx = chartColorMap.get(element.name); // itemStyle에 color를 설정 element.itemStyle = { color: ColorPalette.eCharts.pieChart[colorIdx] }; } }); drawHorizontalBarChart($rTargetId, e.yaxisVO["data"], e.series); }); nrResult.forEach((e) => { if (e.name === "status") { console.log("nrResult e.name => status"); $nrTargetId = "subtask-status-bar"; } else if (e.name === "priority") { console.log("nrResult e.name => priority"); $nrTargetId = "subtask-priority-bar"; } else if (e.name === "issuetype") { console.log("nrResult e.name => issuetype"); $nrTargetId = "subtask-issuetype-bar"; } e.series.forEach((element) => { if (element.emailAddress) { let idFromMail = getIdFromMail(element.emailAddress); element.name = element.name + " (" + idFromMail + ")"; } if (chartColorMap.has(element.name)) { // 해당 name에 해당하는 색상 인덱스를 chartColorMap에서 가져옴 let colorIdx = chartColorMap.get(element.name); // itemStyle에 color를 설정 element.itemStyle = { color: ColorPalette.eCharts.pieChart[colorIdx] }; } }); drawHorizontalBarChart($nrTargetId, e.yaxisVO["data"], e.series); }); } } } }); } function issueContributorHorizontalBarChart(pdServiceLink, pdServiceVersionLinks, accounts, isReq) { $.ajax({ url: "/auth-admin/api/arms/analysis/resource/top-contributors/horizontal-bar", type: "POST", data: JSON.stringify({ pdServiceAndIsReq: { pdServiceLink: pdServiceLink, pdServiceVersionLinks: pdServiceVersionLinks.split(",").map(Number), isReq: isReq }, accounts: accounts }), contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function (data) { let $rTargetId, $nrTargetId; if (isReq && isReq === true) { data.forEach((e) => { if (e.name === "status") { $rTargetId = "req-status-bar"; } else if (e.name === "priority") { $rTargetId = "req-priority-bar"; } else if (e.name === "issuetype") { $rTargetId = "req-issuetype-bar"; } e.series.forEach((element) => { if (element.emailAddress) { let idFromMail = getIdFromMail(element.emailAddress); element.name = element.name + " (" + idFromMail + ")"; } if (chartColorMap.has(element.name)) { // 해당 name에 해당하는 색상 인덱스를 chartColorMap에서 가져옴 let colorIdx = chartColorMap.get(element.name); // itemStyle에 color를 설정 element.itemStyle = { color: ColorPalette.eCharts.pieChart[colorIdx] }; } }); drawHorizontalBarChart($rTargetId, e.yaxisVO["data"], e.series); }); } else { data.forEach((e) => { if (e.name === "status") { $nrTargetId = "subtask-status-bar"; } else if (e.name === "priority") { $nrTargetId = "subtask-priority-bar"; } else if (e.name === "issuetype") { $nrTargetId = "subtask-issuetype-bar"; } e.series.forEach((element) => { if (element.emailAddress) { let idFromMail = getIdFromMail(element.emailAddress); element.name = element.name + " (" + idFromMail + ")"; } if (chartColorMap.has(element.name)) { // 해당 name에 해당하는 색상 인덱스를 chartColorMap에서 가져옴 let colorIdx = chartColorMap.get(element.name); // itemStyle에 color를 설정 element.itemStyle = { color: ColorPalette.eCharts.pieChart[colorIdx] }; } }); drawHorizontalBarChart($nrTargetId, e.yaxisVO["data"], e.series); }); } } } }); } var drawResource = function (pdservice_id, pdServiceVersionLinks) { var deferred = $.Deferred(); var pdId = pdservice_id; var verLinks = pdServiceVersionLinks; ResourceApi.fetchResourceData(pdId, verLinks).done(function () { var fetchedReousrceData = ResourceApi.getFetchedResourceData(); $("#workerStatusTable").table().reDraw(fetchedReousrceData); deferred.resolve(); }); return deferred.promise(); }; function refreshDetailChart() { // 차트8개 초기화 disposeDetailChartInstance(); chartColorMap = new Map(); usedColors = []; } function disposeDetailChartInstance() { const params = ResourceApi.getHorizontalBarParamMap(); var properties = params.properties; properties.forEach((element, idx) => { let reqChartInstance = echarts.getInstanceByDom(document.getElementById(params[element]["target-req"])); let subtaskChartInstance = echarts.getInstanceByDom(document.getElementById(params[element]["target-notReq"])); if (reqChartInstance) { reqChartInstance.dispose(); } if (subtaskChartInstance) { subtaskChartInstance.dispose(); } }); } //email에서 ID 만 가져오기 function getIdFromMail(param) { var full_str = param; var indexOfAt = full_str.indexOf("@"); return full_str.substring(0, indexOfAt); } function 레이더_스택바_초기화() { let radarChart = echarts.getInstanceByDom(document.getElementById("radarPart")); if (radarChart) { radarChart.dispose(); } let stackBarChart = echarts.getInstanceByDom(document.getElementById("apache-echarts-stacked-horizontal-bar")); if (stackBarChart) { stackBarChart.dispose(); } } //////////////////////////////////////////////////////////////////////////////////////// // 투입 인력별 요구사항 관여 차트 생성 (트리맵) //////////////////////////////////////////////////////////////////////////////////////// function drawManRequirementTreeMapChart(pdServiceLink, pdServiceVersionLinks, size, targetElementId) { $.ajax({ url: "/auth-admin/api/arms/analysis/resource/assignees-requirements-involvements-v3", type: "GET", data: { "pdServiceAndIsReq.pdServiceLink": pdServiceLink, "pdServiceAndIsReq.pdServiceVersionLinks": pdServiceVersionLinks, size: size ? size : 1000 }, contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, async: false, statusCode: { 200: function (apiResponse) { const data = apiResponse.response; console.log("[analysisResource :: drawManRequirementTreeMapChart ] :: response"); console.log(data); if ($("#modal_chart").children().length !== 0) { $("#modal_chart").empty(); } if ($("#chart-manpower-requirement").children().length !== 0) { $("#chart-manpower-requirement").empty(); } const treeMapInfos = { id: "chart_root", name: "작업자별 요구사항 관여 트리맵", data: {}, children: data }; init(treeMapInfos, targetElementId); } } }); } var getCurrentDate = function () { let today = new Date(); let year = today.getFullYear().toString(); let month = (today.getMonth() + 1).toString().padStart(2, "0"); let day = today.getDate().toString().padStart(2, "0"); return year + month + day; }; +(function ($) { function getStatusWithIcon(statusName) { const icon = modalStatusIcons[statusName]?.icon || modalStatusIcons["기타"].icon; return `${icon} ${statusName}`.trim(); } const modalStatusIcons = { 열림: { icon: '' }, 진행중: { icon: '' }, "진행 중": { icon: '' }, 종료: { icon: '' }, 해결됨: { icon: '' }, 닫힘: { icon: '' }, 기타: { icon: '' } }; let workerStatusColumns = [ { name: "uniqueAssigneeVO.name", title: "작업자 이름", data: "uniqueAssigneeVO.name", className: "dt-body-center", defaultContent: "-", visible: true, render: function (data, type, row, meta) { if (type === "display") { return '"; } return data; } }, { name: "uniqueAssigneeVO.emailAddress", title: "작업자 메일", data: "uniqueAssigneeVO.emailAddress", className: "dt-body-center", defaultContent: "-", visible: true, render: function (data, type, row, meta) { if (type === "display") { if (data && data !== "") { return '"; } else { return '"; } } return data; } }, { name: "totalIssueCount", title: "요구사항 및 하위/연결이슈 합계", data: "totalIssueCount", className: "dt-body-right", defaultContent: "-", visible: false, render: function (data, type, row, meta) { if (type === "display") { if (data) { return '"; } else { return '"; } } return data; } }, { name: "reqIssueCount", title: "요구사항 이슈", data: "reqIssueCount", className: "dt-body-right", defaultContent: "-", visible: true, render: function (data, type, row, meta) { if (type === "display") { if (data) { return '"; } else { return '"; } } return data; } }, { name: "notReqIssueCount", title: "하위/연결이슈", data: "notReqIssueCount", className: "dt-body-right", defaultContent: "-", visible: true, render: function (data, type, row, meta) { if (type === "display") { if (data) { return '"; } else { return '"; } } return data; } }, { name: "reqIssueProperties", title: "요구사항 이슈 상태", data: "reqIssueProperties", className: "dt-body-right", defaultContent: "-", visible: true, render: function (data, type, row, meta) { if (type === "display") { var reqIssueProperties = data; if (reqIssueProperties && reqIssueProperties.length !== 0) { let return_status = ""; reqIssueProperties.forEach((data, index) => { return_status += getStatusWithIcon(data["name"]) + " - " + data["value"]; // return_status += data["name"] + " - " + data["value"]; return_status += "
"; }); return '"; } else { return '"; } } return data; } }, { name: "notReqIssueProperties", title: "연결이슈 상태", data: "notReqIssueProperties", className: "dt-body-right", defaultContent: "-", visible: true, render: function (data, type, row, meta) { if (type === "display") { var notReqIssueProperties = data; if (notReqIssueProperties && notReqIssueProperties.length !== 0) { let return_status = ""; notReqIssueProperties.forEach((data, index) => { return_status += getStatusWithIcon(data["name"]) + " - " + data["value"]; // return_status += data["name"] + " - " + data["value"]; return_status += "
"; }); return '"; } else { return '"; } } return data; } }, { name: "uniqueAssigneeVO.accountId", title: "계정 아이디", data: "uniqueAssigneeVO.accountId", visible: false, defaultContent: "N/A" }, { name: "uniqueAssigneeVO.serverId", title: "ALM 서버 아이디", data: "uniqueAssignee.serverId", visible: false, defaultContent: "N/A" } ]; $(document).one("init.workerStatusTable", function () { let lastScrollTop = 0; $("#workerStatusTable") .on("checkbox.toggle.table", function (event, rowData, $row, isChecked) { if (isChecked === true) { disposeDetailChartInstance(); ResourceApi.pushCustomAssignee(rowData["uniqueAssigneeVO"]); issueContributorHorizontalBarChartAtOnce(selectedPdServiceId, selectedVersionId, ResourceApi.getCustomBtoaAccounts()); } else { ResourceApi.removeCustomAssignee(rowData["uniqueAssigneeVO"]); disposeDetailChartInstance(); // 전체 선택 해제 일 경우, if (ResourceApi.getCustomAssignees().length === 0) { issueContributorPie(selectedPdServiceId, selectedVersionId); } issueContributorHorizontalBarChartAtOnce(selectedPdServiceId, selectedVersionId, ResourceApi.getCustomBtoaAccounts()); } }) .on("length.dt", function () { lastScrollTop = $(window).scrollTop(); }) .on("page.dt", function () { console.log("workerStatusTable :: page.dt"); lastScrollTop = $(window).scrollTop(); }) .on("draw.dt", function () { $(window).scrollTop(lastScrollTop); }) .table({ order: [], columns: workerStatusColumns, isAddCheckbox: true, scrollCollapse: false, scrollY: "400px", data: [], drawCallback: function () { console.log("workerStatusTable :: drawCallback"); } }); }); })(jQuery);