let _list;
let _totList;
let ixrNm;
let istlLctn;
let unit;
let strtDt;
let endDt;
let searchBtn;
let closeBtn;
let _multiChart;
let _pieChart;
const _pageName = '교통량 통계';
const dateTime = 'yyyy-MM-dd HH:mm';
const dateHour = 'yyyy-MM-dd HH시';
const time = 'HH:mm';
const hour = 'HH시';
const date = 'yyyy-MM-dd';
const month = 'yyyy-MM';
let strtDtVal = new Date();
let endDtVal = new Date();
strtDtVal.setHours("00");
strtDtVal.setMinutes("00");
strtDtVal.setSeconds("00");
endDtVal.setHours("23");
endDtVal.setMinutes("59");
endDtVal.setSeconds("59");
let searchStart = firstSettingTime;
let searchEnd = endSettingTime;
const drctMap = new Map();
const categories = ['-', 'A', 'B', 'C', 'D', 'E', 'F', 'FF', 'FFF'];
const pieSeries = [
{
name :'교통량 통계 조회 (합계)',
data : [
{
id : 'go_tfvl',
name : '직진',
color : 'coral',
y : 0,
},
{
id : 'left_tfvl',
name : '좌회전',
color : 'rgb(124, 181, 236)',
y : 0,
},
{
id : 'rght_tfvl',
name : '우회전',
color : 'rgb(144, 237, 125)',
y : 0,
}
]
},
]
const multiSeries = [
{
name: '직진',
type : 'column',
data: [],
color : 'coral',
},
{
name: '좌회전',
type : 'column',
data: [],
color : 'rgb(124, 181, 236)',
},
{
name: '우회전',
type : 'column',
data: [],
color : 'rgb(144, 237, 125)',
},
{
name: '서비스수준 ( LOS )',
type : 'line',
yAxis: 1,
data: [],
color : 'red',
}
]
const lookupData = [
{
code : 0,
desc : '-',
},
{
code : 1,
desc : 'A',
},
{
code : 2,
desc : 'B',
},
{
code : 3,
desc : 'C',
},
{
code : 4,
desc : 'D',
},
{
code : 5,
desc : 'E',
},
{
code : 6,
desc : 'F',
},
{
code : 7,
desc : 'FF',
},
{
code : 8,
desc : 'FFF',
}
]
const unitData = [
{
unit : '15m',
desc : '15분 통계',
},
// {
// unit : '30m',
// desc : '30분 통계',
// },
{
unit : 'hh',
desc : '시간 통계(1시간)',
},
{
unit : 'dd',
desc : '일 통계(1일)',
},
{
unit : 'mn',
desc : '월 통계(1개월)',
},
];
$(()=>{
//교차로교통량 통계 테이블
let listColumns = [
{
dataField : "ixr_nm",
caption : '교차로명',
alignment : 'center',
},
{
dataField : "stat_dt",
caption : '수집일시',
alignment : 'center',
sortIndex : 1,
sortOrder : 'asc',
},
{
caption : '교통량(대)',
alignment : "center",
columns : [
{
dataField : "go_tfvl",
caption : '직진',
alignment : 'center',
format : '#,##0',
width : 80,
},
{
dataField : "left_tfvl",
caption : '좌회전',
alignment : 'center',
format : '#,##0',
width : 90,
},
{
dataField : "rght_tfvl",
caption : '우회전',
alignment : 'center',
format : '#,##0',
width : 90,
},
{
dataField : "tot_tfvl",
caption : '총교통량',
alignment : "center",
format : '#,##0',
width : 120,
},
],
},
{
dataField : "dely_hh",
caption : '지체시간(초/대)',
alignment : "center",
width : 140,
},
{
dataField : "srvc_lvl",
caption : 'LOS',
alignment : "center",
width : 70,
lookup : {
dataSource : lookupData,
displayExpr : 'desc',
valueExpr : 'code',
}
},
];
_list = initializedGrid($(".list"), '100%', '100%', listColumns,
[], 'single', 'virtual', ['ixr_nm', 'stat_dt'], false, true,
false, '', false, false, true, _pageName,
true, '', null).dxDataGrid('instance');
//교차로교통량 통계 합계 테이블
let totColumns = [
{
dataField : "go_tfvl",
caption : '직진',
alignment : 'center',
format : '#,##0',
},
{
dataField : "left_tfvl",
caption : '좌회전',
alignment : 'center',
format : '#,##0',
},
{
dataField : "rght_tfvl",
caption : '우회전',
alignment : 'center',
format : '#,##0',
},
{
dataField : "tot_tfvl",
caption : '총교통량',
alignment : "center",
format : '#,##0',
},
];
_totList = initializedGrid($(".tot-list"), '100%', '100%', totColumns,
[], 'none', 'virtual', '', false, false,
false, '', false, false, false, '',
false, '', null).dxDataGrid('instance');
_totList.option('sorting', {mode : 'none'});
ixrNm = new dxSelect($(".ixr_nm"), 'outlined', 300, 30, 'ixr_nm', 'ixr_id', false, 'ixr_id', '교차로명');
istlLctn = new dxSelect($(".istl_lctn"), 'outlined', 300, 30, 'desc', 'cmra_id', false, 'cmra_id', '설치위치');
unit = new dxSelect($(".unit"), 'outlined', 150, 30, 'desc', 'unit', false, 'unit', '단위');
strtDt = new dxDate($(".strt-dt"), 'yyyy-MM-dd', '조회기간 시작일', 110, 30, 'date', null, '', null);
strtTime = new dxDate($(".strt-time"), 'HH:mm', '조회기간 시각', 80, 30, 'time', 5, '', null);
endDt = new dxDate($(".end-dt"), 'yyyy-MM-dd', '조회기간 종료일', 110, 30, 'date', null, '', null);
endTime = new dxDate($(".end-time"), 'HH:mm', '조회기간 시각', 80, 30, 'time', 5, '', null);
unit.setDataSource(unitData);
unit.setValue('15m');
unit.onItemClick(unitClick);
strtDt.setValue(strtDtVal);
strtTime.setValue(strtDtVal);
endDt.setValue(endDtVal);
endTime.setValue(endDtVal);
ixrNm.onItemClick((e)=>ixrNmClick(e.itemData.ixr_id));
searchBtn = new dxBtn($(".search-btn"),'조회', 'refresh', 'outlined', 80, 30, false, true);
closeBtn = new dxBtn($(".close-btn"), '닫기', 'close', 'outlined', 80, 30, false, true);
closeBtn.onClick(()=>window.close());
searchBtn.onClick(searchBtnClick);
_multiChart = Highcharts.chart('multi-chart', {
chart: {
type: 'column',
backgroundColor: {
classNmae: 'dx-theme-background-color dx-theme-border-color',
},
},
title: {
text : '교통량 통계 조회',
style : {
color: $('.dx-theme-material-typography').css('color'),
},
},
xAxis: {
categories: [],
labels: {
style: {
color: $('.dx-theme-material-typography').css('color')
}
},
},
yAxis: [{
ticks : 5,
labels: {
style: {
color: $('.dx-theme-material-typography').css('color')
}
},
title: {
text: '교통량(대)',
style: {
color: $('.dx-theme-material-typography').css('color')
}
}
},
{ // Secondary yAxis
min : 1,
max : 8,
title: {
text: '서비스수준(LOS)',
style: {
color: $('.dx-theme-material-typography').css('color'),
}
},
labels: {
style: {
color: $('.dx-theme-material-typography').css('color'),
},
},
categories : categories,
opposite: true,
}],
plotOptions: {
column: {
stacking: 'percent'
}
},
legend: {
align: 'center',
verticalAlign: 'bottom',
itemStyle:{
color: $('.dx-theme-material-typography').css('color'),
},
backgroundColor: {
className : 'dx-nav-item dx-theme-border-color',
}
},
series : multiSeries,
tooltip: {
formatter: function () {
let name = this.series.name;
let dt = name.substring(0,name.indexOf('('));
if (this.series.name.indexOf('( LOS )') > -1) {
let rank = this.series.yAxis.categories[this.y];
if (this.y >= 0){
return '교통량 통계 조회
'
+ '일시 : '
+ this.x
+ '
'
+ '서비스수준(LOS) : '
+ rank
+ '';
}
}
else {
return '교통량 통계 조회 - ' + name +'
'
+ '일시 : '
+ this.x
+ '
'
+ '교통량 : '
+ this.y
+ ' 대';
}
}
},
exporting : {
enabled : false,
},
credits : {
enabled : false
},
});
_pieChart = Highcharts.chart('pie-chart', {
chart: {
type: 'pie',
marginLeft: 20,
marginTop : 20,
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
backgroundColor: {
classNmae: 'dx-theme-background-color dx-theme-border-color',
},
},
title: {
text : '교통량 통계 조회 (합계)',
y : 35,
style : {
color: $('.dx-theme-material-typography').css('color'),
},
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
size: '70%',
dataLabels: {
enabled: true,
format: '{point.name}
{point.y:,.0f} 대',
distance: -50,
filter: {
property: 'percentage',
operator: '>',
value: 4
},
color: $('.dx-theme-material-typography').css('color'),
},
showInLegend: true
}
},
tooltip : {
pointFormat: '{series.name}: {point.y}대'
},
legend: {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
floating: false,
y: 0,
borderWidth: 1,
itemStyle:{
color: $('.dx-theme-material-typography').css('color'),
},
backgroundColor: {
className : 'dx-nav-item dx-theme-border-color',
},
shadow: true,
},
exporting : {
enabled : false,
},
credits : {
enabled : false
},
series : pieSeries,
});
window.$chartArr = [_multiChart, _pieChart];
fetchBaseData();
})
function fetchBaseData(){
const uri = "/api/scrs/tb_sc_ixr_mngm";
let drctData = [];
getData(_codeUrl + '/DRCT', drctData);
if (drctData[0] && drctData[0].length > 0) {
drctData[0].map((item)=>{
drctMap.set(Number(item.cmmn_cd), item.cmmn_cd_kor_nm);
})
}
getDataAsync(uri, (jsonData)=>{
dataSorting(jsonData, 'ixr_nm');
ixrNm.setDataSource(jsonData);
if (jsonData[0]) {
ixrNm.setValue(jsonData[0].ixr_id);
ixrNmClick(jsonData[0].ixr_id);
}
})
}
/**
* 교차로 명칭 클릭 이벤트
* @param ixrIdVal 교차로 Id
*/
function ixrNmClick(ixrIdVal){
let istlData = [];
getData('/api/scrs/tb_sc_ixr_cmra_mngm/' + encodeURIComponent(ixrIdVal), istlData);
if (istlData[0] && istlData[0].length > 0) {
istlData[0].map((item)=>{
item.desc = item.istl_lctn + ' [' + drctMap.get(item.drct_dvsn_cd) + ']';
})
istlLctn.setValue(istlData[0][0].cmra_id);
}
istlLctn.setDataSource(istlData[0]);
}
/**
* 단위 클릭 변경 이벤트
* @param {*} e select 상자 정보
*/
function unitClick(e){
if (e.itemData && e.itemData.unit) {
let format = null;
let display = null;
let changeColumn = null;
const dateColumn = [strtDt, endDt];
const timeColumn = [strtTime, endTime];
const strtTimeBox = $('.strt-time-box');
const endTimeBox = $('.end-time-box');
switch (e.itemData.unit) {
case 'hh':
changeColumn = 'time';
format = hour;
display = 'flex';
break;
case 'dd':
changeColumn = 'date';
format = date;
display = 'none';
break;
case 'mn':
changeColumn = 'date';
format = month;
display = 'none';
break;
default :
changeColumn = 'time';
format = time;
display = 'flex';
break;
}
if (changeColumn) {
if (changeColumn === 'time') {
timeColumn.map((item)=>{
item.setFormat(format);
});
dateColumn.map((item)=>{
item.setFormat(date);
});
}
else {
dateColumn.map((item)=>{
item.setFormat(format);
});
}
strtTimeBox.css('display', display);
endTimeBox.css('display', display);
}
}
}
/**
* 상단 조회 버튼 이벤트
* @returns 유효성 체크용
*/
function searchBtnClick(){
if (ixrNm.isNull()) {
return alertWarning('교차로명을 선택해주세요', null, ixrNm);
}
else if (istlLctn.isNull()) {
return alertWarning('설치위치를 선택해주세요', null, istlLctn);
}
const unitVal = unit.getValue();
let timeArr = getSearchValues(unitVal);
if (timeArr.length === 0){
return;
};
const FROM_DT = timeArr[0];
const TO_DT = timeArr[1];
const idVal = ixrNm.getValue();
const cmraVal = istlLctn.getValue()
let statData = {
ixrId : idVal,
cmraIds : cmraVal,
FROM_DT : FROM_DT,
TO_DT : TO_DT,
};
let losData = {
ixrIds : idVal,
FROM_DT : FROM_DT,
TO_DT : TO_DT,
};
const stat = [];
getData("/api/scrs/statistics/tfvl/" + unitVal + '/' + idVal, stat, statData); // 교차로 통계
const los = [];
getData("/api/scrs/statistics/srvc/" + unitVal, los, losData); // 서비스수준 통계
let formatData = [];
if (stat[0] && stat[0].length > 0) {
stat[0].map((item)=>{
let clone = {...item};
if (los[0] && los[0].length > 0) {
los[0].map((obj)=>{
if (item.ixr_id === obj.ixr_id && item.stat_dt === obj.stat_dt) {
clone.srvc_lvl = nullChecker(obj.srvc_lvl) === "" ? 0 : obj.srvc_lvl;
clone.dely_hh = nullChecker(obj.dely_hh) === "" ? '-' : obj.dely_hh;
}
})
}
formatData.push(clone);
})
}
drawTableAndChart(formatData, unitVal);
}
function drawTableAndChart(jsonData, unitVal){
let xAxis = [];
let totGo = 0;
let totLeft = 0;
let totRght = 0;
let totTot = 0;
let totDataSource;
let yAxis = [
{data: []},
{data: []},
{data: []},
{data: []},
];
if (jsonData.length > 0) {
dataSorting(jsonData, 'clct_dt');
jsonData.map((item)=>{
console.log(item);
if (item.stat_dt) item.stat_dt = timeFommater(item.stat_dt, unitVal);
item.go_tfvl = 0;
item.left_tfvl = 0;
item.rght_tfvl = 0;
for (let key in item) {
if (key.indexOf("pce_") === -1 ) {
if ( key.indexOf('go') > -1 && key !== 'go_tfvl' ) {
item.go_tfvl += item[key];
}
if ( key.indexOf('left') > -1 && key !== 'left_tfvl' ) {
item.left_tfvl += item[key];
}
if ( key.indexOf('rght') > -1 && key !== 'rght_tfvl') {
item.rght_tfvl += item[key];
}
}
}
item.tot_tfvl = item.go_tfvl + item.left_tfvl + item.rght_tfvl;
totGo += item.go_tfvl;
totLeft += item.left_tfvl;
totRght += item.rght_tfvl;
totTot += item.tot_tfvl;
yAxis[0].data.push(item.go_tfvl);
yAxis[1].data.push(item.left_tfvl);
yAxis[2].data.push(item.rght_tfvl);
yAxis[3].data.push(nullChecker(item.srvc_lvl) === "" ? 0 : item.srvc_lvl);
xAxis.push(item.stat_dt);
})
totDataSource = [{
go_tfvl : totGo,
left_tfvl : totLeft,
rght_tfvl : totRght,
tot_tfvl : totTot,
}];
}
else {
totDataSource = [];
}
let pieYAxis = [
{y:totGo},
{y:totLeft},
{y:totTot},
]
_list.option('dataSource', jsonData);
_totList.option('dataSource', totDataSource);
_multiChart.update({
xAxis : {
categories : xAxis,
},
series : [
{
data : yAxis[0].data
},
{
data : yAxis[1].data
},
{
data : yAxis[2].data
},
{
data : yAxis[3].data
},
]
});
_pieChart.update({
series : [
{
data : pieYAxis
},
]
});
selResultMsg(jsonData);
}
function getSearchValues(unitVal){
const display = $('.strt-time-box').css('diplay');
let dateColumns = [strtDt, strtTime, endDt, endTime];
if (display === "none") {
dateColumns = [strtDt, endDt];
}
for (let dateColumn of dateColumns) {
if (dateColumn.isValidation()) {
alertWarning('형식에 맞게 입력해주세요. [ ' + dateColumn.label + ' ]', null, dateColumn);
return [];
}
else if (dateColumn.isNull()) {
alertWarning('조회기간을 입력해주세요. [ ' + dateColumn.label + ' ]', null, dateColumn);
return [];
}
}
let FROM_DT;
let TO_DT;
let format;
switch (unitVal) {
case '15m':
case '30m':
FROM_DT = concateVal(strtDt, 8, strtTime, 4) + '00';
TO_DT = concateVal(endDt, 8, endTime, 4) + '59';
break;
case 'hh':
FROM_DT = concateVal(strtDt, 8, strtTime, 2) + '0000';
TO_DT = concateVal(endDt, 8, endTime, 2) + '5959';
break;
case 'dd':
FROM_DT = strtDt.getSendDateValue().substring(0, 8) + '000000';
TO_DT = endDt.getSendDateValue().substring(0, 8) + '235959';
break;
case 'mn':
FROM_DT = strtDt.getSendDateValue().substring(0, 6) + '01000000';;
TO_DT = endDt.getSendDateValue().substring(0, 6) + '31235959';
break;
}
if (FROM_DT > TO_DT) {
alertWarning('검색 시작 기간 보다 검색 종료 기간이 큽니다.', null, endDt);
return [];
}
return [FROM_DT, TO_DT];
}
function concateVal(dt, dtNum, time, timeNum){
return dt.getSendDateValue().substring(0,dtNum) + time.getSendTimeValue().substring(0, timeNum);
}
function timeFommater(data, unitVal){
let str = "";
str += data.substring(0, 4);
str += "-";
str += data.substring(4, 6);
switch (unitVal) {
case '15m':
str += "-";
str += data.substring(6, 8);
str += " ";
str += data.substring(8, 10);
str += ":";
str += data.substring(10, 12);
break;
case '30m':
str += "-";
str += data.substring(6, 8);
str += " ";
str += data.substring(8, 10);
str += ":";
str += data.substring(10, 12);
break;
case 'hh':
str += "-";
str += data.substring(6, 8);
str += " ";
str += data.substring(8, 10);
str += "시";
break;
case 'dd':
str += "-";
str += data.substring(6, 8);
break;
case 'mn':
break;
}
return str;
}