Chart.js doughnut chart insufficient height - javascript

I was working on a dashboard which has a doughnut chart on the right side of the page. While I was successful at making the the itself i've been struggling with the height of the the chart. If canvas tag is set using attributes the the whole chart stretches and the height of the chart has a default size of of (128px).
Here is the code below:-
<input type="text" name="balance" value="42" id="balance" hidden>
<div class="chartWrapper">
<canvas id="myChart" height="180px"></canvas>
<div class="ChartContent">
<h2>84%</h2>
</div>
</div>
//START DOUGHNUT CHART
var balance = document.getElementById('balance').value;
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Withdrawal Amount', 'Balance Amount'],
datasets: [{
data: [80, 124, balance],
backgroundColor: [
'#232c66',
'#ffa5a2',
],
borderColor: [
'#232c66',
'#ffa5a2',
],
borderWidth: 2,
hoverBorderWidth: 1,
weight: 2,
clip:
{
left: 5,
top: 5,
right: -2,
bottom: 0
}
}]
},
options: {
cutoutPercentage: 180,
rotation : 5,
animation: true,
legend: {
position: 'chartArea',
padding: 1
},
layout: {
padding: 20
}
}
});
//END DOUGHNUT CHART

Related

How to get radar chart coordinates using getValueForDistanceFromCenter with Chart.js?

I am experimenting with Chart.js to build radar charts. I mastered the basics (see basic chart below), but I would like to use the x y coordinates of the graph to place texts directly on the canvas.
After some digging, I found out that it is not possible to use getValueForPixel or getPixelForTick in a radar chart. See this github issue. In the connecting thread, a new method getValueForDistanceFromCenter is introduced.
As I understand it, it would be possible to calculate the distance from the center with this method, and use it to get coordinates. I searched the Chart.js documentation and other sites, but cannot find any code examples or information on how to implement this.
Can somebody point me in the right direction how to implement the method in the code?
var data = {
labels: ["Ball Skills", "Shooting", "Physical"],
datasets: [{
label: [`ikke`, `jij`],
backgroundColor: "rgba(38,120,255,0.2)",
borderColor: "rgba(38,120,255, 1)",
data: [90, 90, 90]
}]
};
var options = {
responsive: true,
tooltips: false,
title: {
text: 'Basic example',
display: true,
position: `bottom`,
},
scale: {
angleLines: {
display: true
},
ticks: {
suggestedMin: 0,
suggestedMax: 100,
stepSize: 25,
maxTicksLimit: 11,
display: false,
}
},
legend: {
labels: {
padding: 10,
fontSize: 14,
lineHeight: 30,
},
},
};
var myChart = new Chart(document.getElementById("chart"), {
type: 'radar',
data: data,
options: options
});
The radialLinear scale (in version 2.9.4 that I have seen your are using version 2) there is the method getValueForDistanceFromCenter(value) to get the distance from center but there is another method getPointPositionForValue(index, value) which can provide you the point at a specif index of your data.
To use them and to draw what you want on chart using those points, you need to implement a plugin.
In the below snippet, I'm drawing a rect between the points at a specific value.
const ctx = document.getElementById("myChart");
const data = {
labels: ["Ball Skills", "Shooting", "Physical"],
datasets: [{
label: [`ikke`, `jij`],
backgroundColor: "rgba(38,120,255,0.2)",
borderColor: "rgba(38,120,255, 1)",
data: [50, 50, 50]
}]
};
const options = {
responsive: true,
tooltips: false,
title: {
text: 'Basic example',
display: true,
position: `bottom`,
},
scale: {
angleLines: {
display: true
},
ticks: {
suggestedMin: 0,
suggestedMax: 100,
stepSize: 25,
maxTicksLimit: 11,
display: false,
}
},
legend: {
labels: {
padding: 10,
fontSize: 14,
lineHeight: 30,
},
},
};
const plugin = {
id: 'getDistance',
afterDraw(chart) {
const c = chart.ctx;
const rScale = chart.scale;
c.save();
chart.data.datasets[0].data.forEach(function(item, index) {
const point = rScale.getPointPositionForValue(0.5 + index, 50);
c.beginPath();
c.fillStyle = 'red';
c.fillRect(point.x - 5, point.y - 5, 10, 10);
c.fill();
});
c.restore();
}
};
const myChart = new Chart(ctx, {
type: 'radar',
plugins: [plugin],
data: data,
options: options
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.4/dist/Chart.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"/>
</div>
</body>
</html>

How do we put one time series on the left Y-axis and another on the right Y-axis?

How do we put one time series on the left Y-axis and another time series on the right Y-axis (so that we can use two separate scales)?
This is the current chart view
This is the sample chart view I need with left and right time series on Y-axis
The sample code I have used to render the chart is:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
var xValues = [8.8, 8.6, 9.0, 9.7, 9.5, 9.1, 9.0, 9.2, 9.0, 9.6];
var yValues = [31.0, 23.0, 23.0, 45.29, 44.21, 3.53, 83.0, 21.0, 80.0, 38.88]
var labels = ['W12', 'W13', 'W14', 'W15', 'W16', 'W17', 'W18', 'W1P', 'W2P', 'W3P'];
new Chart("id", {
type: "line",
data: {
labels: labels,
datasets: [{
data: xValues,
borderColor: "green",
fill: false,
label: "Salary"
}, {
data: yValues,
borderColor: "orange",
fill: false,
label: "Ownership",
}]
},
options: {
legend: {display: true},
title: {
display: true,
text: "Salary & Ownership"
},
}
});
Thank you.
You can achieve this by providing yAxisID in each datasets data. Following that, mentioning position of each y axis in options.scales.
In the below code, I have made two y axis yAxis: y and yAxis: y1 and mentioned the position left for axis y and position right for axis y1.
You can read more about multi axis line chart here - link
const ctx = document.getElementById("chart").getContext("2d");
var xValues = [8.8, 8.6, 9.0, 9.7, 9.5, 9.1, 9.0, 9.2, 9.0, 9.6];
var yValues = [31.0, 23.0, 23.0, 45.29, 44.21, 3.53, 83.0, 21.0, 80.0, 38.88]
var labels = ['W12', 'W13', 'W14', 'W15', 'W16', 'W17', 'W18', 'W1P', 'W2P', 'W3P'];
const chart6 = new Chart(ctx, {
type: "line",
data: {
labels: labels,
datasets: [{
data: xValues,
borderColor: "green",
fill: false,
label: "Salary",
yAxisID: 'y',
}, {
data: yValues,
borderColor: "orange",
fill: false,
label: "Ownership",
yAxisID: 'y1',
}],
},
options: {
legend: {
display: true
},
title: {
display: true,
text: "Salary & Ownership"
},
scales: {
y: {
type: "linear",
display: true,
position: "left",
},
y1: {
type: "linear",
display: true,
position: "right",
},
},
}
});
#container {
width: clamp(250px, 80%, 1024px);
margin-inline: auto;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
row-gap: 2em;
}
#chart {
position: relative;
max-width: 400px;
max-height: 300px;
}
<body>
<div id="container">
<canvas id="chart" width="400" height="300" role="img" area-label="First Chart for showing frequencies with year." tabindex="0">
</div>
<!-- Date Adaptor (Moment) CDN -->
<script src="https://cdn.jsdelivr.net/npm/chart.js#^3"></script>
<script src="https://cdn.jsdelivr.net/npm/moment#^2"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#^1"></script>
<!-- Chart.js CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js">
</script>
</body>

How to change the angle of x axis ticks dynamically based on size of name?

My charts are changing its alignments due to the size of X-axis label names. The angle of the names also change in order to make it fit in the view. I do not want any changes in the graph alignments (which I believe is due to names printed in an angle) and also want the names in X-Axis to print normally. Graph wrong alignment images.
I have tried using the maxRotation and minRotation to 90 but here all the values are tilted to 90. I want this to be made dynamic ie. the angle must be either 0 or 90 (if the program wants to change angle).
Chartjs code
scales: {
y: {
beginAtZero : false,
ticks: {
display: false,
},
grid : {
display : false,
drawTicks : false,
drawBorder: false
},
},
x: {
maxBarThickness: 10,
ticks : {
color: 'black',
maxRotation: 90,
minRotation: 0,
autoSkip: false,
fontSize : 10,
},
grid : {
display : false,
drawTicks : false
}
}
}
HTML code to hold charts
<style>
.first {
float : left;
width: 45%;
margin: 10px;
}
</style>
<div class ="first"> <canvas id="Services"></canvas> </div>
<div class ="first"> <canvas id="VPN"> </canvas> </div>
<div class = "first"> <canvas id="Policy ID"></canvas> </div>
<div class = "first"> <canvas id="Source Country"></canvas> </div>
<div class = "first"> <canvas id="Source IP"> </canvas> </div>
<div class = "first"> <canvas id="Destination IP"></canvas> </div>
How do I achieve this where I can change the tilt angle to 90 if required ?
You can dynamically change it in the chart config itself and then call update on the chart like so:
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'orange'
}
]
},
options: {
scales: {
x: {
ticks: {
minRotation: 0,
maxRotation: 0
}
}
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
const chart = new Chart(ctx, options);
document.getElementById("switch").addEventListener("click", () => {
chart.options.scales.x.ticks.minRotation = chart.options.scales.x.ticks.minRotation === 0 ? 90 : 0;
chart.options.scales.x.ticks.maxRotation = chart.options.scales.x.ticks.maxRotation === 0 ? 90 : 0;
chart.update();
});
<body>
<button id="switch">
Switch tick rotation
</button>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.js"></script>
</body>

How to add image inside the every slice of doughnut chart using Chart.js? [duplicate]

This question already has answers here:
Chart.js Picture inside doughnut segment
(2 answers)
Closed 3 years ago.
I have draw a doughnut chart using Chart.js https://www.chartjs.org/docs/latest/charts/doughnut.html and i want to add image (i.e .png .svg) inside of every slice of doughnut chart as well as gradient background color.
this goal i want to achieve...image link here
html code here....
<canvas id="myChart" width="600" height="400"></canvas>
js code here
var ctx = $('#myChart');
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Instagram: 35% ($38.21, 100 items)',
'Pinterest: 20% ($23.98, 69 items)',
'Direct: 15% ($17.77, 48 items)',
'Facebook: 12% ($13.54, 41 items)',
'Twitter: 10% ($11.02, 35 items)',
'youtube: 8% ($9.63, 21 items)'],
datasets: [{
data: [35, 20, 15, 12, 10, 8],
backgroundColor: [
'#ff0',
'#BD081C',
'#232323',
'#1877F2',
'#1DA1F2',
'#FF0000'
]
}]
},
options: {
rotation:-0.2 * Math.PI,
responsive: false,
scales: {
Axes: [{
gridLines: {
drawBorder: false,
},
}]
},
legend: {
display: true,
position: "right",
align: "center",
onClick: null,
fontSize: 30,
fullWidth:true,
labels: {
fontColor: '#000',
fontSize:16,
padding:30,
}
},
}
});
Do something like this
var ctx=myChart.width/2;
var cy=myChart.height/2;
ctx.translate(cx,cy);
var startAngle = myChart.segments[thisWedgeIndex].startAngle;
var endAngle = myChart.segments[thisWedgeIndex].endAngle;
var midAngle = startAngle+(endAngle-startAngle)/2;
ctx.rotate(midAngle);//mid angle rotation
//inner radious
var midWedgeRadius=myChart.innerRadius+(chart.radius-chart.innerRadius)/2;
context.translate(midWedgeRadius,0);
context.setTransform(1,0,0,1,0,0);//rotate

Chart.js: width and height of a pie chart not respected

I'm using Chart.js to create pie charts. I need each chart to be 76x76px. Unfortunately, the rendered chart is always a bit smaller than the size if the wrapping div and the canvas itself.
If you inspect the chart in the FIDDLE, you'll see what I mean: the canvas element has a fixed size but the chart itself doesn't fill it fully.
It's almost as if there was a top margin reserved for something that isn't there.
The code:
HTML
<div class="wrapper">
<canvas id="myChart" width="76" height="76"></canvas>
</div>
JS
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
datasets: [{
data: [30, 70],
backgroundColor: [
'green',
'gray'
],
borderWidth: 0
}]
},
options: {
tooltips: {
enabled: false
},
events: []
}
});
CSS
.wrapper {
width: 76px;
height: 76px;
}
Any ideas what I should do to make the pie chart fill the 76x76px canvas?
The additional space is reserved for the legend, which is enabled by default. Simply disable it and you should have the whole space for the chart:
legend: {
display: false
}
A working example:
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
datasets: [{
data: [30, 70],
backgroundColor: [
'green',
'gray'
],
borderWidth: 0
}]
},
options: {
tooltips: {
enabled: false
},
legend: {
display: false // <- the important part
},
events: []
}
});
.wrapper {
width: 76px;
height: 76px;
border: 1px solid black; /* for demonstration purposes*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js" integrity="sha512-d9xgZrVZpmmQlfonhQUvTR7lMPtO7NkZMkA0ABN3PHCbKA5nqylQ/yWlFAyY6hYgdF1Qh6nYiuADWwKB4C2WSw==" crossorigin="anonymous"></script>
<div class="wrapper">
<canvas id="myChart" width="76" height="76"></canvas>
</div>

Categories