Reputation:
Note: I'm quite new to javascript and ChartJS, so I have done my best to look at similar questions but I'm unsure how to apply the solutions to my issue. I'm really quite confused by the plugins, and it seems whenever I try to literally copy and paste in solutions from other posted questions, it either breaks the graph or just doesn't do anything at all. So, with that in mind, I appreciate any help!
I'm trying to format the outer of two overlaid doughnut graphs using ChartJS so that the outer graph looks like a rounded bracket. The intention is to be able to group certain slices of the inner doughnut together, EG: Inner graph shows number of years John has lived in 5 different places, the outer graph is grouping the 2nd, 3rd, and 4th slice to indicate that he lived in these locations while he was a wildland forest firefighter for the US Forest Service.
See below. Please note, the tick marks on the edges are important. It should look like a rounded bracket -> ] <-
Things I have tried:
borderWidth: { top: 1, right: 1, bottom: 0, left: 1 }
breaks the graph, as I'm not sure there's a "bottom" persay to a doughnut graph{1, 98, 1}
with the cutout
specified on each slice so it would look like cutout: {85, 90, 85}
, in theory. This version is untested.)Pardon the comments in the js, those are just there for me to remember what's going on.
var chart1 = document.getElementById('chart1').getContext('2d');
let doughnut1 = new Chart(chart1, {
type: 'doughnut',
data: {
datasets: [{ // OUTER ring
data: [100], //leave at 100
backgroundColor: ['#fff'],
circumference: 300, //determines circumference of outer border X out of 360
weight: 0.15,
radius: '100%',
borderColor: 'black',
borderWidth: 4
}, {
data: [14, 14, 22, 37, 13],
backgroundColor: ['#f5ce42', '#ccc3a3', '#fc95f2', '#cdb2ed', '#423225'],
radius: '95%',
borderColor: 'black',
borderAlign: 'inside'
}]
}
});
.wrap__chart {width: 50vw; margin: 0 auto;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<div class="wrap__chart">
<canvas id="chart1"></canvas>
</div>
Parameters for this graph are:
Upvotes: 0
Views: 1261
Reputation:
Ok I finally found a solution for my own question. It's quite roundabout, so I don't know if it's an actual answer for anyone else.
It involves using three graphs, unfortunately:
var sliceA = 60000,
sliceB = 24000,
sliceC = 36000;
var protected = (((sliceA + sliceB)/(sliceA + sliceC + sliceB)) * 360);
//colors
var outerRing = 'green';
var ctx = document.getElementById("chart");
var chart = new Chart(ctx, {
type: 'doughnut',
data: {
datasets: [{
data: [sliceA, sliceB, sliceC],
backgroundColor: ['limegreen', 'skyblue', 'firebrick'],
radius: '82%',
cutout: '50%',
}]
}
});
var chart2 = document.getElementById('chart2').getContext('2d');
let doughnut2 = new Chart(chart2, {
type: 'doughnut',
data: {
datasets: [{ // OUTER ring
data: [1, 98, 1], //leave at 100
backgroundColor: [outerRing, 'transparent', outerRing],
circumference: (protected + 5), //determines circumference of outer border X out of 360
weight: 0.5,
radius: '100%',
borderWidth: 0,
borderAlign: 'inside',
borderColor: 'transparent',
rotation: -2
},
{ data: //14, 14, 22, 37, 13
[100],
backgroundColor: [outerRing],
radius: '97%',
cutout: '92%',
circumference: (protected + 2),
borderWidth: '5px',
borderColor: outerRing,
rotation: -1
}
]
},
options: {
parsing: {
key: 'nested.value'
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<div class="container">
<canvas id="chart" style="position:absolute;"></canvas>
<canvas id="chart2" style="position:absolute;"></canvas>
</div>
it's not perfect, i'm still working out how to make the back rotation and addition to the variable "protected" in the outer rings responsive, with the intention of making it so that the inside of each tick mark aligns perfectly with 0 degrees and var protected degrees on the circle, to properly indicate that the outer ring encompasses all slices of the doughnut chart within the specified range.
you can change the outer ring style from a capital i to a [ style by changing the radius of each of the two layers of the outer ring. Switching the second dataset to be 100% and the first to be ~95% will change it accordingly.
Upvotes: 0
Reputation: 1106
You can leave a single line instead of a rectangle by modifying the width property weight: 0.15
to weight: 0.001
and the border property borderWidth: 4
to borderWidth: 1
. There is no other property you can change to make it more like what you want.
The new code:
var chart1 = document.getElementById('chart1').getContext('2d');
let doughnut1 = new Chart(chart1, {
type: 'doughnut',
data: {
datasets: [{ // OUTER ring
data: [100], //leave at 100
backgroundColor: ['#fff'],
circumference: 300, //determines circumference of outer border X out of 360
weight: 0.001,
radius: '100%',
borderColor: 'black',
borderWidth: 1
}, {
data: [14, 14, 22, 37, 13],
backgroundColor: ['#f5ce42', '#ccc3a3', '#fc95f2', '#cdb2ed', '#423225'],
radius: '95%',
borderColor: 'black',
borderAlign: 'inside'
}]
}
});
Upvotes: 0