score:24
With v2.1.3, you can use the pluginService
to do this
Preview
Script
// round corners
Chart.pluginService.register({
afterUpdate: function (chart) {
if (chart.config.options.elements.arc.roundedCornersFor !== undefined) {
var arc = chart.getDatasetMeta(0).data[chart.config.options.elements.arc.roundedCornersFor];
arc.round = {
x: (chart.chartArea.left + chart.chartArea.right) / 2,
y: (chart.chartArea.top + chart.chartArea.bottom) / 2,
radius: (chart.outerRadius + chart.innerRadius) / 2,
thickness: (chart.outerRadius - chart.innerRadius) / 2 - 1,
backgroundColor: arc._model.backgroundColor
}
}
},
afterDraw: function (chart) {
if (chart.config.options.elements.arc.roundedCornersFor !== undefined) {
var ctx = chart.chart.ctx;
var arc = chart.getDatasetMeta(0).data[chart.config.options.elements.arc.roundedCornersFor];
var startAngle = Math.PI / 2 - arc._view.startAngle;
var endAngle = Math.PI / 2 - arc._view.endAngle;
ctx.save();
ctx.translate(arc.round.x, arc.round.y);
console.log(arc.round.startAngle)
ctx.fillStyle = arc.round.backgroundColor;
ctx.beginPath();
ctx.arc(arc.round.radius * Math.sin(startAngle), arc.round.radius * Math.cos(startAngle), arc.round.thickness, 0, 2 * Math.PI);
ctx.arc(arc.round.radius * Math.sin(endAngle), arc.round.radius * Math.cos(endAngle), arc.round.thickness, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
ctx.restore();
}
},
});
// write text plugin
Chart.pluginService.register({
afterUpdate: function (chart) {
if (chart.config.options.elements.center) {
var helpers = Chart.helpers;
var centerConfig = chart.config.options.elements.center;
var globalConfig = Chart.defaults.global;
var ctx = chart.chart.ctx;
var fontStyle = helpers.getValueOrDefault(centerConfig.fontStyle, globalConfig.defaultFontStyle);
var fontFamily = helpers.getValueOrDefault(centerConfig.fontFamily, globalConfig.defaultFontFamily);
if (centerConfig.fontSize)
var fontSize = centerConfig.fontSize;
// figure out the best font size, if one is not specified
else {
ctx.save();
var fontSize = helpers.getValueOrDefault(centerConfig.minFontSize, 1);
var maxFontSize = helpers.getValueOrDefault(centerConfig.maxFontSize, 256);
var maxText = helpers.getValueOrDefault(centerConfig.maxText, centerConfig.text);
do {
ctx.font = helpers.fontString(fontSize, fontStyle, fontFamily);
var textWidth = ctx.measureText(maxText).width;
// check if it fits, is within configured limits and that we are not simply toggling back and forth
if (textWidth < chart.innerRadius * 2 && fontSize < maxFontSize)
fontSize += 1;
else {
// reverse last step
fontSize -= 1;
break;
}
} while (true)
ctx.restore();
}
// save properties
chart.center = {
font: helpers.fontString(fontSize, fontStyle, fontFamily),
fillStyle: helpers.getValueOrDefault(centerConfig.fontColor, globalConfig.defaultFontColor)
};
}
},
afterDraw: function (chart) {
if (chart.center) {
var centerConfig = chart.config.options.elements.center;
var ctx = chart.chart.ctx;
ctx.save();
ctx.font = chart.center.font;
ctx.fillStyle = chart.center.fillStyle;
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.fillText(centerConfig.text, centerX, centerY);
ctx.restore();
}
},
})
and then
...
options: {
elements: {
arc: {
roundedCornersFor: 0
},
center: {
// the longest text that could appear in the center
maxText: '100%',
text: '67%',
fontColor: '#FF6684',
fontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
fontStyle: 'normal',
// fontSize: 12,
// if a fontSize is NOT specified, we will scale (within the below limits) maxText to take up the maximum space in the center
// if these are not specified either, we default to 1 and 256
minFontSize: 1,
maxFontSize: 256,
}
}
}
};
You can get rid of a bit of code if you don't want it to be generic (eg. if you fix the fontSize, if you fix the index to round, etc.)
Fiddle - http://jsfiddle.net/cd3fdoy9/
score:0
Modified code slightly to handle the use of arc.borderWidth in the arc if its used. For version 2.8 of Charts.js
Chart.pluginService.register({
afterUpdate: function (chart) {
if (chart.config.options.elements.arc.roundedCornersFor !== undefined) {
var arc = chart.getDatasetMeta(0).data[chart.config.options.elements.arc.roundedCornersFor];
arc.round = {
x: (chart.chartArea.left + chart.chartArea.right + chart.config.options.elements.arc.borderWidth) / 2,
y: (chart.chartArea.top + chart.chartArea.bottom) / 2,
radius: (chart.outerRadius + chart.innerRadius) / 2,
thickness: (chart.outerRadius - chart.innerRadius - (chart.config.options.elements.arc.borderWidth /2)) / 2 -1,
backgroundColor: arc._model.backgroundColor
};
}
},
afterDraw: function (chart) {
if (chart.config.options.elements.arc.roundedCornersFor !== undefined) {
var ctx = chart.chart.ctx;
var arc = chart.getDatasetMeta(0).data[chart.config.options.elements.arc.roundedCornersFor];
var startAngle = Math.PI / 2 - arc._view.startAngle;
var endAngle = Math.PI / 2 - arc._view.endAngle;
ctx.save();
ctx.translate(arc.round.x, arc.round.y);
ctx.fillStyle = arc.round.backgroundColor;
ctx.beginPath();
ctx.arc(arc.round.radius * Math.sin(startAngle), arc.round.radius * Math.cos(startAngle), arc.round.thickness, 0, 2 * Math.PI);
ctx.arc(arc.round.radius * Math.sin(endAngle), arc.round.radius * Math.cos(endAngle), arc.round.thickness, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
ctx.restore();
}
}
});
score:0
I work on the same project and make this
Chart.defaults.RoundedDoughnut = Chart.helpers.clone(Chart.defaults.doughnut);
const costume = Chart.controllers.doughnut.extend({
draw(ease) {
Chart.controllers.doughnut.prototype.draw.call(this, ease);
const { ctx } = this.chart.chart;
const easingDecimal = ease || 1;
const arcs = this.getMeta().data;
Chart.helpers.each(arcs, function(arc, index) {
arc.transition(easingDecimal).draw();
const vm = arc._view;
const radius = (vm.outerRadius + vm.innerRadius) / 2;
const thickness = (vm.outerRadius - vm.innerRadius - 2) / 2;
const startAngle = Math.PI - vm.startAngle - Math.PI / 2;
const angle = Math.PI - vm.endAngle - Math.PI / 2;
if (index % 2 == 1) {
ctx.save();
ctx.fillStyle = vm.backgroundColor;
ctx.translate(vm.x, vm.y);
ctx.beginPath();
ctx.arc(
radius * Math.sin(startAngle),
radius * Math.cos(startAngle),
thickness,
0,
2 * Math.PI,
);
ctx.fill();
ctx.fillStyle = vm.backgroundColor;
ctx.beginPath();
ctx.arc(
radius * Math.sin(angle),
radius * Math.cos(angle),
thickness,
0,
2 * Math.PI,
);
ctx.fill();
ctx.restore();
}
if (index == 2) {
ctx.save();
ctx.fillStyle = arcs[1]._view.backgroundColor;
ctx.translate(vm.x, vm.y);
ctx.beginPath();
ctx.arc(
radius * Math.sin(startAngle),
radius * Math.cos(startAngle),
thickness,
0,
2 * Math.PI,
);
ctx.fill();
ctx.restore();
}
});
},
});
const deliveredData = {
labels: ['1', '2', '3', '4'],
datasets: [
{
data: [5, 40, 5, 30],
backgroundColor: ['#fff', '#ff0000', '#fff', '#ffff00'],
},
],
};
Chart.controllers.RoundedDoughnut = costume;
const newChartInstance = new Chart(chartRef.current, {
type: 'RoundedDoughnut',
data: deliveredData,
options: { cutoutPercentage: 75, legend: { display: false }, tooltips: { enabled: false } },
});
score:2
I've added a piece of code to change the center text when legend is clicked.
afterDraw: function (chart) {
if (chart.center) {
var ctx = chart.chart.ctx;
var i,a,s;
var n = chart;
var total = 0;
for(i=0,a=(n.data.datasets||[]).length;a>i;++i){
s = n.getDatasetMeta(i);
var x;
for(x=0; x<s.data.length; x++){
if (!s.data[x].hidden)
total += n.data.datasets[i].data[x];
}
}
ctx.save();
ctx.font = chart.center.font;
ctx.fillStyle = chart.center.fillStyle;
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.fillText(total, centerX, centerY);
ctx.restore();
}
}
Fiddle - http://jsfiddle.net/cd3fdoy9/49/
Source: stackoverflow.com
Related Query
- Chart.js Doughnut with rounded edges and text centered
- Vue Chart.js Doughnut Chart with rounded and spaced arcs (vue3-chart-v2)
- Chart.js Doughnut with rounded edges
- Keep chart.js doughnut with fixed width and height centered in container
- Vue Chart 3 - Doughnut Charts with Text in the Middle (Trouble registering a plugin)
- Doughnut Chart not displaying data with Chart Js and Backbone js
- Text inside Doughnut chart using Chart.js and Angular2, Ionic2
- Chartjs - Doughnut chart with multi layer and running value
- JavaScript doughnut chart with centered hover label
- How to add text inside the doughnut chart using Chart.js?
- Chartjs 2 - Stacked bar and unstacked line on same chart with same y axis
- chartjs datalabels change font and color of text displaying inside pie chart
- How to add text in centre of the doughnut chart using Chart.js?
- Chart.js Mixed Bar and Line chart with different scales
- Problem for display a chart with Chart.js and Angular
- Show X axis on top and bottom in line chart rendered with Chart.js 2.4.0
- Chart.JS full-width, responsive doughnut chart with Bootstrap
- Chart.js HTML custom legend issues with doughnut chart
- ChartJs line chart - display permanent icon above some data points with text on hover
- Create a rounded bar graph with Angular and chartJS
- Can we draw a Line Chart with both solid and dotted line in it?
- Chartjs extended doughnut with text tooltip issue
- Increase padding between legend and chart with react-chartjs-2
- Chartjs doughnut chart with gradient color
- Bold text inside doughnut chart (chart.js)
- How can I add some text in the middle of a half doughnut chart in Chart.JS?
- ChartJS (React) Line Chart - How to show single tooltip with data and labels from 3 (multiple) dataset?
- React chart : prevent chart's canvas scaling with height and width
- Why would a ChartJS chart end up with width 0 and height 0?
- Stacked bar chart with rounded corner of bar using Chart.js
More Query from same tag
- How to change color by clicking on the chart bar?
- "this" doesn't work in click event handler
- Additional line in BarChart (Charts.js)
- react-chartjs-2 bar touches the top
- Animation chart js (line), animate chart drawing line by line
- Chart.js creating multiple Charts in Angular in same Component
- Is there a way to trigger point hit on an xAxis hover
- how can i show labels and value in both on bar chart
- Unable to Construct Stacked Vue-ChartJS Line Plot
- Transform JSON data for ChartJS
- how to get React chartjs to resize back down with window
- Using Chart.js 2.0, display line chart values
- chartJS - points overplotting, jittering, noise?
- Chart.js line chart is cut off at the top?
- Chart.js line chart not showing in Google Chrome canvas(only in Microsoft Edge)
- How could chartjs font family display everywhere
- i can't alias in Apache permission denied
- Chart JS date-hour AxesX
- How to update data Chart in async way in Angular Chart.js?
- chart.js in mvc graph are not show
- Do not rotate scale title at xAxis
- Chart.js tooltip background color setting
- ng2-charts - Angular 4 working example
- Creating chart.js chart directly to PNG in Node js?
- ChartJS: How to set fixed Y axis max and min
- How to disable scientific notations in logarithmic chart type
- ChartJS fails to render horizontal bar chart for timeseries data
- Time format on the x axis in Chart.js
- Exporting chart.js charts to svg using canvas2svg.js
- chart resizing in ng2-google-charts