Chart.js MixedChart 막대차트와 라인차트.
테스트 코드지만.. 힘들게 짰는데.. 역시 필요가 없게 되었다. 코드 파기하기전에 복붙해놓고...나중에 공부해야지. 나중이 과연 오긴 할까.. 일단 복붙이라도 ㅠㅠ
const mainMixedChart = {
mainTrfByAcsr : null, // 시간대별 접근로 교통량 차트
mainTrfByAcsr15mi: null, // 시간대별 접근로 교통량 15분 데이터 차트
mainPdstByAcsr : null, // 시간대별 접근로 보행자 차트
mainLosByAcsr : null, // 시간대별 접근로 보행자 차트
init:function(){
mainMixedChart.getTrfByAcsr_1hh(); // 시간대별 접근로 교통량 1시간 테이블
mainMixedChart.initChart(); // 시간대별 접근로 교통량 15분 테이블
},
getTrfByAcsr_1hh: function() {
comm.noAsyncAjax("/main/getTrfByAcsr.json", null, function(data){
const avgData = data["AVG"];
const listData = data["LIST"];
let lineChartGroupData = {};
avgData.forEach(function(item) {
if (!lineChartGroupData[item.ACSR_ID]) {
lineChartGroupData[item.ACSR_ID] = {
labels: [],
TRF_QNTY: []
};
}
lineChartGroupData[item.ACSR_ID].labels.push((item.TOT_DT));
lineChartGroupData[item.ACSR_ID].TRF_QNTY.push(item.TRF_QNTY);
});
//console.log("lineChartGroupData lineChartGroupData ::: "+JSON.stringify(lineChartGroupData) );
let barChartGroupData = {};
listData.forEach(function(item) {
if (!barChartGroupData[item.ACSR_ID]) {
barChartGroupData[item.ACSR_ID] = {
labels: [],
TRF_QNTY: []
};
}
barChartGroupData[item.ACSR_ID].labels.push((item.TOT_DT).split(' ')[1].substring(0, 5));
barChartGroupData[item.ACSR_ID].TRF_QNTY.push(item.TRF_QNTY);
});
// 각 ACSR_ID에 대한 데이터를 Chart.js 라인 차트에 적용
Object.keys(lineChartGroupData).forEach(function(ACSR_ID) {
const ctx = document.getElementById('mainTrfByAcsr').getContext("2d");
const colorAry = ['rgb(171, 224, 218)', 'rgb(185, 216, 218)', 'rgb(138, 176, 176)', 'rgba(138, 176, 176, 0.1)'];
// 그라디언트 생성
const gradient = ctx.createLinearGradient(0, 0, 0, 400); // 그라디언트의 시작과 끝 지점 설정
gradient.addColorStop(0, colorAry[2]); // 시작 색상
gradient.addColorStop(0.8, colorAry[3]); // 끝 색상
// 데이터 준비 (라인 차트)
const lineChartTrfData = {
type: 'line',
label: "평균",
data: lineChartGroupData[ACSR_ID].TRF_QNTY,
fill: true,
backgroundColor: gradient, // 라인 차트의 배경 색상
borderColor: colorAry[1],
};
// 데이터 준비 (막대 차트)
const barChartTrfData = {
type: 'bar',
label: "오늘",
data: barChartGroupData[ACSR_ID].TRF_QNTY, // barChartGroupData로 변경
backgroundColor: colorAry[0], // 막대 차트의 배경 색상
};
// Chart.js 차트 생성 및 표시
new Chart(ctx, {
data: {
datasets: [barChartTrfData,lineChartTrfData],
// labels: lineChartGroupData[ACSR_ID].labels
labels: barChartGroupData[ACSR_ID].labels, // barChartGroupData로 변경
},
options: {
plugins:{
legend : {
display : false,
// font: { size: 8 }
// }
},
datalabels: { display: false,},
},
responsive: true,
scales: {
y: {
beginAtZero: false,
//suggestedMin :800,
//suggestedMax: 1300,
ticks: {
font: { size: 10 },
}
},
x: {
ticks: {
font: { size: 8 },
//maxTicksLimit: 10 // 원하는 표시할 최대 라벨 개수로 변경
autoSkip:false, //라벨스킵 여부
maxRotation:60, //각도
}
}
},
}
,
tooltips:{showTooltips: false,}
}); //END new Chart
});
});
},
/*차트 생성 - 시간대별 접근로 교통량 15분 테이블 */
initChart: function(){
if(this.mainTrfByAcsr15mi != undefined) this.mainTrfByAcsr15mi.destroy();
this.mainTrfByAcsr15mi = makeMixedChart($('#mainTrfByAcsr15mi'), "", [])
//console.log(Object.entries(this.mainTrfByAcsr15mi))
if(this.mainPdstByAcsr != undefined) this.mainPdstByAcsr.destroy();
this.mainPdstByAcsr = makeMixedChart($('#mainPdstByAcsr'), "", [])
if(this.mainLosByAcsr != undefined) this.mainLosByAcsr.destroy();
this.mainLosByAcsr = makeMixedChart($('#mainLosByAcsr'), "", [])
},
/* 시간대별 접근로 교통량 : 15분 15mi : 진행중 */
getTrfByAcsr15mi: function(crsrdid, acsrid) {
comm.noAsyncAjax("/main/getTrfByAcsr15mi.json", {"CRSRD_ID":crsrdid}, function(data){
//console.log(JSON.stringify(data));
// [1] 데이터 : 오늘과 평균 데이터를 나눠서 bar차트, line차트로 나눠 담기.
const avgData = data["AVG"];
const listData = data["LIST"];
// [2] 평균 데이터
let lineChartGroupData = {};
avgData.forEach(function(item) {
if (!lineChartGroupData[item.ACSR_ID]) {
lineChartGroupData[item.ACSR_ID] = {
labels: [],
TRF_QNTY: [],
PDST_QNTY:[]
};
}
lineChartGroupData[item.ACSR_ID].labels.push((item.TOT_DT));
lineChartGroupData[item.ACSR_ID].TRF_QNTY.push(item.TRF_QNTY);
lineChartGroupData[item.ACSR_ID].PDST_QNTY.push(item.PDST_QNTY);
});
//console.log("lineChartGroupData ::: "+JSON.stringify(lineChartGroupData) );
// [3] 오늘 데이터
let barChartGroupData = {};
listData.forEach(function(item) {
if (!barChartGroupData[item.ACSR_ID]) {
barChartGroupData[item.ACSR_ID] = {
labels: [],
TRF_QNTY: [],
PDST_QNTY:[]
};
}
barChartGroupData[item.ACSR_ID].labels.push((item.TOT_DT).split(' ')[1].substring(0, 5));
barChartGroupData[item.ACSR_ID].TRF_QNTY.push(item.TRF_QNTY);
barChartGroupData[item.ACSR_ID].PDST_QNTY.push(item.PDST_QNTY);
});
//console.log("barChartGroupData ::: " + JSON.stringify(barChartGroupData));
mainMixedChart.generatorChart($('#mainTrfByAcsr15mi'), acsrid, lineChartGroupData, barChartGroupData);
});
},
generatorChart: function(ctxx, acsrid, lineChartGroupData, barChartGroupData ){
//console.log("barChartGroupData : "+JSON.stringify(barChartGroupData) );
// ---------------------------------------------------------------------
//console.log("lineChartGroupData : "+JSON.stringify(lineChartGroupData) );
const ctx = ctxx[0].getContext("2d");
const colorAry = ['rgb(171, 224, 218)', 'rgb(185, 216, 218)', 'rgb(138, 176, 176)', 'rgba(138, 176, 176, 0.1)'];
// 그라디언트 생성
const gradient = ctx.createLinearGradient(0, 0, 0, 400); // 그라디언트의 시작과 끝 지점 설정
gradient.addColorStop(0, colorAry[2]); // 시작 색상
gradient.addColorStop(0.8, colorAry[3]); // 끝 색상
//let lineChartTrfData = {};
//let barChartTrfData = {};
//let lineChartPDSTData = {};
//let barChartPDSTData = {};
//let labels = barChartGroupData['ACSR000001'].labels;
// ACSR 갯수대로 반복
//Object.keys(lineChartGroupData).forEach(function(ACSR_ID) {});
// ACSR_ID에 따른 데이터 가져오기
const lineChartData = lineChartGroupData[acsrid]; // 매개변수로 받은 ACSR_ID
const barChartData = barChartGroupData[acsrid]; // 매개변수로 받은 ACSR_ID
const labels = lineChartData.labels;
// 데이터 준비 (라인 차트)
const lineChartTrfData = {
type: 'line',
label: "평균",
//data: lineChartGroupData[ACSR_ID].TRF_QNTY,
data: lineChartData.TRF_QNTY,
fill: true,
backgroundColor: gradient,
borderColor: colorAry[1],
};
// 데이터 준비 (막대 차트)
const barChartTrfData = {
type: 'bar',
label: "오늘",
//data: barChartGroupData[ACSR_ID].TRF_QNTY,
data: barChartData.TRF_QNTY,
backgroundColor: colorAry[0],
};
// 데이터 준비 (라인 차트)
const lineChartPDSTData = {
type: 'line',
label: "평균",
//data: lineChartGroupData[ACSR_ID].PDST_QNTY,
data: lineChartData.PDST_QNTY,
fill: true,
backgroundColor: gradient,
borderColor: colorAry[1],
};
// 데이터 준비 (막대 차트)
const barChartPDSTData = {
type: 'bar',
label: "오늘",
//data: barChartGroupData[ACSR_ID].PDST_QNTY,
data: barChartData.PDST_QNTY,
backgroundColor: colorAry[0],
};
mainMixedChart.updateChart('mainPdstByAcsr', acsrid, barChartPDSTData, lineChartPDSTData, labels);
mainMixedChart.updateChart('mainTrfByAcsr15mi', acsrid, barChartTrfData, lineChartTrfData, labels);
}, //END generatorChart
updateChart:function(propertyNM, acsrid, barChartTrfData, lineChartTrfData, labels){
console.log('updateChart : ');
//console.log("updateChart acsrid : "+acsrid); // 2번호출 되는 이유는 당연히 위에서 2번 호출 하니까
//console.log("barChartTrfData : "+ JSON.stringify(barChartTrfData));
//console.log("lineChartTrfData : "+ JSON.stringify(lineChartTrfData));
const noData = {
id: 'noData',
afterDatasetsDraw :((chart, args, plugins) => {
const {ctx, data, chartArea : {top, bottom, left, right, width, height} } = chart;
ctx.save();
if(mainMixedChart[propertyNM].data.datasets[0].data.length === 0){
ctx.fillStyle = 'rgba(102,102,102, 0.8)';
ctx.fillRect(left, top, width, height);
ctx.font = 'bold 20px sans-serif';
ctx.fillStyle = 'black';
ctx.textAlign = 'center';
ctx.fillText('No Data Available', left+width/2, top+height/2)
}
}),
}
mainMixedChart[propertyNM].data = {datasets:[barChartTrfData, lineChartTrfData], labels:labels};
// STYLE
mainMixedChart[propertyNM].options.plugins.legend = {display: false };
mainMixedChart[propertyNM].options.plugins = {noData};
mainMixedChart[propertyNM].options.maxBarThickness = 20;
mainMixedChart[propertyNM].options.plugins.datalabels = {display: false };
mainMixedChart[propertyNM].options.scales = {
y: {beginAtZero: true, ticks: { font: { size: 10 } } },
x: { ticks: {font: { size: 8 },autoSkip:false,maxRotation:60,} },
y1:{display:false}};
mainMixedChart[propertyNM].tooltips = { showTooltips: false };
// console.log("-------------------------------------------");
// console.log(Object.entries(this.mainTrfByAcsr15mi))
// console.log("-------------------------------------------");
mainMixedChart[propertyNM].update();
},
getTrfByAcsr15mi_origin: function(crsrdid, acsrid) {
comm.noAsyncAjax("/main/getTrfByAcsr15mi_origin.json", {"CRSRD_ID":crsrdid}, function(data){
console.log("getTrfByAcsr15mi_origin.json :::::: -------- "+JSON.stringify(data));
if (data.length < 1 ) console.log('데이터 영'+data.length());
if (data.length < 1 ) console.log('데이터 영'+data.length);
// ACSR_ID 별로 데이터 묶음
let GroupData = {};
data.forEach(function(item) {
if (!GroupData[item.ACSR_ID]) {
GroupData[item.ACSR_ID] = {
labels: [],
TRF_QNTY: [],
WD_TRF_QNTY: [],
YD_TRF_QNTY: [],
PDST_QNTY:[],
WD_PDST_QNTY:[],
YD_PDST_QNTY:[],
LOS: [],
WD_LOS: [],
YD_LOS: [],
};
}
GroupData[item.ACSR_ID].labels.push((item.TOT_DT));
GroupData[item.ACSR_ID].TRF_QNTY.push(item.TRF_QNTY);
GroupData[item.ACSR_ID].WD_TRF_QNTY.push(item.WD_TRF_QNTY);
GroupData[item.ACSR_ID].YD_TRF_QNTY.push(item.YD_TRF_QNTY);
GroupData[item.ACSR_ID].PDST_QNTY.push(item.PDST_QNTY);
GroupData[item.ACSR_ID].WD_PDST_QNTY.push(item.WD_PDST_QNTY);
GroupData[item.ACSR_ID].YD_PDST_QNTY.push(item.YD_PDST_QNTY);
GroupData[item.ACSR_ID].LOS.push(item.LOS);
GroupData[item.ACSR_ID].WD_LOS.push(item.WD_LOS);
GroupData[item.ACSR_ID].YD_LOS.push(item.YD_LOS);
});
// ----------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------
const colorAry = ['rgb(171, 224, 218)', 'rgb(185, 216, 218)', 'rgb(138, 176, 176)', 'rgba(138, 176, 176, 0.1)'];
// 그라디언트 생성
const ctx = document.getElementById("mainTrfByAcsr15mi").getContext("2d");
//const ctx = mainMixedChart.mainTrfByAcsr15mi.ctx.getContext("2d");
const gradient = ctx.createLinearGradient(0, 0, 0, 400); // 그라디언트의 시작과 끝 지점 설정
gradient.addColorStop(0, colorAry[2]); // 시작 색상
gradient.addColorStop(0.8, colorAry[3]); // 끝 색상
// ----------------------------------------------------------------------------------
const ChartData = GroupData[acsrid]; // 매개변수로 받은 ACSR_ID
const labels = ChartData.labels;
console.log("ChartData.TRF_QNTY : "+JSON.stringify(ChartData.TRF_QNTY ));
console.log("labels : "+ labels);
console.log("labels jjjj : "+ JSON.stringify(labels));
// 교통량 TRF
const lineChartTrfData = { // WD 평균
type: 'line',
label: "평균",
data: ChartData.WD_TRF_QNTY,
fill: true,
backgroundColor: gradient,
borderColor: colorAry[1],
};
const barChartTrfData = {
type: 'bar',
label: "오늘",
data: ChartData.TRF_QNTY,
backgroundColor: colorAry[0],
borderRadius: 10,
};
// 보행자 PDST
const lineChartPDSTData = {
type: 'line',
label: "평균",
data: ChartData.WD_PDST_QNTY,
fill: true,
backgroundColor: gradient,
borderColor: colorAry[1],
};
const barChartPDSTData = {
type: 'bar',
label: "오늘",
data: ChartData.PDST_QNTY,
backgroundColor: colorAry[0],
borderRadius: 10,
};
// LOS
const lineChartLOSData = {
type: 'line',
label: "평균",
data: ChartData.WD_LOS,
fill: true,
backgroundColor: gradient,
borderColor: colorAry[1],
};
const barChartLOSData = {
type: 'bar',
label: "오늘",
data: ChartData.LOS,
backgroundColor: colorAry[0],
borderRadius: 10,
};
mainMixedChart.updateChart('mainTrfByAcsr15mi', acsrid, barChartTrfData, lineChartTrfData, labels);
mainMixedChart.updateChart('mainPdstByAcsr', acsrid, barChartPDSTData, lineChartPDSTData, labels);
mainMixedChart.updateChart('mainLosByAcsr', acsrid, barChartLOSData, lineChartLOSData, labels);
});
},
}// END mainMixedChart
728x90
300x250