Index: arms/js/analysisCost.js =================================================================== diff -u -r2d883339525ee7ae56b5e7f67c9dd41a10f32f1e -ra54357de72a58f5276a9c5bf10948ab8b5e83c42 --- arms/js/analysisCost.js (.../analysisCost.js) (revision 2d883339525ee7ae56b5e7f67c9dd41a10f32f1e) +++ arms/js/analysisCost.js (.../analysisCost.js) (revision a54357de72a58f5276a9c5bf10948ab8b5e83c42) @@ -10,13 +10,7 @@ var pdServiceListData; var versionListData; -const personData = { - "홍길동": { total: 2000000, salary: 1400000, performance: 600000 }, - "이순신": { total: 3000000, salary: 1800000, performance: 1200000 }, - "유관순": { total: 1500000, salary: 600000, performance: 900000 }, - "안중근": { total: 1200000, salary: 480000, performance: 720000 }, - "세종대왕": { total: 1800000, salary: 720000, performance: 1080000 } -}; +var personData = {}; //////////////////////////////////////////////////////////////////////////////////////// //Document Ready @@ -63,10 +57,7 @@ "../reference/jquery-plugins/d3-5.16.0/d3.min.js", // 생성한 차트 import "js/analysis/topmenu/basicRadar.js", - "js/analysis/topmenu/topMenu.js", - - //CirclePacking with d3 Chart - "js/analysis/resource/chart/circularPackingChart.js" + "js/analysis/topmenu/topMenu.js" ], [ "../reference/jquery-plugins/dataTables-1.10.16/media/css/jquery.dataTables_lightblue4.css", @@ -97,7 +88,6 @@ candleStickChart(); - manPowerAnalysisChart(); //제품(서비스) 셀렉트 박스 이니시에이터 makePdServiceSelectBox(); @@ -109,28 +99,10 @@ // 비용 입력 costInput(); - const selectElement = document.getElementById('person-select'); - - for (const person in personData) { - const optionElement = document.createElement('option'); - optionElement.value = person; - optionElement.text = person; - selectElement.appendChild(optionElement); - } - - let firstPerson = selectElement.options[0].value; // 첫번째 option의 value를 가져옵니다. - console.log(firstPerson); - gaugeRingManPowerAnalysisChart(firstPerson); - - document.getElementById('person-select').addEventListener('change', function() { - let selectedPerson = this.value; - console.log(selectedPerson); - - gaugeRingManPowerAnalysisChart(selectedPerson); - }); }) - .catch(function () { + .catch(function (e) { console.error("플러그인 로드 중 오류 발생"); + console.error(e); }); } @@ -210,10 +182,7 @@ // 요구사항 및 연결이슈 통계 getReqAndLinkedIssueData(selectedPdServiceId, selectedVersionId); - // Circular Packing with D3 차트 - getReqStatusAndAssignees(selectedPdServiceId, selectedVersionId); - - + 담당자목록_조회(); //요구사항 현황 데이터 테이블 로드 // console.log(" ============ makeVersionMultiSelectBox ============= "); // endPointUrl = @@ -817,79 +786,6 @@ return year + "-" + month + "-" + day; } -///////////////////////////////////////////////////////// -// Circular Packing Chart -///////////////////////////////////////////////////////// -function getReqStatusAndAssignees(pdServiceLink, pdServiceVersionLinks) { - - const url = new UrlBuilder() - .setBaseUrl("/auth-user/api/arms/analysis/scope/req-status-and-reqInvolved-unique-assignees") - .addQueryParam("요구_사항.isReqType","REQUIREMENT") - .addQueryParam("요구_사항.pdServiceLink", selectedPdServiceId) - .addQueryParam("요구_사항.pdServiceVersionLinks", selectedVersionId) - .addQueryParam('요구_사항.메인그룹필드', "pdServiceVersion") - .addQueryParam('요구_사항.컨텐츠보기여부', false) - .addQueryParam('요구_사항.크기', 10000) - .addQueryParam('요구_사항.하위그룹필드들', "key,assignee.assignee_emailAddress.keyword") - .addQueryParam('요구_사항.하위크기', 10000) - .addQueryParam("하위_이슈_사항.isReqType","ISSUE") - .addQueryParam("하위_이슈_사항.pdServiceLink", selectedPdServiceId) - .addQueryParam("하위_이슈_사항.pdServiceVersionLinks", selectedVersionId) - .addQueryParam('하위_이슈_사항.메인그룹필드', "parentReqKey") - .addQueryParam('하위_이슈_사항.컨텐츠보기여부', false) - .addQueryParam('하위_이슈_사항.크기', 10000) - .addQueryParam('하위_이슈_사항.하위그룹필드들', "assignee.assignee_emailAddress.keyword") - .addQueryParam('하위_이슈_사항.하위크기', 10000) - .build(); - - $.ajax({ - url: url, - type: "GET", - contentType: "application/json;charset=UTF-8", - dataType: "json", - progress: true, - statusCode: { - 200: function (result) { - console.log("[ analysisScope :: getReqStatusAndAssignees ] :: result"); - console.log(result); - let pdServiceName; - pdServiceListData.forEach(elements => { - if (elements["pdServiceId"] === +pdServiceLink) { - pdServiceName = elements["pdServiceName"]; - } - }); - let dataObject = {}; - let issueStatusSet = new Set(); - let issueStatusList = []; - if (result.length > 0) { - for (let i = 0; i < result.length; i++) { - // 버전이름 가져오기 - let versionName =""; - for (let j = 0; j < versionListData.length; j++) { - if(result[i]["제품_서비스_버전"] === versionListData[j]["c_id"]){ - versionName = versionListData[j]["c_title"].replaceAll(".","_"); - break; - } - } - let verSubObject = {}; - result[i]["요구사항들"].forEach((element) => { - // 작업자수가 0이 아닌 요구 사항만 (담당자 배정된 요구사항만) - if (element["작업자수"] !== 0) { - verSubObject[element["요구_사항_번호"]] = - {"$count" : element["작업자수"], "$status" : element["요구_사항_상태"]}; - issueStatusSet.add(element["요구_사항_상태"]); - } - }); - dataObject[versionName] = verSubObject; - } - } - issueStatusSet.forEach(e=>issueStatusList.push(e)); - drawCircularPacking("circularPacking",pdServiceName,dataObject, issueStatusList); - } - } - }); -} - function chord(data) { const $container = document.getElementById("circular_sankey"); const $chart = makeChart(data); @@ -992,153 +888,153 @@ // 요구사항 별 수익 현황 그래프 ///////////////////////////////////////////////////////// function incomeStatusChart(){ -var chartDom = document.getElementById('income_status_chart'); -var myChart = echarts.init(chartDom); -var option; + var chartDom = document.getElementById('income_status_chart'); + var myChart = echarts.init(chartDom); + var option; -option = { - xAxis: { - type: 'category', - data: [ - '2024-01-01', - '2024-01-11', - '2024-01-12', - '2024-01-17', - '2024-01-23', - '2024-02-12', - '2024-02-11' - ], - axisLabel: { - color: '#FFFFFF' - } - }, - yAxis: { - type: 'value', - axisLabel: { - color: '#FFFFFF' - } - }, - legend: { - data: ['예상', '소모 비용', '투자비용'] , - textStyle: { - color: '#FFFFFF' // 범례 텍스트 색상 변경 - } - }, - series: [ - { - data: [0, 50, 100, 150, 200, 250, 300], - type: 'line', - name: '예상', // 첫 번째 선에 대한 라벨 - lineStyle: { - type: 'dashed' // 선의 스타일을 점선으로 변경 - }, - markLine: { - lineStyle: { - color: 'red', // line color - type: 'dashed', // line style - width: 3 // line width + option = { + xAxis: { + type: 'category', + data: [ + '2024-01-01', + '2024-01-11', + '2024-01-12', + '2024-01-17', + '2024-01-23', + '2024-02-12', + '2024-02-11' + ], + axisLabel: { + color: '#FFFFFF' + } }, - label: { - position: 'middle', // label이 markLine의 중간에 위치하도록 설정 - formatter: '투자 비용', // label의 텍스트 설정 - fontSize: 15, // label의 폰트 크기 설정 - color: '#FFFFFF' + yAxis: { + type: 'value', + axisLabel: { + color: '#FFFFFF' + } }, - data: [ - { - yAxis: 300, - name: '투자비용' // line label - } - ] - } - }, - { - data: [0, 100, 120, 120, 280, 320, 320], - type: 'line', - name: '소모 비용', - markLine: { - lineStyle: { - color: 'red', // line color - type: 'dashed', // line style - width: 3 // line width + legend: { + data: ['예상', '소모 비용', '투자비용'] , + textStyle: { + color: '#FFFFFF' // 범례 텍스트 색상 변경 + } }, - label: { - position: 'middle', // label이 markLine의 중간에 위치하도록 설정 - formatter: '요구사항 기한', // label의 텍스트 설정 - fontSize: 15, // label의 폰트 크기 설정 - color: '#FFFFFF' - }, - data: [ - { - xAxis: 6, - name: '투자비용' // line label - } + series: [ + { + data: [0, 50, 100, 150, 200, 250, 300], + type: 'line', + name: '예상', // 첫 번째 선에 대한 라벨 + lineStyle: { + type: 'dashed' // 선의 스타일을 점선으로 변경 + }, + markLine: { + lineStyle: { + color: 'red', // line color + type: 'dashed', // line style + width: 3 // line width + }, + label: { + position: 'middle', // label이 markLine의 중간에 위치하도록 설정 + formatter: '투자 비용', // label의 텍스트 설정 + fontSize: 15, // label의 폰트 크기 설정 + color: '#FFFFFF' + }, + data: [ + { + yAxis: 300, + name: '투자비용' // line label + } + ] + } + }, + { + data: [0, 100, 120, 120, 280, 320, 320], + type: 'line', + name: '소모 비용', + markLine: { + lineStyle: { + color: 'red', // line color + type: 'dashed', // line style + width: 3 // line width + }, + label: { + position: 'middle', // label이 markLine의 중간에 위치하도록 설정 + formatter: '요구사항 기한', // label의 텍스트 설정 + fontSize: 15, // label의 폰트 크기 설정 + color: '#FFFFFF' + }, + data: [ + { + xAxis: 6, + name: '투자비용' // line label + } + ] + } + } ] - } - } - ] -}; + }; -option && myChart.setOption(option); + option && myChart.setOption(option); } ///////////////////////////////////////////////////////// // 투입 비용 현황 차트 ///////////////////////////////////////////////////////// function compareCostsChart(selectedPdServiceId, selectedVersionId){ -var chartDom = document.getElementById("compare_costs"); -var myChart = echarts.init(chartDom); -var option; -var titles = versionListData.map(item => item.c_title); + var chartDom = document.getElementById("compare_costs"); + var myChart = echarts.init(chartDom); + var option; + var titles = versionListData.map(item => item.c_title); -option = { - tooltip: { - trigger: 'axis', - axisPointer: { - type: 'shadow' - } - }, - legend: { - textStyle: { - color: '#FFFFFF' - } - }, - grid: { - left: '3%', - right: '4%', - bottom: '3%', - containLabel: true - }, - xAxis: { - type: 'value', - boundaryGap: [0, 0.01], - axisLabel: { - color: '#FFFFFF' - } - }, - yAxis: { - type: 'category', - data: titles, - axisLabel: { - color: '#FFFFFF' - } - }, - series: [ - { - name: '투자 비용', - type: 'bar', - data: [18203, 23489, 29034, 104970] - }, - { - name: '소모 비용', - type: 'bar', - data: [19325, 23438, 31000, 121594] - } - ] -}; + option = { + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow' + } + }, + legend: { + textStyle: { + color: '#FFFFFF' + } + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true + }, + xAxis: { + type: 'value', + boundaryGap: [0, 0.01], + axisLabel: { + color: '#FFFFFF' + } + }, + yAxis: { + type: 'category', + data: titles, + axisLabel: { + color: '#FFFFFF' + } + }, + series: [ + { + name: '투자 비용', + type: 'bar', + data: [18203, 23489, 29034, 104970] + }, + { + name: '소모 비용', + type: 'bar', + data: [19325, 23438, 31000, 121594] + } + ] + }; -option && myChart.setOption(option); + option && myChart.setOption(option); } //////////////////////////////////////////////////////////////////////////////////////// @@ -1723,13 +1619,13 @@ left: 10, containLabel: true }, -/* { - top: '55%', - width: '100%', - bottom: 0, - left: 10, - containLabel: true - }*/ + /* { + top: '55%', + width: '100%', + bottom: 0, + left: 10, + containLabel: true + }*/ ], xAxis: [ { @@ -1810,7 +1706,12 @@ window.addEventListener('resize', myChart.resize); } -function manPowerAnalysisChart() { +function manPowerAnalysisChart(selectedPerson) { + + let manPowerData = personData[selectedPerson]; + console.log(selectedPerson); + console.log(manPowerData); + var dom = document.getElementById('manpower-analysis-chart'); var myChart = echarts.init(dom, null, { renderer: 'canvas', @@ -1819,19 +1720,20 @@ var option; - var salaryArr = [200, 100, 66, 200, 150, 150, 77, 23]; - var revenueArr = [100, 50, 30, 20, 10, 5, 3, 66]; + // var salaryArr = [200, 100, 66, 200, 150, 150, 77, 23]; + // var revenueArr = [100, 50, 30, 20, 10, 5, 3, 66]; + // + // var maxArr = salaryArr.map(function(salary, i) { + // return { + // value: Math.max(salary, revenueArr[i]), + // symbolSize: [0, 0] + // }; + // }); - var maxArr = salaryArr.map(function(salary, i) { - return { - value: Math.max(salary, revenueArr[i]), - symbolSize: [0, 0] - }; - }); - option = { grid: { top: 50, + left: '20 %', bottom: '5%', }, tooltip: { @@ -1841,7 +1743,7 @@ }, }, xAxis: { - data: ['사슴', '로켓', '비행기', '기차', '배', '자동차', '달리기', '걷기'], + data: [selectedPerson], axisTick: { show: false }, axisLine: { show: false }, axisLabel: { @@ -1850,50 +1752,41 @@ }, yAxis: { splitLine: { show: false }, - axisTick: { show: false }, - axisLine: { show: false }, - axisLabel: { show: false } + axisTick: { show: true }, + axisLine: { show: true }, + axisLabel: { + show: true, + color: '#ffffff' + } }, /*color: ['#e54035'],*/ series: [ { - name: 'glyph', - type: 'pictorialBar', - barGap: '-100%', - symbolPosition: 'end', - symbolSize: 50, - symbolOffset: [0, '-120%'], - barCategoryGap: '40%', - label: { - show: true, - position: 'outside' - }, - data: maxArr, - tooltip: { - show: false - } - }, - { name: '연봉', type: 'pictorialBar', - barCategoryGap: '-130%', + barCategoryGap: '0%', // symbol: 'path://M0,10 L10,10 L5,0 L0,10 z', symbol: 'path://M0,10 C10,10 10,0 20,0 C30,0 30,10 40,10', itemStyle: { opacity: 0.5 }, emphasis: { itemStyle: { - opacity: 1 + opacity: 0.7 } }, - data: salaryArr, - z: 10 + data: [manPowerData.salary], + z: 10, + label: { + show: true, + position: 'outside', + color: "white", // 여기에 'color' 속성을 추가해주세요. + }, }, { name: '벌어들인 수익', type: 'pictorialBar', - barCategoryGap: '-100%', + barCategoryGap: '0%', // symbol: 'path://M0,10 L10,10 L5,0 L0,10 z', symbol: 'path://M0,10 C10,10 10,0 20,0 C30,0 30,10 40,10', itemStyle: { @@ -1902,12 +1795,17 @@ }, emphasis: { itemStyle: { - opacity: 1, + opacity: 0.7, } }, - data: revenueArr, - z: 10 + data: [manPowerData.performance], + z: 10, + label: { + show: true, + position: 'outside', + color: "white", // 여기에 'color' 속성을 추가해주세요. + }, }, ] }; @@ -1919,163 +1817,90 @@ window.addEventListener('resize', myChart.resize); } -function gaugeRingManPowerAnalysisChart(selectedPerson) { - - let manPowerData = personData[selectedPerson]; - console.log(manPowerData); - - var dom = document.getElementById('gauge-ring-container'); - var myChart = echarts.init(dom, null, { - renderer: 'canvas', +// 주식차트 +function candleStickChart() { + var dom = document.getElementById("candlestick-chart-container"); + var myChart = echarts.init(dom, "dark", { + renderer: "canvas", useDirtyRect: false }); - var app = {}; var option; - const gaugeData = [ - { - value: (manPowerData.salary / manPowerData.salary) * 100, - name: '연봉', - title: { - offsetCenter: ['0%', '0%'], - color: '#fff' - }, - detail: { - valueAnimation: true, - offsetCenter: ['0%', '10%'] - } - }, - { - value: (manPowerData.performance / manPowerData.salary) * 100, - name: '성과', - title: { - offsetCenter: ['0%', '-30%'], - color: '#fff' - }, - detail: { - valueAnimation: true, - offsetCenter: ['0%', '-20%'] - } - } - ]; option = { + xAxis: { + data: ["2017-10-24", "2017-10-25", "2017-10-26", "2017-10-27"] + }, + yAxis: {}, series: [ { - type: 'gauge', - startAngle: 90, - endAngle: -270, - pointer: { - show: false - }, - progress: { - show: true, - overlap: false, - roundCap: true, - clip: false, - itemStyle: { - borderWidth: 1, - borderColor: '#464646' - } - }, - axisLine: { - lineStyle: { - width: 50 - } - }, - splitLine: { - show: false, - distance: 0, - length: 10 - }, - axisTick: { - show: false - }, - axisLabel: { - show: false, - distance: 50 - }, - data: gaugeData, - title: { - fontSize: 14 - }, - detail: { - width: 50, - height: 14, - fontSize: 14, - color: 'white', - borderColor: 'inherit', - borderRadius: 20, - borderWidth: 1, - valueAnimation: true, - offsetCenter: ['0%', '10%'], - formatter: function(params) { - return (params * manPowerData.salary / 100).toFixed(0); // 실제 금액 표시 - } - } + type: "candlestick", + data: [ + [20, 34, 10, 38], + [40, 35, 30, 50], + [31, 38, 33, 44], + [38, 15, 5, 42] + ] } - ] + ], + tooltip: { + trigger: "axis", + position: "top", + borderWidth: 1, + axisPointer: { + type: "cross" + } + }, + backgroundColor: "rgba(255,255,255,0)" }; -// myChart.setOption(option); - myChart.setOption({ - series: [ - { - data: gaugeData, - pointer: { - show: false - } - } - ] - }); - - if (option && typeof option === 'object') { - myChart.setOption(option); + if (option && typeof option === "object") { + myChart.setOption(option, true); } - window.addEventListener('resize', myChart.resize); + window.addEventListener("resize", myChart.resize); } -// 주식차트 -function candleStickChart() { - var dom = document.getElementById("candlestick-chart-container"); - var myChart = echarts.init(dom, "dark", { - renderer: "canvas", - useDirtyRect: false - }); +function 담당자목록_조회() { + // 초기화 로직 + $("#person-select-box").hide(); + $('.person-data + .bootstrap-select .dropdown-menu').empty(); + $('.person-data + .bootstrap-select .filter-option').text(""); - var option; + var data = { + "홍길동": { total: 2000000, salary: 1400000, performance: 600000 }, + "이순신": { total: 3000000, salary: 1800000, performance: 1200000 }, + "유관순": { total: 1500000, salary: 600000, performance: 900000 }, + "안중근": { total: 1200000, salary: 480000, performance: 720000 }, + "세종대왕": { total: 1800000, salary: 720000, performance: 1080000 } + }; - option = { - xAxis: { - data: ["2017-10-24", "2017-10-25", "2017-10-26", "2017-10-27"] - }, - yAxis: {}, - series: [ - { - type: "candlestick", - data: [ - [20, 34, 10, 38], - [40, 35, 30, 50], - [31, 38, 33, 44], - [38, 15, 5, 42] - ] - } - ], - tooltip: { - trigger: "axis", - position: "top", - borderWidth: 1, - axisPointer: { - type: "cross" - } - }, - backgroundColor: "rgba(255,255,255,0)" - }; + personData = data; - if (option && typeof option === "object") { - myChart.setOption(option, true); - } + var options = Object.keys(personData); + if (options.length > 0) { + $("#person-select-box").show(); + $("#first-person-select").text(options[0]); + manPowerAnalysisChart(options[0]); - window.addEventListener("resize", myChart.resize); + $.each(options, function(index, option) { + $('.person-data').append($('