Index: arms/js/dashboard.js =================================================================== diff -u -r8b7f73456cca89b6dd4ba0f4787e5a437cffe1ef -r944620c4dd5cc2016f84fc13f504c930b3ded3e0 --- arms/js/dashboard.js (.../dashboard.js) (revision 8b7f73456cca89b6dd4ba0f4787e5a437cffe1ef) +++ arms/js/dashboard.js (.../dashboard.js) (revision 944620c4dd5cc2016f84fc13f504c930b3ded3e0) @@ -217,9 +217,8 @@ selectedVersionId = versionTag.join(','); DashboardApi.대시보드_톱메뉴_초기화(); - DashboardApi.대시보드_톱메뉴_세팅(); + DashboardApi.대시보드_톱메뉴_세팅(selectedPdServiceId, selectedVersionId); - combinationChart($("#selected_pdService").val(), selectedVersionId); drawProductToManSankeyChart($("#selected_pdService").val(), selectedVersionId); drawManRequirementTreeMapChart($("#selected_pdService").val(), selectedVersionId); @@ -234,6 +233,7 @@ function bind_VersionData_By_PdService() { $(".multiple-select option").remove(); + console.log("[Dashboard :: bind_VersionData_By_PdService] :: 실행"); $.ajax({ url: "/auth-user/api/arms/pdService/getVersionList.do?c_id=" + $("#selected_pdService").val(), type: "GET", @@ -254,9 +254,8 @@ selectedVersionId = pdServiceVersionIds.join(','); DashboardApi.대시보드_톱메뉴_초기화(); - DashboardApi.대시보드_톱메뉴_세팅(); + DashboardApi.대시보드_톱메뉴_세팅(selectedPdServiceId,selectedVersionId); - combinationChart($("#selected_pdService").val(), selectedVersionId); drawProductToManSankeyChart($("#selected_pdService").val(), selectedVersionId); drawManRequirementTreeMapChart($("#selected_pdService").val(), selectedVersionId); @@ -1122,7 +1121,7 @@ .addQueryParam('하위그룹필드들', "assignee.assignee_accountId.keyword,assignee.assignee_displayName.keyword") .addQueryParam('크기', 1000) .addQueryParam('하위크기', 1000) - .addQueryParam('컨텐츠보기여부', true) + .addQueryParam('컨텐츠보기여부', false) .build(); $.ajax({ @@ -1188,7 +1187,7 @@ groups: [issueStatusTypes] }, color: { - pattern: dashboardColor.accumulatedIssueStatusColor, + pattern: dashboardColor.combinationChartColor, }, onrendered: function() { d3.selectAll('.c3-line, .c3-bar, .c3-arc') Index: arms/js/dashboard/api/dashboardApi.js =================================================================== diff -u -r8b7f73456cca89b6dd4ba0f4787e5a437cffe1ef -r944620c4dd5cc2016f84fc13f504c930b3ded3e0 --- arms/js/dashboard/api/dashboardApi.js (.../dashboardApi.js) (revision 8b7f73456cca89b6dd4ba0f4787e5a437cffe1ef) +++ arms/js/dashboard/api/dashboardApi.js (.../dashboardApi.js) (revision 944620c4dd5cc2016f84fc13f504c930b3ded3e0) @@ -1,6 +1,9 @@ var DashboardApi = (function () { "use strict"; + var dashboard_pdServiceId; + var dashboard_pdServiceVersionLinks; + // 버전정보 - gauge, timeLine var version_info = []; @@ -255,8 +258,11 @@ }); }; - function 대시보드_톱메뉴_세팅() { - DashboardApi.pullTotalApi(selectedPdServiceId, selectedVersionId) + function 대시보드_톱메뉴_세팅(pdService_id, pdServiceVersionLinks) { + dashboard_pdServiceId = pdService_id; + dashboard_pdServiceVersionLinks = pdServiceVersionLinks; + + DashboardApi.pullTotalApi(dashboard_pdServiceId, dashboard_pdServiceVersionLinks) .then(() => { req_state = DashboardApi.getReqStateData(); timeStatus_info = DashboardApi.getTimeStatus(); @@ -295,6 +301,7 @@ }) .then(() => { 대시보드_도넛차트("donut-chart"); + 대시보드_콤비네이션차트("combination-chart"); }) .catch((error) => { console.error('Error occurred:', error); @@ -367,7 +374,7 @@ let totalDocCount = reqStateData["total"]; const chart = c3.generate({ - bindto: '#donut-chart', + bindto: $targetId, data: { columns: columnsData, type: 'donut', @@ -387,7 +394,7 @@ }, }); - $(document).on('click', '#donut-chart .c3-legend-item', function () { + $(document).on('click', $targetId +' .c3-legend-item', function () { const id = $(this).text(); let isHidden = false; @@ -413,10 +420,170 @@ totalDocCount += docCount; } } - $($targetId +'.c3-chart-arcs-title').text("Total : " + totalDocCount); + $($targetId +' .c3-chart-arcs-title').text("Total : " + totalDocCount); }); } + function 대시보드_콤비네이션차트(targetElementId) { + let $targetId = "#"+targetElementId; // "#combination-chart" + + + function combinationChartNoData() { + c3.generate({ + bindto: $targetId, + data: { + x: 'x', + columns: [], + type: 'bar', + types: {}, + }, + }); + } + + if(!targetElementId) { + combinationChartNoData(); + return false; + } + + if(dashboard_pdServiceId === "" || dashboard_pdServiceVersionLinks === "") { + combinationChartNoData(); + return false; + } + + const url = new UrlBuilder() + .setBaseUrl('/auth-user/api/arms/dashboard/requirements-jira-issue-statuses') + .addQueryParam('pdServiceLink', dashboard_pdServiceId) + .addQueryParam('pdServiceVersionLinks', dashboard_pdServiceVersionLinks) + .addQueryParam('메인그룹필드', "pdServiceVersion") + .addQueryParam('하위그룹필드들', "assignee.assignee_accountId.keyword,assignee.assignee_displayName.keyword") + .addQueryParam('크기', 1000) + .addQueryParam('하위크기', 1000) + .addQueryParam('컨텐츠보기여부', false) + .build(); + + $.ajax({ + url: url, + type: "GET", + contentType: "application/json;charset=UTF-8", + dataType: "json", + progress: true, + statusCode: { + 200: function (apiResponse) { + const data = apiResponse.response; + if ((Array.isArray(data) && data.length === 0) || + (typeof data === 'object' && Object.keys(data).length === 0) || + (typeof data === 'string' && data === "{}")) { + combinationChartNoData(); + return; + } + + const issueStatusTypesSet = new Set(); + for (const month in data) { + for (const status in data[month].statuses) { + issueStatusTypesSet.add(status); + } + } + const issueStatusTypes = [...issueStatusTypesSet]; + + let columnsData = []; + + issueStatusTypes.forEach((status) => { + const columnData = [status]; + for (const month in data) { + const count = data[month].statuses[status] || 0; + columnData.push(count); + } + columnsData.push(columnData); + }); + + const requirementCounts = ['요구사항']; + for (const month in data) { + requirementCounts.push(data[month].totalRequirements); + } + columnsData.push(requirementCounts); + + let monthlyTotals = {}; + + for (const month in data) { + monthlyTotals[month] = data[month].totalIssues + data[month].totalRequirements; + } + + + const chart = c3.generate({ + bindto: $targetId, + data: { + x: 'x', + columns: [ + ['x', ...Object.keys(data)], + ...columnsData, + ], + type: 'bar', + types: { + '요구사항': 'area', + }, + groups: [issueStatusTypes] + }, + color: { + pattern: dashboardColor.combinationChartColor, + }, + onrendered: function() { + d3.selectAll('.c3-line, .c3-bar, .c3-arc') + .style('stroke', 'white') + .style('stroke-width', '0.3px'); + }, + axis: { + x: { + type: 'category', + }, + }, + tooltip: { + format: { + title: function (index) { + const month = Object.keys(data)[index]; + const total = monthlyTotals[month]; + return `${month} | Total : ${total}`; + }, + }, + } + }); + + $(document).on('click', $targetId+' .c3-legend-item', function () { + let id = this.__data__; + let isHidden = false; + + if($(this).hasClass('c3-legend-item-hidden')) { + isHidden = false; + $(this).removeClass('c3-legend-item-hidden'); + } else { + isHidden = true; + $(this).addClass('c3-legend-item-hidden'); + } + + let docCount = 0; + + for (const month in data) { + if (data[month].statuses.hasOwnProperty(id)) { + docCount = data[month].statuses[id]; + } else if (id === '요구사항') { + docCount = data[month].totalRequirements; + } + } + + // 월별 통계 값 업데이트 + for (const month in data) { + if (isHidden) { + monthlyTotals[month] -= docCount; + } else { + monthlyTotals[month] += docCount; + } + } + }); + } + } + }); + + } + return { 대시보드_톱메뉴_세팅, 대시보드_톱메뉴_초기화, pullTotalApi, Index: arms/js/dashboard/chart/colorPalette.js =================================================================== diff -u -r8b7f73456cca89b6dd4ba0f4787e5a437cffe1ef -r944620c4dd5cc2016f84fc13f504c930b3ded3e0 --- arms/js/dashboard/chart/colorPalette.js (.../colorPalette.js) (revision 8b7f73456cca89b6dd4ba0f4787e5a437cffe1ef) +++ arms/js/dashboard/chart/colorPalette.js (.../colorPalette.js) (revision 944620c4dd5cc2016f84fc13f504c930b3ded3e0) @@ -577,10 +577,38 @@ "rgba(166,86,40,0.7)" ], reqStateColor: [ - "rgba(219, 42, 52, 0.8)", - "rgba(228, 148, 0, 0.8)", - "rgba(45, 133, 21, 0.8)", - "rgba(36, 119, 255,0.8)" + "rgba(219, 42, 52, 0.7)", + "rgba(228, 148, 0, 0.7)", + "rgba(45, 133, 21, 0.7)", + "rgba(36, 119, 255,0.7)" + ], + combinationChartColor: [ + "rgba(227,26,27,0.75)", + "rgba(255,127,0,0.75)", + "rgba(192,192,128,0.8)", + "rgba(77,175,74,0.8)", + "rgba(55,125,184,0.8)", + "rgba(151,78,163,0.8)", + "rgba(166,86,40,0.8)", + "rgba(224,0,224,0.7)", + "rgba(64,128,224,0.7)", + "rgba(64,160,64,0.8)", + "rgba(192,128,96,0.8)", + "rgba(245,235,51,0.75)", + "rgba(160,96,224,0.8)", + "rgba(128,64,0,0.8)" + ], + combinationChartColor1: [ + "rgba(158, 1, 66, 0.8)", + "rgba(213, 62, 79, 0.8)", + "rgba(244, 109, 67, 0.8)", + "rgba(253, 174, 97, 0.8)", + "rgba(254, 224, 139, 0.8)", + "rgba(230, 245, 152, 0.8)", + "rgba(171, 221, 164, 0.8)", + "rgba(102, 194, 165, 0.8)", + "rgba(50, 136, 189, 0.8)", + "rgba(94, 79, 162, 0.8)" ] } }; \ No newline at end of file