대시보드 수정

main
이범준 1 year ago
parent 6d6771976f
commit 19c40e94b9

@ -5,19 +5,19 @@
<div class="card dashboard-total"> <div class="card dashboard-total">
<div class="card-body row"> <div class="card-body row">
<div class="col px-4 card-separator d-flex flex-column align-items-center"> <div class="col px-4 card-separator d-flex flex-column align-items-center">
<p class="mb-1">2/10</p> <p class="mb-1" id="card1-1">?/?</p>
<i class="svg-cctv-fixed w-px-30 d-block" title="고정형CCTV"></i> <i class="svg-cctv-fixed w-px-30 d-block" title="고정형CCTV"></i>
</div> </div>
<div class="col px-4 card-separator d-flex flex-column align-items-center"> <div class="col px-4 card-separator d-flex flex-column align-items-center">
<p class="mb-1">2/3</p> <p class="mb-1" id="card1-2">?/?</p>
<i class="svg-crackdown-road w-px-30 d-block" title="도보단속"></i> <i class="svg-crackdown-road w-px-30 d-block" title="도보단속"></i>
</div> </div>
<div class="col px-4 card-separator d-flex flex-column align-items-center"> <div class="col px-4 card-separator d-flex flex-column align-items-center">
<p class="mb-1">2/3</p> <p class="mb-1" id="card1-3">?/?</p>
<i class="svg-cctv-drive w-px-30 d-block" title="이동형CCTV"></i> <i class="svg-cctv-drive w-px-30 d-block" title="이동형CCTV"></i>
</div> </div>
<div class="col px-4 d-flex flex-column align-items-center"> <div class="col px-4 d-flex flex-column align-items-center">
<p class="mb-1">10/10</p> <p class="mb-1" id="card1-4">?/?</p>
<i class="svg-crackdown-minwon w-px-30 d-block" title="민원(즉시단속)"></i> <i class="svg-crackdown-minwon w-px-30 d-block" title="민원(즉시단속)"></i>
</div> </div>
</div> </div>
@ -29,11 +29,11 @@
<div class="card dashboard-total"> <div class="card dashboard-total">
<div class="card-body row"> <div class="card-body row">
<div class="col px-4 card-separator d-flex flex-column align-items-center"> <div class="col px-4 card-separator d-flex flex-column align-items-center">
<p class="mb-1">2/10</p> <p class="mb-1" id="card2-1">?/?</p>
<i class="svg-target-lvy w-px-30 d-block" title="등록대상"></i> <i class="svg-target-lvy w-px-30 d-block" title="등록대상"></i>
</div> </div>
<div class="col px-4 d-flex flex-column align-items-center"> <div class="col px-4 d-flex flex-column align-items-center">
<p class="mb-1">2/3</p> <p class="mb-1" id="card2-2">?/?</p>
<i class="svg-target-transfer w-px-30 d-block" title="이첩대상"></i> <i class="svg-target-transfer w-px-30 d-block" title="이첩대상"></i>
</div> </div>
</div> </div>
@ -45,15 +45,15 @@
<div class="card dashboard-total"> <div class="card dashboard-total">
<div class="card-body row"> <div class="card-body row">
<div class="col px-4 card-separator d-flex flex-column align-items-center"> <div class="col px-4 card-separator d-flex flex-column align-items-center">
<p class="mb-1">2/10</p> <p class="mb-1" id="card3-1">?/?</p>
<i class="svg-sendstat-guide w-px-30 d-block" title="계도장 발송현황"></i> <i class="svg-sendstat-guide w-px-30 d-block" title="계도장 발송현황"></i>
</div> </div>
<div class="col px-4 card-separator d-flex flex-column align-items-center"> <div class="col px-4 card-separator d-flex flex-column align-items-center">
<p class="mb-1">2/3</p> <p class="mb-1" id="card3-2">?/?</p>
<i class="svg-sendstat-before w-px-30 d-block" title="사전통보 발송현황"></i> <i class="svg-sendstat-before w-px-30 d-block" title="사전통보 발송현황"></i>
</div> </div>
<div class="col px-4 d-flex flex-column align-items-center"> <div class="col px-4 d-flex flex-column align-items-center">
<p class="mb-1">2/3</p> <p class="mb-1" id="card3-3">?/?</p>
<i class="svg-sendstat-nop w-px-30 d-block" title="고지서 발송현황"></i> <i class="svg-sendstat-nop w-px-30 d-block" title="고지서 발송현황"></i>
</div> </div>
</div> </div>
@ -65,15 +65,15 @@
<div class="card dashboard-total"> <div class="card dashboard-total">
<div class="card-body row"> <div class="card-body row">
<div class="col px-4 card-separator d-flex flex-column align-items-center"> <div class="col px-4 card-separator d-flex flex-column align-items-center">
<p class="mb-1">2/10</p> <p class="mb-1" id="card4-1">?/?</p>
<i class="svg-opn-rcp w-px-30 d-block" title="접수"></i> <i class="svg-opn-rcp w-px-30 d-block" title="접수"></i>
</div> </div>
<div class="col px-4 card-separator d-flex flex-column align-items-center"> <div class="col px-4 card-separator d-flex flex-column align-items-center">
<p class="mb-1">2/3</p> <p class="mb-1" id="card4-2">?/?</p>
<i class="svg-opn-decision w-px-30 d-block" title="수용/미수용"></i> <i class="svg-opn-decision w-px-30 d-block" title="수용/미수용"></i>
</div> </div>
<div class="col px-4 d-flex flex-column align-items-center"> <div class="col px-4 d-flex flex-column align-items-center">
<p class="mb-1">2/3</p> <p class="mb-1" id="card4-3">?/?</p>
<i class="svg-opn-selfdrop w-px-30 d-block" title="자진취하"></i> <i class="svg-opn-selfdrop w-px-30 d-block" title="자진취하"></i>
</div> </div>
</div> </div>
@ -138,13 +138,13 @@
<c:set var="dashboardScript" scope="request"> <c:set var="dashboardScript" scope="request">
var falseLineChart = `<svg xmlns="http://www.w3.org/2000/svg" var falseLineChart = `<svg xmlns="http://www.w3.org/2000/svg" class="skeleton"
height="250" viewBox="0 0 24 24" style="fill: rgba(0, 0, 0, 1);transform: ;msFilter:;"> height="250" viewBox="0 0 24 24" style="fill: rgba(0, 0, 0, 1);transform: ;msFilter:;">
<path class="skeleton" d="M3 3v17a1 1 0 0 0 1 1h17v-2H5V3H3z"></path> <path class="skeleton" d="M3 3v17a1 1 0 0 0 1 1h17v-2H5V3H3z"></path>
<path class="skeleton" d="M15.293 14.707a.999.999 0 0 0 1.414 0l5-5-1.414-1.414L16 12.586l-2.293-2.293a.999.999 0 0 0-1.414 0l-5 5 1.414 1.414L13 12.414l2.293 2.293z"></path> <path class="skeleton" d="M15.293 14.707a.999.999 0 0 0 1.414 0l5-5-1.414-1.414L16 12.586l-2.293-2.293a.999.999 0 0 0-1.414 0l-5 5 1.414 1.414L13 12.414l2.293 2.293z"></path>
</svg>`; </svg>`;
var falseDoughnutChart = `<svg xmlns="http://www.w3.org/2000/svg" var falseDoughnutChart = `<svg xmlns="http://www.w3.org/2000/svg" class="skeleton"
height="250" viewBox="0 0 24 24" style="fill: rgba(0, 0, 0, 1);transform: ;msFilter:;"> height="250" viewBox="0 0 24 24" style="fill: rgba(0, 0, 0, 1);transform: ;msFilter:;">
<path class="skeleton" d="M13 6c2.507.423 4.577 2.493 5 5h4c-.471-4.717-4.283-8.529-9-9v4z"></path> <path class="skeleton" d="M13 6c2.507.423 4.577 2.493 5 5h4c-.471-4.717-4.283-8.529-9-9v4z"></path>
<path class="skeleton" d="M18 13c-.478 2.833-2.982 4.949-5.949 4.949-3.309 0-6-2.691-6-6C6.051 8.982 8.167 6.478 11 6V2c-5.046.504-8.949 4.773-8.949 9.949 0 5.514 4.486 10 10 10 5.176 0 9.445-3.903 9.949-8.949h-4z"></path> <path class="skeleton" d="M18 13c-.478 2.833-2.982 4.949-5.949 4.949-3.309 0-6-2.691-6-6C6.051 8.982 8.167 6.478 11 6V2c-5.046.504-8.949 4.773-8.949 9.949 0 5.514 4.486 10 10 10 5.176 0 9.445-3.903 9.949-8.949h-4z"></path>
@ -154,11 +154,6 @@ fnMakeSkeleton();
sleep(3000).then(() => fnLoadStatisticsData()); sleep(3000).then(() => fnLoadStatisticsData());
//지연
function sleep(ms) {
return new Promise((r) => setTimeout(r, ms));
}
//데이터 로딩 전 이미지 표시 //데이터 로딩 전 이미지 표시
function fnMakeSkeleton(){ function fnMakeSkeleton(){
@ -179,86 +174,175 @@ function fnLoadStatisticsData(){
//TODO : ajax //TODO : ajax
var data = {}; var data = {};
fnRenderDashboardContents(data);
data = {
statItems : [
{ itemName : "고정형CCTV", completeCnt : 2, totalCnt : 10, itemCursor : "card1-1"},
{ itemName : "도보단속", completeCnt : 2, totalCnt : 3, itemCursor : "card1-2"},
{ itemName : "이동형CCTV", completeCnt : 2, totalCnt : 3, itemCursor : "card1-3"},
{ itemName : "민원(즉시단속)", completeCnt : 10, totalCnt : 10, itemCursor : "card1-4"}
]
};
fnRenderDashboardContents(data, "card1" , "progressAndTotal");
data = {
statItems : [
{ itemName : "등록대상", completeCnt : 45, totalCnt : 50, itemCursor : "card2-1"},
{ itemName : "이첩대상", completeCnt : 35, totalCnt : 40, itemCursor : "card2-2"}
]
};
fnRenderDashboardContents(data, "card2" , "progressAndTotal");
data = {
statItems : [
{ itemName : "계도장", completeCnt : 4, totalCnt : 10, itemCursor : "card3-1"},
{ itemName : "사전통보", completeCnt : 5, totalCnt : 11, itemCursor : "card3-2"},
{ itemName : "고지서", completeCnt : 6, totalCnt : 12, itemCursor : "card3-3"}
]
};
fnRenderDashboardContents(data, "card3" , "progressAndTotal");
data = {
statItems : [
{ itemName : "접수", completeCnt : 49, totalCnt : 100, itemCursor : "card4-1"},
{ itemName : "수용/미수용", completeCnt : 50, totalCnt : 98, itemCursor : "card4-2"},
{ itemName : "자진취하", completeCnt : 51, totalCnt : 97, itemCursor : "card4-3"}
]
};
fnRenderDashboardContents(data, "card4" , "progressAndTotal");
data = {
statItems : [
{ itemName : "고정형", valueByTime : [80, 150, 180, 270, 210, 160, 160, 202, 265, 210, 270, 255, 290, 360, 375] },
{ itemName : "도보", valueByTime : [80, 125, 105, 130, 215, 195, 140, 160, 230, 300, 220, 170, 210, 200, 280] },
{ itemName : "민원", valueByTime : [80, 99, 82, 90, 115, 115, 74, 75, 130, 155, 125, 90, 140, 130, 180] }
]
};
fnRenderDashboardContents(data, "lineChart" , "line");
data = {
statItems : [
{ itemName : "단속", value : 15 },
{ itemName : "계고", value : 15 },
{ itemName : "서손", value : 70 }
]
};
fnRenderDashboardContents(data, "doughnutChart1", "doughnut");
data = {
statItems : [
{ itemName : "계고장", value : 10 },
{ itemName : "사전통보", value : 10 },
{ itemName : "고지서", value : 80 }
]
};
fnRenderDashboardContents(data, "doughnutChart2", "doughnut");
data = {
statItems : [
{ itemName : "수용", value : 33 },
{ itemName : "미수용", value : 33 },
{ itemName : "자진취하", value : 34 }
]
};
fnRenderDashboardContents(data, "doughnutChart3", "doughnut");
}
//대시보드 콘텐츠 표시
function fnRenderDashboardContents(returnData, cursor, statType){
if(statType == "progressAndTotal"){
fnRenderProgressAndTotal(returnData, cursor);
return;
}
if(statType == "line"){
fnRenderLine(returnData, cursor);
return;
}
if(statType == "doughnut"){
fnRenderDoughnut(returnData, cursor);
return;
}
} }
//콘텐츠(차트) 표시 //진행건수,전체건수 표시
function fnRenderDashboardContents(data){ function fnRenderProgressAndTotal(returnData, cursor){
for(var i=0; i < returnData.statItems.length; i++){
$("#"+returnData.statItems[i].itemCursor).html(returnData.statItems[i].completeCnt + "/" + returnData.statItems[i].totalCnt);
}
if(cursor == "card1"){
mappingButtonAndMenu("btnGoToCrdn","단속 관리"); mappingButtonAndMenu("btnGoToCrdn","단속 관리");
return;
}
if(cursor == "card2"){
mappingButtonAndMenu("btnGoToOpnn","의견제출 관리"); mappingButtonAndMenu("btnGoToOpnn","의견제출 관리");
return;
}
}
$("#lineChartCardBody svg").remove(); //라인차트 표시
$("#doughnutChart1CardBody svg").remove(); function fnRenderLine(returnData, cursor){
$("#doughnutChart2CardBody svg").remove(); var yellowColor = '#ffe800';
$("#doughnutChart3CardBody svg").remove(); var cyanColor = '#28dac6';
var orangeLightColor = '#FDAC34';
$("#lineChart").show(); var borderColor = '#f0f0f0';
$("#doughnutChart1").show(); var gridColor = '#f0f0f0';
$("#doughnutChart2").show(); var tickColor = 'rgba(0, 0, 0, 0.75)'; // x & y axis tick color
$("#doughnutChart3").show();
// Color Variables $("#"+cursor).siblings("svg").remove();
const yellowColor = '#ffe800';
let borderColor, gridColor, tickColor;
borderColor = '#f0f0f0'; $("#"+cursor).show();
gridColor = '#f0f0f0';
tickColor = 'rgba(0, 0, 0, 0.75)'; // x & y axis tick color
const lineChart = document.getElementById('lineChart'); var datasets = [];
if (lineChart) { for(var i=0; i < returnData.statItems.length; i++){
const lineChartVar = new Chart(lineChart, { var defaultObject = {
type: 'line',
data: {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
datasets: [
{
data: [80, 150, 180, 270, 210, 160, 160, 202, 265, 210, 270, 255, 290, 360, 375],
label: '고정형',
borderColor: config.colors.danger,
tension: 0.5, tension: 0.5,
pointStyle: 'circle', pointStyle: 'circle',
backgroundColor: config.colors.danger,
fill: false, fill: false,
pointRadius: 1, pointRadius: 1,
pointHoverRadius: 5, pointHoverRadius: 5,
pointHoverBorderWidth: 5, pointHoverBorderWidth: 5,
pointBorderColor: 'transparent', pointBorderColor: 'transparent',
pointHoverBorderColor: config.colors.cardColor, pointHoverBorderColor: config.colors.cardColor
pointHoverBackgroundColor: config.colors.danger };
},
{ defaultObject.label = returnData.statItems[i].itemName;
data: [80, 125, 105, 130, 215, 195, 140, 160, 230, 300, 220, 170, 210, 200, 280],
label: '도보', defaultObject.data = returnData.statItems[i].valueByTime;
borderColor: config.colors.primary,
tension: 0.5, if(i % 3 == 0){
pointStyle: 'circle', defaultObject.backgroundColor = config.colors.danger;
backgroundColor: config.colors.primary, defaultObject.pointHoverBackgroundColor = config.colors.danger;
fill: false, defaultObject.borderColor = config.colors.danger
pointRadius: 1,
pointHoverRadius: 5,
pointHoverBorderWidth: 5,
pointBorderColor: 'transparent',
pointHoverBorderColor: config.colors.cardColor,
pointHoverBackgroundColor: config.colors.primary
},
{
data: [80, 99, 82, 90, 115, 115, 74, 75, 130, 155, 125, 90, 140, 130, 180],
label: '민원',
borderColor: yellowColor,
tension: 0.5,
pointStyle: 'circle',
backgroundColor: yellowColor,
fill: false,
pointRadius: 1,
pointHoverRadius: 5,
pointHoverBorderWidth: 5,
pointBorderColor: 'transparent',
pointHoverBorderColor: config.colors.cardColor,
pointHoverBackgroundColor: yellowColor
} }
] if(i % 3 == 1){
defaultObject.backgroundColor = config.colors.primary;
defaultObject.pointHoverBackgroundColor = config.colors.primary;
defaultObject.borderColor = config.colors.primary;
}
if(i % 3 == 2){
defaultObject.backgroundColor = yellowColor;
defaultObject.pointHoverBackgroundColor = yellowColor;
defaultObject.borderColor = yellowColor;
}
datasets.push(defaultObject);
}
var lineChart = document.getElementById(cursor);
if (lineChart) {
var lineChartVar = new Chart(lineChart, {
type: 'line',
data: {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
datasets: datasets
}, },
options: { options: {
responsive: true, responsive: true,
@ -316,77 +400,52 @@ function fnRenderDashboardContents(data){
} }
}); });
} }
return;
}
// Color Variables //도넛차트 표시
const cyanColor = '#28dac6', function fnRenderDoughnut(returnData, cursor){
orangeLightColor = '#FDAC34'; var yellowColor = '#ffe800';
let cardColor, headingColor, labelColor, legendColor; var cyanColor = '#28dac6';
var orangeLightColor = '#FDAC34';
var borderColor = '#f0f0f0';
var gridColor = '#f0f0f0';
var tickColor = 'rgba(0, 0, 0, 0.75)'; // x & y axis tick color
var cardColor = config.colors.cardColor;
var headingColor = config.colors.headingColor;
var labelColor = config.colors.textMuted;
var legendColor = config.colors.bodyColor;
$("#"+cursor).siblings("svg").remove();
$("#"+cursor).show();
var lebels = [];
var datas = [];
var colors = [];
for(var i=0; i < returnData.statItems.length; i++){
lebels.push(returnData.statItems[i].itemName);
datas.push(returnData.statItems[i].value);
if(i % 3 == 0){ colors.push(cyanColor); }
if(i % 3 == 1){ colors.push(orangeLightColor); }
if(i % 3 == 2){ colors.push(config.colors.primary); }
}
cardColor = config.colors.cardColor;
headingColor = config.colors.headingColor;
labelColor = config.colors.textMuted;
legendColor = config.colors.bodyColor;
const doughnutChart1 = document.getElementById('doughnutChart1'); var doughnutChart = document.getElementById(cursor);
if (doughnutChart1) { if (doughnutChart) {
const doughnutChartVar = new Chart(doughnutChart1, { var doughnutChartVar = new Chart(doughnutChart, {
type: 'doughnut', type: 'doughnut',
data: { data: {
labels: ['단속', '계고', '서손'], labels: lebels,
datasets: [ datasets: [
{ {
data: [10, 10, 80], data: datas,
backgroundColor: [cyanColor, orangeLightColor, config.colors.primary], backgroundColor: colors,
borderWidth: 0,
pointStyle: 'rectRounded'
}
]
},
options: {
responsive: true,
animation: {
duration: 500
},
cutout: '68%',
plugins: {
legend: {
display: true,
position : 'left'
},
tooltip: {
callbacks: {
label: function (context) {
const label = context.label || '';
const value = context.parsed;
const output = ' ' + label + ' : ' + value + ' %';
return output;
}
},
// Updated default tooltip UI
rtl: true,
backgroundColor: cardColor,
titleColor: headingColor,
bodyColor: legendColor,
borderWidth: 1, borderWidth: 1,
borderColor: borderColor
}
}
}
});
}
const doughnutChart2 = document.getElementById('doughnutChart2');
if (doughnutChart2) {
const doughnutChartVar = new Chart(doughnutChart2, {
type: 'doughnut',
data: {
labels: ['계고장', '사전통보', '고지서'],
datasets: [
{
data: [10, 10, 80],
backgroundColor: [cyanColor, orangeLightColor, config.colors.primary],
borderWidth: 0,
pointStyle: 'rectRounded' pointStyle: 'rectRounded'
} }
] ]
@ -423,55 +482,13 @@ function fnRenderDashboardContents(data){
} }
}); });
} }
return;
const doughnutChart3 = document.getElementById('doughnutChart3');
if (doughnutChart3) {
const doughnutChartVar = new Chart(doughnutChart3, {
type: 'doughnut',
data: {
labels: ['수용', '미수용', '자진취하'],
datasets: [
{
data: [10, 10, 80],
backgroundColor: [cyanColor, orangeLightColor, config.colors.primary],
borderWidth: 0,
pointStyle: 'rectRounded'
}
]
},
options: {
responsive: true,
animation: {
duration: 500
},
cutout: '68%',
plugins: {
legend: {
display: true,
position : 'left'
},
tooltip: {
callbacks: {
label: function (context) {
const label = context.label || '';
const value = context.parsed;
const output = ' ' + label + ' : ' + value + ' %';
return output;
}
},
// Updated default tooltip UI
rtl: true,
backgroundColor: cardColor,
titleColor: headingColor,
bodyColor: legendColor,
borderWidth: 1,
borderColor: borderColor
}
}
}
});
}
} }
</c:set> </c:set>

@ -1,3 +1,8 @@
//지연
function sleep(ms) {
return new Promise((r) => setTimeout(r, ms));
}
/************************************************************************** /**************************************************************************
* validation * validation
**************************************************************************/ **************************************************************************/

Loading…
Cancel
Save