본문 바로가기

javascript/Chartjs

Chart js MixedChart

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