Chart js. How to change font styles for "labels" array? - javascript

I got a chart from Chart JS library.
Screenshot
var ctx = document.getElementById("myChart");
var data = {
labels: ["HTML", "CSS", "JavaScript", "jQuery", "Bootstrap", "Gulp", "PHP", 'SQL', 'Git'],
datasets: [
{
defaultFontColor: 'red',
backgroundColor: "rgba(0,255,255,.4)",
borderColor: "rgba(0,255,255,.4)",
pointBackgroundColor: "red",
pointBorderColor: "#fff",
lineTension: 0,
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(179,181,198,1)",
data: [95, 99, 60, 91, 36, 95, 40, 95, 95]
}
]
};
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: data,
options: {
responsive: true,
scale: {
reverse: false,
ticks: {
// defaultFontSize: true
}
}
}
});
I need to change font styles for underlined labels. I've dug over documentation and i tried all what i could. Even global font settings didn't change label styles, though it worked for the rest of other text. Have you met such a problem? Thanks.

It's well hidden, but you can find this under "Point Label Options"
http://www.chartjs.org/docs/#scales-radial-linear-scale
here is a example:
https://jsfiddle.net/qvrt01jp/1/
options: {
scale: {
pointLabels :{
fontStyle: "bold",
}
}
}
global should also work if set it like this:
Chart.defaults.global.defaultFontStyle = 'italic'

To give an update for v3.5.1:
Like this for font weights:
Chart.defaults.font.weight = '600';
Or if you want to do it inside the options object:
options: {
plugins: {
legend: {
labels: {
font: {
style: 'italic',
weight: '600',
}
}
}
}
}
Documentation with more info: https://www.chartjs.org/docs/latest/general/fonts.html

Related

How to add a title in Doughnut chart chart.js React

I want to add a Title for the Doughnut chart in my React app but for some reason it doesn't work. I have this code:
const chartData = {
labels: [],
datasets: [{
data: [],
backgroundColor: [
Colors.primary,
Colors.secondary,
Colors.danger,
Colors.warning
],
hoverBackgroundColor: [
'rgb(143, 0, 180, 0.3)',
'rgb(0, 196, 204, 0.3)',
'rgb(206, 0, 0, 0.3)',
'rgb(255, 179, 0, 0.3)'
],
hoverOffset: 10
}]
};
const options = {
responsive: true,
legend: {
display: false,
position: 'right',
},
title: {
display: true,
fontSize: 20,
text: 'Tickets'
}
}
<Doughnut
data = { chartData }
options = { options }
/>
What could have gone wrong here? I also want to place the labels on the right side of the chart, but it doesn't work as well. Below is the output.
Since Chart.js version 3 title, subtitle, legend and tooltip are plugins and their options must be defined in plugins node.
As far as I have seen, react-chartjs-2 is working with Chartjs version >= 3.
const options = {
responsive: true,
plugins: {
legend: {
display: false,
position: 'right',
},
title: {
display: true,
fontSize: 20, // <--- this is not a managed option since CHART.JS 3
text: 'Tickets'
}
}
}

chart.js - horizontalBar stacked chart with xaxis as dates

I am looking to create a bar chart but have had a hell of a time trying to find what I need through chart.js 2.1
Goal is to have a chart that looks like this:
sample image
So far I have been unsuccessful getting the xAxis to reflect dates.
Here's the story:
yAxis are vendor groups that have stacking due dates (the dates may/may not match up with another vendor group). Each stack has a numeric value as well, but this does not affect the layout of the chart, just an overlay of data.
xAxis are all the due dates, starting with the current date and moving on.
Any assistance or jfiddle examples would be EXTREMELY helpful!
Here's what I have today: https://jsfiddle.net/npk3xdb0/
HTML:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment#latest/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.min.js"></script>
<canvas id="bar-chart-horizontal" width="200" height="50"></canvas>
JAVASCRIPT:
new Chart(document.getElementById("bar-chart-horizontal"), {
type: "horizontalBar",
data: {
labels: ['V1','V2','V3'],
datasets: [{ data: [50, 60, 75], backgroundColor: "#8C453E"},{ data: [50, 70, 85], backgroundColor: "#684796"},{ data: [50, 53, 111], backgroundColor: "#427780"},{ data: [19, , ], backgroundColor: "#599647"}]
},
options: {
tooltips: { enabled: false },
hover :{ animationDuration:0 },
scales: {
xAxes: [{
ticks: { beginAtZero:true, fontFamily: "'Open Sans Bold', sans-serif", fontSize:11 },
scaleLabel:{ display:false },
gridLines: { },
stacked: true
}],
yAxes: [{
gridLines: { display:false, color: "#fff", zeroLineColor: "#fff", zeroLineWidth: 0 },
ticks: { fontFamily: "'Open Sans Bold', sans-serif", fontSize:11 },
stacked: true
}]
},
legend:{ display:false },
animation: {
onComplete: function () {
var chartInstance = this.chart;
var ctx = chartInstance.ctx;
ctx.textAlign = "right";
ctx.font = "9px Open Sans";
ctx.fillStyle = "#fff";
Chart.helpers.each(this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
Chart.helpers.each(meta.data.forEach(function (bar, index) {
data = dataset.data[index];
//if(i==0){
// ctx.fillText(data, 20, bar._model.y+4);
//} else {
ctx.fillText(data, bar._model.x-3, bar._model.y+4);
//}
}),this)
}),this);
}
},
pointLabelFontFamily : "Quadon Extra Bold",
scaleFontFamily : "Quadon Extra Bold",
}
});

How to maintain chartjs / ng2-charts gradient on window resize?

I had applied some gradient rule to my chartjs chart. And it looks great as you can see on the below
However, when the browser window is resized (i.e. width of window is smaller), the gradient is ruined (bottom blue colors disappeared). Screenshot:
I want to maintain the graph's gradient with all values and fit the different widths (responsive). Is there any way to do that? Here is what I had tried but didn't work:
.TS File
ngAfterViewInit() {
const ctx = (<HTMLCanvasElement>this.myChart.nativeElement).getContext('2d');
const purple_orange_gradient = ctx.createLinearGradient(0, 200, 0, 20);
purple_orange_gradient.addColorStop(0.1, "#000279");
purple_orange_gradient.addColorStop(0.2, "#0000F2");
purple_orange_gradient.addColorStop(0.3, "#0362FD");
purple_orange_gradient.addColorStop(0.4, "#04D3FD");
purple_orange_gradient.addColorStop(0.5, "#45FFB7");
purple_orange_gradient.addColorStop(0.6, "#B7FF46");
purple_orange_gradient.addColorStop(0.7, "#FFD401");
purple_orange_gradient.addColorStop(0.8, "#FE6500");
purple_orange_gradient.addColorStop(0.9, "#F30004");
purple_orange_gradient.addColorStop(1, "#7E0100");
const bar_chart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: []=this.histogramLabels.reverse(),
datasets: [{
borderColor: purple_orange_gradient,
pointBorderColor: purple_orange_gradient,
pointBackgroundColor: purple_orange_gradient,
pointHoverBackgroundColor: purple_orange_gradient,
pointHoverBorderColor: purple_orange_gradient,
pointBorderWidth: 10,
pointHoverRadius: 10,
pointHoverBorderWidth: 1,
pointRadius: 3,
fill: true,
backgroundColor: purple_orange_gradient,
borderWidth: 4,
data: []=this.histogramGraphData
}]
},
options: {
legend: {
display:false,
position: "bottom"
},
scales: {
yAxes: [{
ticks: {
display: false,
fontColor: "rgba(0,0,0,0.5)",
fontStyle: "bold",
beginAtZero: true,
maxTicksLimit: 1,
padding: 20,
},
gridLines: {
drawTicks: false,
display: false
}
}],
xAxes: [{
gridLines: {
zeroLineColor: "transparent",
},
ticks: {
padding: 20,
beginAtZero: true,
fontColor: "rgba(0,0,0,0.5)",
fontStyle: "bold"
}
}]
}
}
}
)
}
.HTML
<div class="row my-2">
<div class="col-md-6">
<canvas id=”myChart” #myChart height="130"></canvas>
</div>
</div>
HTML Canvas' createLinearGradient() depends on the y axis coordinates that you pass in as argument. You had passed in a static 200 every time (i.e. ctx.createLinearGradient(0, 200, 0, 20);).
That's why the gradient's steps remains the same everytime. For the gradient to update, you have to recalculate the height of the <canvas> element on window resize and pass it in to createLinearGradient() again.
You can accomplish this by:
Separating the block where you create the gradient into a separate function. eleHeight retrieves the height of the canvas element.
generateGradient(){
let eleHeight = this.myChart.nativeElement.offsetHeight;
// console.log(eleHeight)
let purple_orange_gradient: CanvasGradient = this.myChart.nativeElement.getContext('2d').createLinearGradient(0, eleHeight, 0, 20);
purple_orange_gradient.addColorStop(0.1, "#000279");
purple_orange_gradient.addColorStop(0.2, "#0000F2");
purple_orange_gradient.addColorStop(0.3, "#0362FD");
purple_orange_gradient.addColorStop(0.4, "#04D3FD");
purple_orange_gradient.addColorStop(0.5, "#45FFB7");
purple_orange_gradient.addColorStop(0.6, "#B7FF46");
purple_orange_gradient.addColorStop(0.7, "#FFD401");
purple_orange_gradient.addColorStop(0.8, "#FE6500");
purple_orange_gradient.addColorStop(0.9, "#F30004");
purple_orange_gradient.addColorStop(1, "#7E0100");
return purple_orange_gradient;
}
Add a onresize event handler to your containing <div> and generate the gradient again. You also need to programatically update the chart every time you make a change to re-render it.
<div style="display: block; max-height: 100%" (window:resize)="onResize($event)" >
...
</div>
onResize(event?){
// console.log("onResize");
this.barChartData.forEach((d, i) => {
d.backgroundColor = this.generateGradient();
})
this.chart.chart.update(); //update the chart to re-render it
}
Update the barchartData's properties (that uses gradient) in ngAfterViewInit. We need to do this here because we only want the height of the <canvas> element with data populated. Without data populated, the element is much smaller.
ngAfterViewInit(){
this.barChartData.forEach((d, i) => {
d.backgroundColor = this.generateGradient();
});
this.chart.chart.update(); //update the chart to re-render it
}
Have a look at this Stackblitz example⚡⚡ I have created.
You have to change the gradient whenever your canvas is resizing. Took me a while to figure out a good structure to minimize lines of code and optimize performance. This is the best I could achieve.
There are exeptions when the chart.js onResize() fires though but I couldn't solve this issue completly bulletproof. But for simple resizes it should work.
Complete code (same code in JSBin with live preview):
let sData = {}
sData.labels = []
sData.data = []
const count = 50
for (let x = 0; x < count; x++) {
sData.data.push(Math.floor(Math.random()*100))
sData.labels.push(x)
}
const canvas = document.getElementById('chart')
const ctx = canvas.getContext("2d")
let purple_orange_gradient
function updateGradient() {
let bottom = bar_chart.chartArea.bottom
let top = bar_chart.chartArea.top
purple_orange_gradient = ctx.createLinearGradient(0, bottom+top, 0, top)
purple_orange_gradient.addColorStop(0.1, "#000279")
purple_orange_gradient.addColorStop(0.2, "#0000F2")
purple_orange_gradient.addColorStop(0.3, "#0362FD")
purple_orange_gradient.addColorStop(0.4, "#04D3FD")
purple_orange_gradient.addColorStop(0.5, "#45FFB7")
purple_orange_gradient.addColorStop(0.6, "#B7FF46")
purple_orange_gradient.addColorStop(0.7, "#FFD401")
purple_orange_gradient.addColorStop(0.8, "#FE6500")
purple_orange_gradient.addColorStop(0.9, "#F30004")
purple_orange_gradient.addColorStop(1.0, "#7E0100")
return purple_orange_gradient
}
const bar_chart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: sData.labels,
datasets: [{
borderColor: purple_orange_gradient,
pointBorderColor: purple_orange_gradient,
pointBackgroundColor: purple_orange_gradient,
pointHoverBackgroundColor: purple_orange_gradient,
pointHoverBorderColor: purple_orange_gradient,
pointBorderWidth: 10,
pointHoverRadius: 10,
pointHoverBorderWidth: 1,
pointRadius: 3,
fill: true,
backgroundColor: purple_orange_gradient,
borderWidth: 4,
data: sData.data
}]
},
options: {
legend: {
display: false,
position: "bottom"
},
scales: {
yAxes: [{
ticks: {
display: false,
fontColor: "rgba(0,0,0,0.5)",
fontStyle: "bold",
beginAtZero: true,
maxTicksLimit: 1,
padding: 20,
},
gridLines: {
drawTicks: false,
display: false
}
}],
xAxes: [{
gridLines: {
zeroLineColor: "transparent",
},
ticks: {
padding: 20,
beginAtZero: true,
fontColor: "rgba(0,0,0,0.5)",
fontStyle: "bold"
}
}]
},
onResize: function(chart, size) {
// onResize gradient change
changeGradient()
}
}
});
// Initial gradient change
changeGradient()
function changeGradient() {
let newGradient = updateGradient()
bar_chart.data.datasets[0].borderColor = newGradient
bar_chart.data.datasets[0].pointBorderColor = newGradient
bar_chart.data.datasets[0].pointBackgroundColor = newGradient
bar_chart.data.datasets[0].pointHoverBackgroundColor = newGradient
bar_chart.data.datasets[0].pointHoverBorderColor = newGradient
bar_chart.data.datasets[0].backgroundColor = newGradient
bar_chart.update()
}

Legend option destroys pie chart in Chart.js

My Chart.js pie is working fine, but when I add the legend option, it disappears, much to my dismay. Other options like title and animation work pretty well, only the legend options ruins the pie. I have looked at the code thoroughly, but can't figure out what I'm not doing right. Below is my code:
if ( $('#broadsheet_piechart_sample').length ) {
var ctx = document.getElementById("broadsheet_piechart_sample");
var data = {
datasets: [{
data: [10, 20, 30, 40, 50],
backgroundColor: ['#455C73', '#9B59B6', '#BDC3C7', '#26B99A', '#3498DB'],
}],
labels: ['Dark Gray', 'Purple', 'Gray', 'Green', 'Blue']
};
//options
var options = {
title: {
display: true,
position: "top",
text: "Test Pie Chart",
fontSize: 18,
fontColor: "#111"
},
animation: {
duration: 0
},
legend: {
display: true,
position: "bottom",
labels: {
fontColor: "#333",
fontSize: 16
}
}
};
var broadsheet_piechart_sample = new Chart(ctx, {
data: data,
type: 'pie',
options: options
});
}
You are may using an old version which can cause this issue.
Please upgrade to the latest CharJs version (2.7.3).
Here is what I did for example : example Just exactly what you did.

How can I change the font (family) for the labels in Chart.JS?

I want to change the font to something snazzier in my Chart.JS horizontal bar chart. I've tried the following, but none of it works:
var optionsBar = {
. . .
//fontFamily: "'Candara', 'Calibri', 'Courier', 'serif'"
//bodyFontFamily: "'Candara', 'Calibri', 'Courier', 'serif'"
//bodyFontFamily: "'Candara'"
label: {
font: {
family: "Georgia"
}
}
};
I also read that this would work:
Chart.defaults.global.defaultFont = "Georgia"
...but where would this code go, and how exactly should it look? I tried this:
priceBarChart.defaults.global.defaultFont = "Georgia";
...but also to no good effet.
For the full picture/context, here is all the code that makes up this chart:
HTML
<div class="chart">
<canvas id="top10ItemsChart" class="pie"></canvas>
<div id="pie_legend"></div>
</div>
JQUERY
var ctxBarChart =
$("#priceComplianceBarChart").get(0).getContext("2d");
var barChartData = {
labels: ["Bix Produce", "Capitol City", "Charlies Portland",
"Costa Fruit and Produce", "Get Fresh Sales",
"Loffredo East", "Loffredo West", "Paragon", "Piazza Produce"],
datasets: [
{
label: "Price Compliant",
backgroundColor: "rgba(34,139,34,0.5)",
hoverBackgroundColor: "rgba(34,139,34,1)",
data: [17724, 5565, 3806, 5925, 5721, 6635, 14080, 9027,
25553]
},
{
label: "Non-Compliant",
backgroundColor: "rgba(255, 0, 0, 0.5)",
hoverBackgroundColor: "rgba(255, 0, 0, 1)",
data: [170, 10, 180, 140, 30, 10, 50, 100, 10]
}
]
}
var optionsBar = {
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
},
//fontFamily: "'Candara', 'Calibri', 'Courier', 'serif'"
//bodyFontFamily: "'Candara', 'Calibri', 'Courier', 'serif'"
//bodyFontFamily: "'Candara'"
//Chart.defaults.global.defaultFont = where does this go?
label: {
font: {
family: "Georgia"
}
}
};
var priceBarChart = new Chart(ctxBarChart, {
type: 'horizontalBar',
data: barChartData,
options: optionsBar
});
//priceBarChart.defaults.global.defaultFont = "Georgia";
I even tried this:
CSS
.candaraFont13 {
font-family:"Candara, Georgia, serif";
font-size: 13px;
}
HTML
<div class="graph_container candaraFont13">
<canvas id="priceComplianceBarChart"></canvas>
</div>
...but I reckon the canvas drawing takes care of the font appearance, as adding this made no difference.
UPDATE
I tried this and it completely broke it:
Chart.defaults.global = {
defaultFontFamily: "Georgia"
}
UPDATE 2
As Matthew intimated, this worked (before any of the chart-specific script):
Chart.defaults.global.defaultFontFamily = "Georgia";
This should be useful: http://www.chartjs.org/docs/. It says "There are 4 special global settings that can change all of the fonts on the chart. These options are in Chart.defaults.global".
You'll need to change defaultFontFamily for the font. And defaultFontColor, defaultFontSize, and defaultFontStyle for color, size, etc.
If you wanted to add the font-family to the chart object then you can add it in the options object.
options: {
legend: {
labels: {
fontFamily: 'YourFont'
}
}...}
Here is a link to the docs: https://www.chartjs.org/docs/latest/general/fonts.html
Change font size, color, family and weight using chart.js
scales: {
yAxes: [{ticks: {fontSize: 12, fontFamily: "'Roboto', sans-serif", fontColor: '#000', fontStyle: '500'}}],
xAxes: [{ticks: {fontSize: 12, fontFamily: "'Roboto', sans-serif", fontColor: '#000', fontStyle: '500'}}]
}
See the full code
<!doctype html>
<html>
<head>
<title>Chart.js</title>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet">
<script src="js/Chart.bundle.js"></script>
<script src="js/utils.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
font-weight:700;
}
</style>
</head>
<body>
<div id="container" style="width:70%;">
<canvas id="canvas"></canvas>
</div>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var color = Chart.helpers.color;
var barChartData = {
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
datasets: [{
label: 'Completed',
// Green
backgroundColor: '#4caf50',
borderColor: '#4caf50',
borderWidth: 1,
data: [
5, 15, 25, 35, 45, 55
]
}, {
label: 'Created',
// Blue
backgroundColor: '#1976d2',
borderColor: '#1976d2',
borderWidth: 1,
data: [
10, 20, 30, 40, 50, 60
]
}]
};
window.onload = function () {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
responsive: true,
legend: {
position: 'top',
onClick: null
},
title: {
display: true,
text: '',
fontSize: 20
},
scales: {
yAxes: [{ticks: {fontSize: 12, fontFamily: "'Roboto', sans-serif", fontColor: '#000', fontStyle: '500'}}],
xAxes: [{ticks: {fontSize: 12, fontFamily: "'Roboto', sans-serif", fontColor: '#000', fontStyle: '500'}}]
}
}
});
};
</script>
</body>
</html>
You named the chart priceBarChart in the following part of your code:
var priceBarChart = new Chart(ctxBarChart, {
type: 'horizontalBar',
data: barChartData,
options: optionsBar
})
Which means that priceBarChart.defaults.global.defaultFont = 'Georgia' will 'dive' into the variable priceBarChart, go into its default properties, change one of its global properties and that one is defaultFont, exactly what you want.
But when you apply this code, you basically create the chart with the wrong font and then change it again, which is a bit ugly. What you need to do is tell the chart what the font is beforehand.
You do this by merging your font declaration with the rest of the options, just like how you did it with your variables barChartData and optionsBar.
After you've created barChartData and optionsBar, create another variable with the name, let's say, defaultOptions, like so:
var defaultOptions = {
global: {
defaultFont: 'Georgia'
}
}
You can see that it has the same structure. You go into the global options, and change its defaultFont property. Now you need to apply it to the created chart at the moment it is created, like so:
var priceBarChart = new Chart(ctxBarChart, {
type: 'horizontalBar',
data: barChartData,
options: optionsBar,
defaults: defaultOptions //This part has been added
})
This method of overwriting options is what is being used in almost every JavaScript plugin. When you create a new instance, the plugin copies an object that contains objects that contain objects and so forth. But these objects can be modified with additional options, like barChartData, optionsBar and defaultOptions.
I hope this helps!

Categories