• HTML
  • JS
  • J볃교

Chart.js 를 활용하여 그래프 모양 다르게 나타내기

2019-03-20 256

설명

  • 카카오톡 링크

반응형은 적용되지만, x축 타이틀은 적응형으로 반영 되었습니다~!
※9월,10월,11월,12월은 /js/utils.js 안에 있습니다~!
chart.js 다운받기
utils.js 다운받기

소스실행 현황

소스보기( X표시가 나타나면 무시하셔도 됩니다! )

	<script src="/js/chart.js"></script>
	<script src="/js/utils.js"></script>
	
	<style>
		.content {position:relative;}
		.content span {display:inline-block; width:150px; position:absolute; top:110px; left:85px}
		.content .wrapper {display:inline-block; width:100%; box-sizing:border-box; padding-left:150px}
		#chart-0 {height:300px}

		@media screen and (max-width:950px) {
			#chart-0 {height:250px}
		}

		.chartjs-tooltip { /* 기본적인 모양 */
			opacity: 0;
			position: absolute;
			background:rgba(0, 0, 0, .7);
			color: white;
			border-radius: 3px;
			pointer-events: none;
			-webkit-transform: translate(-50%, 0);
			transform: translate(-50%, 0);
			padding: 4px 10px 6px;
			font-size:21px;
			font-weight:300; 
			letter-spacing:-0.025em;
			color:#fff;
			margin-top:25px;
			border-radius:5px;
			box-shadow:3px 0 3px rgba(0,0,0,0.3)
		}

		.chartjs-tooltip2 { /* 미리띠워져 있는 모양 */
			position: absolute;
			background:rgba(0, 0, 0, .7);
			color: white;
			border-radius: 3px;
			pointer-events: none;
			-webkit-transform: translate(-50%, 0);
			transform: translate(-50%, 0);
			padding: 4px 10px 6px;
			font-size:21px;
			font-weight:300; 
			letter-spacing:-0.025em;
			color:#fff;
			margin-top:25px;
			border-radius:5px;
			box-shadow:3px 0 3px rgba(0,0,0,0.3)
		}

		.chartjs-tooltip.on {
			margin-top:-48px;
		}

		.chartjs-tooltip2.on {
			margin-top:-50px;
		}

		.chartjs-tooltip:after {content:""; position:absolute; left:50%; margin-left:-9px; top:-11px; width:18px; height:12px; background:url('/img/chart_bg.png') no-repeat center center; background-size:cover}
		.chartjs-tooltip2:after {content:""; position:absolute; left:50%; margin-left:-9px; top:-11px; width:18px; height:12px; background:url('/img/chart_bg.png') no-repeat center center; background-size:cover}
		.chartjs-tooltip.on:after {content:""; position:absolute; left:50%; margin-left:-8px; top:27px; width:18px; height:12px; background:url('/img/chart_bg.png') no-repeat center center; background-size:cover;transform: rotate(180deg);	}
		.chartjs-tooltip2.on:after {content:""; position:absolute; left:50%; margin-left:-8px; top:27px; width:18px; height:12px; background:url('/img/chart_bg.png') no-repeat center center; background-size:cover;transform: rotate(180deg);	}

		.chartjs-tooltip-key {
			display: inline-block;
			width: 10px;
			height: 10px;
		}
	</style>
	<div class="content">
		<div id="canvas-holder1">
			<canvas id="chart-0"></canvas>
			<div class="chartjs-tooltip" id="tooltip-0"></div>
			<div class="chartjs-tooltip" id="tooltip-1"></div>

			<div class="chartjs-tooltip2" id="wow0_1">29.65%</div>
			<div class="chartjs-tooltip2 on" id="wow0_3">14.71%</div>
			<div class="chartjs-tooltip2 on" id="wow1_3">3.91%</div>
		</div>
	</div>

	<script>
		var customTooltips = function(tooltip) {
			$(this._chart.canvas).css('cursor', 'pointer');

			var positionY = this._chart.canvas.offsetTop;
			var positionX = this._chart.canvas.offsetLeft;

			$('.chartjs-tooltip').css({
				opacity: 0,
			});

			if (!tooltip || !tooltip.opacity) {
				return;
			}

			if (tooltip.dataPoints.length > 0) {
				tooltip.dataPoints.forEach(function(dataPoint) {
					if(dataPoint.index != 1 && dataPoint.index != 3) { 
						var content = [dataPoint.yLabel].join(': ') + "%";
						var $tooltip = $('#tooltip-' + dataPoint.datasetIndex);
						if(dataPoint.index > 1) {
							$tooltip.addClass("on");
						} else {
							$tooltip.removeClass("on");
						}

						$tooltip.html(content);
						$tooltip.css({
							opacity: 1,
							top: positionY + dataPoint.y + 'px',
							left: positionX + dataPoint.x + 'px',
						});
					} else {
						if(dataPoint.datasetIndex == 1 && dataPoint.index == 1) { // 2번째 줄이면서, 2번째 요소를 선택
							var content = [dataPoint.yLabel].join(': ') + "%";
							var $tooltip = $('#tooltip-' + dataPoint.datasetIndex);
							if(dataPoint.index > 1) {
								$tooltip.addClass("on");
							} else {
								$tooltip.removeClass("on");
							}

							$tooltip.html(content);
							$tooltip.css({
								opacity: 1,
								top: positionY + dataPoint.y + 'px',
								left: positionX + dataPoint.x + 'px',
							});
						}
					}
				});
			}
		};
		var fontsize;
		if(window.innerWidth < 950) {
			fontsize = 14
		} else {
			fontsize = 24
		}

		var presets = window.chartColors;
		var utils = Samples.utils;
		var inputs = {
			min: -100,
			max: 100,
			count: 4,
			decimals: 2,
			continuity: 1
		};

		function generateData(config) {
			return utils.numbers(Chart.helpers.merge(inputs, config || {}));
		}

		function generateLabels(config) {
			return utils.months(Chart.helpers.merge({
				count: inputs.count,
				section: 3
			}, config || {}));
		}

		var options = {
			maintainAspectRatio: false,
			spanGaps: false,
			elements: {
				line: {
					tension: 0.000001
				}
			},
			plugins: {
				filler: {
					propagate: false
				}
			},
			scales: {
				xAxes: [{
					ticks: {
						autoSkip: false,
						maxRotation: 0
					}
				}]
			}
		};

		[false, 'origin', 'start', 'end'].forEach(function(boundary, index) {

			// reset the random seed to generate the same data for all charts
			utils.srand(8);

			new Chart('chart-' + index, {
				type: 'line',
				data: {
					labels: generateLabels(),
					datasets: [{
						backgroundColor: '#fff', // 점 배경
						borderWidth: 2, // 선굵기
						borderColor: '#f2849e', //선색상
						pointRadius: 7, // 점 둥글기
						pointHoverRadius: 7,//  마우스 올렸을때 점 둥글기
						pointHoverBackgroundColor: '#f2849e', // 마우스 올렸을때 점 색상
						data: [
							'14','29.65','13','14.71' // 데이터
							],
						label: '',
						fill: boundary // 색상
					}, {
						backgroundColor: '#effaff',
						borderWidth: 2,
						borderColor: '#404040',
						pointRadius: 7,
						pointHoverRadius: 7,
						pointHoverBackgroundColor: '#404040',
						data: [
							'6','5','4','3.91'
							],
						label: '',
						fill: boundary
					}]
				},
				options: Chart.helpers.merge(options, {
					title: {
						display: true
					},
					legend: {
						display: false
					},
					scales: {
						xAxes: [{
							ticks: {
								fontFamily: "Spoqa Han Sans",
								fontSize: fontsize
							},
							gridLines: {
								drawBorder: false,
								drawOnChartArea: false
							}
						}],
						yAxes: [{
							display:false,
							gridLines: {
								drawOnChartArea: false,
									
							}
						}]
					},
					tooltips: {
						enabled: false,
						mode: 'index',
						intersect: true,
						custom: customTooltips
					}
					
				})

			});
		});

		Chart.plugins.register({
			afterDatasetsDraw: function(chart) {
				var ctx = chart.ctx;

				chart.data.datasets.forEach(function(dataset, i) {
					var meta = chart.getDatasetMeta(i);
					if (!meta.hidden) {
						meta.data.forEach(function(element, index) {
							if(element._datasetIndex == 0) {
								if(element._index != 0 && element._index != 2) {
									// Draw the text in black, with the specified font
									

									// Just naively convert to string for now
									var dataString = dataset.data[index].toString() + "%";

									// Make sure alignment settings are correct
									ctx.textAlign = 'center';
									ctx.textBaseline = 'middle';

									var padding = 5;
									var position = element.tooltipPosition();
									//ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
									$("#wow"+element._datasetIndex+"_"+element._index).css({left:position.x, top:position.y});
								}
							} else {
								if(element._index == 3) {
									// Draw the text in black, with the specified font

									// Just naively convert to string for now
									var dataString = dataset.data[index].toString() + "%";

									// Make sure alignment settings are correct
									ctx.textAlign = 'center';
									ctx.textBaseline = 'middle';

									var padding = 5;
									var position = element.tooltipPosition();
									//ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
									$("#wow"+element._datasetIndex+"_"+element._index).css({left:position.x, top:position.y});
								}
							}
						});
					}
				});
			}
		});

		
	</script>