Chart.js
Categories
- chart
- vue-chartjs
- vue-chart-3 - chart.js 3.x 지원.
- react-chartjs-2 - react 지원.
- chartjs-plugin-streaming
adapters
Plugins
- chartjs-plugin-datalabels - 차트 영역 안에 라벨 쓰기
Height Size
- (이슈) : react-chartjs 사이즈 조정하기
- javascript - React chart : prevent chart's canvas scaling with height and width - Stack Overflow
직계 부모 부모 태그(주로
겠지)의 높이(height)가 중요하다.
또한 비율 문제로 인해 강제로 이미지 크기가 줄어들 수 있다. 이 때`maintainAspectRatio: false` 를 사용하면 된다.
<div style={{height:'100px',width:'200px'}}>
<HorizontalBar data={data} options={chartOptions}/>
</div>
PS. 옵션 중 `responsive: false`를 사용하면 (부모 태그의 크기가 작다면) 화면에 짤릴 수 있다.
Responsive Charts
- [Responsive Charts | Chart.js](https://www.chartjs.org/docs/latest/configuration/responsive.html)
캔버스 크기 변경 시기를 감지하는 것은 캔버스 요소에서 직접 수행할 수 없습니다. Chart.js는 부모 컨테이너를 사용하여 캔버스 렌더링 및 디스플레이 크기를 업데이트합니다. 그러나 이 방법을 사용하려면 컨테이너가 상대적으로 배치(`position: relative;`)되고 차트 캔버스에만 전용(자식 element 가 canvas 만 존재)되어야 합니다. 그런 다음 컨테이너 크기에 대한 상대 값을 설정하여 응답성을 달성할 수 있습니다.
<div class="chart-container" style="position: relative; height:40vh; width:80vw">
<canvas id="chart"></canvas>
</div>
Bar chart
// Bar chart
new Chart(document.getElementById("bar-chart"), {
type: 'bar',
data: {
labels: ["Africa", "Asia", "Europe", "Latin America", "North America"],
datasets: [
{
label: "Population (millions)",
backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
data: [2478,5267,734,784,433]
}
]
},
options: {
legend: { display: false },
title: {
display: true,
text: 'Predicted world population (millions) in 2050'
}
}
});
Line chart
new Chart(document.getElementById("line-chart"), {
type: 'line',
data: {
labels: [1500,1600,1700,1750,1800,1850,1900,1950,1999,2050],
datasets: [{
data: [86,114,106,106,107,111,133,221,783,2478],
label: "Africa",
borderColor: "#3e95cd",
fill: false
}, {
data: [282,350,411,502,635,809,947,1402,3700,5267],
label: "Asia",
borderColor: "#8e5ea2",
fill: false
}, {
data: [168,170,178,190,203,276,408,547,675,734],
label: "Europe",
borderColor: "#3cba9f",
fill: false
}, {
data: [40,20,10,16,24,38,74,167,508,784],
label: "Latin America",
borderColor: "#e8c3b9",
fill: false
}, {
data: [6,3,2,2,7,26,82,172,312,433],
label: "North America",
borderColor: "#c45850",
fill: false
}
]
},
options: {
title: {
display: true,
text: 'World population per region (in millions)'
}
}
});
Dark Theme
- [Chart.js Dark Theme - JSFiddle - Code Playground](https://jsfiddle.net/UXMike/h2yoLgxq/22/)
$(document).ready( function() {
// Javascript method's body can be found in assets/js/demos.js
var gradientChartOptionsConfigurationWithTooltipPurple = {
maintainAspectRatio: false,
legend: {
display: false
},
tooltips: {
backgroundColor: '#f5f5f5',
titleFontColor: '#333',
bodyFontColor: '#666',
bodySpacing: 4,
xPadding: 12,
mode: "nearest",
intersect: 0,
position: "nearest"
},
responsive: true,
scales: {
yAxes: [{
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: 'rgba(29,140,248,0.0)',
zeroLineColor: "transparent",
},
ticks: {
suggestedMin: 60,
suggestedMax: 125,
padding: 20,
fontColor: "#9a9a9a"
}
}],
xAxes: [{
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: 'rgba(225,78,202,0.1)',
zeroLineColor: "transparent",
},
ticks: {
padding: 20,
fontColor: "#9a9a9a"
}
}]
}
};
var ctx = document.getElementById("chartLinePurple").getContext("2d");
var gradientStroke = ctx.createLinearGradient(0, 230, 0, 50);
gradientStroke.addColorStop(1, 'rgba(72,72,176,0.2)');
gradientStroke.addColorStop(0.2, 'rgba(72,72,176,0.0)');
gradientStroke.addColorStop(0, 'rgba(119,52,169,0)'); //purple colors
var data = {
labels: ['JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'],
datasets: [{
label: "Data",
fill: true,
backgroundColor: gradientStroke,
borderColor: '#d048b6',
borderWidth: 2,
borderDash: [],
borderDashOffset: 0.0,
pointBackgroundColor: '#d048b6',
pointBorderColor: 'rgba(255,255,255,0)',
pointHoverBackgroundColor: '#d048b6',
pointBorderWidth: 20,
pointHoverRadius: 4,
pointHoverBorderWidth: 15,
pointRadius: 4,
data: [80, 100, 70, 80, 120, 80],
}]
};
var myChart = new Chart(ctx, {
type: 'line',
data: data,
options: gradientChartOptionsConfigurationWithTooltipPurple
});
var config = {
type: 'line',
data: {
labels: chart_labels,
datasets: [{
label: "My First dataset",
fill: true,
backgroundColor: gradientStroke,
borderColor: '#d346b1',
borderWidth: 2,
borderDash: [],
borderDashOffset: 0.0,
pointBackgroundColor: '#d346b1',
pointBorderColor: 'rgba(255,255,255,0)',
pointHoverBackgroundColor: '#d346b1',
pointBorderWidth: 20,
pointHoverRadius: 4,
pointHoverBorderWidth: 15,
pointRadius: 4,
data: chart_data,
}]
},
options: gradientChartOptionsConfigurationWithTooltipPurple
};
new Chart(ctx, config);
});
Pie chart
new Chart(document.getElementById("pie-chart"), {
type: 'pie',
data: {
labels: ["Africa", "Asia", "Europe", "Latin America", "North America"],
datasets: [{
label: "Population (millions)",
backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
data: [2478,5267,734,784,433]
}]
},
options: {
title: {
display: true,
text: 'Predicted world population (millions) in 2050'
}
}
});
Radar chart
new Chart(document.getElementById("radar-chart"), {
type: 'radar',
data: {
labels: ["Africa", "Asia", "Europe", "Latin America", "North America"],
datasets: [
{
label: "1950",
fill: true,
backgroundColor: "rgba(179,181,198,0.2)",
borderColor: "rgba(179,181,198,1)",
pointBorderColor: "#fff",
pointBackgroundColor: "rgba(179,181,198,1)",
data: [8.77,55.61,21.69,6.62,6.82]
}, {
label: "2050",
fill: true,
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
pointBorderColor: "#fff",
pointBackgroundColor: "rgba(255,99,132,1)",
pointBorderColor: "#fff",
data: [25.48,54.16,7.61,8.06,4.45]
}
]
},
options: {
title: {
display: true,
text: 'Distribution in % of world population'
}
}
});
Polar chart
new Chart(document.getElementById("polar-chart"), {
type: 'polarArea',
data: {
labels: ["Africa", "Asia", "Europe", "Latin America", "North America"],
datasets: [
{
label: "Population (millions)",
backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
data: [2478,5267,734,784,433]
}
]
},
options: {
title: {
display: true,
text: 'Predicted world population (millions) in 2050'
}
}
});
Doughnut chart
new Chart(document.getElementById("doughnut-chart"), {
type: 'doughnut',
data: {
labels: ["Africa", "Asia", "Europe", "Latin America", "North America"],
datasets: [
{
label: "Population (millions)",
backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
data: [2478,5267,734,784,433]
}
]
},
options: {
title: {
display: true,
text: 'Predicted world population (millions) in 2050'
}
}
});
바깥 원 크기 변경
- [Doughnut and Pie Charts | Chart.js](https://www.chartjs.org/docs/latest/charts/doughnut.html#config-options)
`cutout` 값을 조정하면 된다. 의미는 중간에서 잘린 차트 부분. 문자열이고 '%'로 끝나는 경우 차트 반경의 백분율입니다. 숫자는 픽셀로 간주됩니다.
내부 Border 제거
- [javascript - How to remove the inside-border from a single-element doughnut chart? Chart.js - Stack Overflow](https://stackoverflow.com/questions/47547837/how-to-remove-the-inside-border-from-a-single-element-doughnut-chart-chart-js)
`datasets`의 각 데이터셋에 `borderWidth`값을 0으로 바꾸면 된다.
Horizontal bar chart
new Chart(document.getElementById("bar-chart-horizontal"), {
type: 'horizontalBar',
data: {
labels: ["Africa", "Asia", "Europe", "Latin America", "North America"],
datasets: [
{
label: "Population (millions)",
backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
data: [2478,5267,734,784,433]
}
]
},
options: {
legend: { display: false },
title: {
display: true,
text: 'Predicted world population (millions) in 2050'
}
}
});
Grouped bar chart
new Chart(document.getElementById("bar-chart-grouped"), {
type: 'bar',
data: {
labels: ["1900", "1950", "1999", "2050"],
datasets: [
{
label: "Africa",
backgroundColor: "#3e95cd",
data: [133,221,783,2478]
}, {
label: "Europe",
backgroundColor: "#8e5ea2",
data: [408,547,675,734]
}
]
},
options: {
title: {
display: true,
text: 'Population growth (millions)'
}
}
});
Mixed chart
new Chart(document.getElementById("mixed-chart"), {
type: 'bar',
data: {
labels: ["1900", "1950", "1999", "2050"],
datasets: [{
label: "Europe",
type: "line",
borderColor: "#8e5ea2",
data: [408,547,675,734],
fill: false
}, {
label: "Africa",
type: "line",
borderColor: "#3e95cd",
data: [133,221,783,2478],
fill: false
}, {
label: "Europe",
type: "bar",
backgroundColor: "rgba(0,0,0,0.2)",
data: [408,547,675,734],
}, {
label: "Africa",
type: "bar",
backgroundColor: "rgba(0,0,0,0.2)",
backgroundColorHover: "#3e95cd",
data: [133,221,783,2478]
}
]
},
options: {
title: {
display: true,
text: 'Population growth (millions): Europe & Africa'
},
legend: { display: false }
}
});
Bubble chart
new Chart(document.getElementById("bubble-chart"), {
type: 'bubble',
data: {
labels: "Africa",
datasets: [
{
label: ["China"],
backgroundColor: "rgba(255,221,50,0.2)",
borderColor: "rgba(255,221,50,1)",
data: [{
x: 21269017,
y: 5.245,
r: 15
}]
}, {
label: ["Denmark"],
backgroundColor: "rgba(60,186,159,0.2)",
borderColor: "rgba(60,186,159,1)",
data: [{
x: 258702,
y: 7.526,
r: 10
}]
}, {
label: ["Germany"],
backgroundColor: "rgba(0,0,0,0.2)",
borderColor: "#000",
data: [{
x: 3979083,
y: 6.994,
r: 15
}]
}, {
label: ["Japan"],
backgroundColor: "rgba(193,46,12,0.2)",
borderColor: "rgba(193,46,12,1)",
data: [{
x: 4931877,
y: 5.921,
r: 15
}]
}
]
},
options: {
title: {
display: true,
text: 'Predicted world population (millions) in 2050'
}, scales: {
yAxes: [{
scaleLabel: {
display: true,
labelString: "Happiness"
}
}],
xAxes: [{
scaleLabel: {
display: true,
labelString: "GDP (PPP)"
}
}]
}
}
});
Doughnut 차트 중앙에 글씨 넣기
- [chart.js 2.1 - JSFiddle - Code Playground](https://jsfiddle.net/kdvuxbtj/)
Chart.pluginService.register({
beforeDraw: function(chart) {
if (chart.config.options.elements.center) {
// Get ctx from string
var ctx = chart.chart.ctx;
// Get options from the center object in options
var centerConfig = chart.config.options.elements.center;
var fontStyle = centerConfig.fontStyle || 'Arial';
var txt = centerConfig.text;
var color = centerConfig.color || '#000';
var maxFontSize = centerConfig.maxFontSize || 75;
var sidePadding = centerConfig.sidePadding || 20;
var sidePaddingCalculated = (sidePadding / 100) * (chart.innerRadius * 2)
// Start with a base font of 30px
ctx.font = "30px " + fontStyle;
// Get the width of the string and also the width of the element minus 10 to give it 5px side padding
var stringWidth = ctx.measureText(txt).width;
var elementWidth = (chart.innerRadius * 2) - sidePaddingCalculated;
// Find out how much the font can grow in width.
var widthRatio = elementWidth / stringWidth;
var newFontSize = Math.floor(30 * widthRatio);
var elementHeight = (chart.innerRadius * 2);
// Pick a new font size so it will not be larger than the height of label.
var fontSizeToUse = Math.min(newFontSize, elementHeight, maxFontSize);
var minFontSize = centerConfig.minFontSize;
var lineHeight = centerConfig.lineHeight || 25;
var wrapText = false;
if (minFontSize === undefined) {
minFontSize = 20;
}
if (minFontSize && fontSizeToUse < minFontSize) {
fontSizeToUse = minFontSize;
wrapText = true;
}
// Set font settings to draw it correctly.
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var centerX = ((chart.chartArea.left + chart.chartArea.right) / 2);
var centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2);
ctx.font = fontSizeToUse + "px " + fontStyle;
ctx.fillStyle = color;
if (!wrapText) {
ctx.fillText(txt, centerX, centerY);
return;
}
var words = txt.split(' ');
var line = '';
var lines = [];
// Break words up into multiple lines if necessary
for (var n = 0; n < words.length; n++) {
var testLine = line + words[n] + ' ';
var metrics = ctx.measureText(testLine);
var testWidth = metrics.width;
if (testWidth > elementWidth && n > 0) {
lines.push(line);
line = words[n] + ' ';
} else {
line = testLine;
}
}
// Move the center up depending on line height and number of lines
centerY -= (lines.length / 2) * lineHeight;
for (var n = 0; n < lines.length; n++) {
ctx.fillText(lines[n], centerX, centerY);
centerY += lineHeight;
}
//Draw text in center
ctx.fillText(line, centerX, centerY);
}
}
});
var config = {
type: 'doughnut',
data: {
labels: [
"Red",
"Green",
"Yellow"
],
datasets: [{
data: [300, 50, 100],
backgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
]
}]
},
options: {
elements: {
center: {
text: 'Red is 2/3 of the total numbers',
color: '#FF6384', // Default is #000000
fontStyle: 'Arial', // Default is Arial
sidePadding: 20, // Default is 20 (as a percentage)
minFontSize: 25, // Default is 20 (in px), set to false and text will not wrap.
lineHeight: 25 // Default is 25 (in px), used for when text wraps
}
}
}
};
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, config);
또는 [CSS:position#relative](CSS%3Aposition.md#relative) 을 사용하면 된다.
See also
- [node](Node.md)
- [Visualizations](Visualizations.md)
- [d3.js](D3.js.md)
- [three.js](Three.js.md)
- [Chart.js](Chart.js.md)
- [Paper.js](Paper.js.md)
- [Fabric.js](Fabric.js.md)
- [ECharts](ECharts.md)
- [Two.js](Two.js.md)
- [Google charts](Google_charts.md)
- [ApexCharts](ApexCharts.md)
Favorite site
- [Build a Realtime Chart with Vue.js](https://medium.com/js-dojo/build-a-realtime-chart-with-vue-js-d7e2e25a5e21)
- [awesome chart.js](https://github.com/chartjs/awesome)
- [10 Chart.js example charts to get you started](https://tobiasahlin.com/blog/chartjs-charts-to-get-you-started/)