Hello,
We have implemented Kendo Vue Donut chart, using visual function, that in most cases rendered well.
But we found that on certain devices (regardless bigger or smaller) the chart renders each slice of the donut as a full circle and puts them all one on top of the other. The attached image demonstrates it.
Our investigation shows that it is the result of the seriesDefaults holeSize value AND the visual function stroke line width.
Both are determined programmatically at run time.
The following values result with the correct donut you see in the image:
holeSize: 83
visual stroke width: 22 (or less)
And the following values result with the incorrect donut:
holeSize: 83
visual stroke width: 23 (or more)
Notice it is also related to the holeSize - for example the following will be rendered well:
holeSize: 85
visual stroke width: 23 (or more)
And holeSize 84 with visual stroke width of 23 is rendered incorrectly.
Can you please advise how we can make sure it will always be rendered correctly? Is there a certain ratio between the holeSize and the visual stroke width we need to maintain?
Thanks,
Ron.
5 Answers, 1 is accepted
Hi Ron,
Can you please share with me the custom visual function that you use for the stroke? Also, why don't you try using the border series configuration that we offer out-of-the-box instead, or you cannot get the same results with it? I will need some additional information and preferably a runnable example where I can check your current configuration in order to give you more insights on the issue with the Donut Chart that you are facing.
I am looking forward to your reply!
Regards,
Teya
Progress Telerik
Thanks Teya,
Unfortunately Kendo does not offer pie in the design we need to implement (as seen in the screen I attached). Hence we are forced to use the visual function.
You may see further details in previous post I sent about this chart: https://www.telerik.com/forums/improving-donut-chart-truncated-labels
I read about the border series configuration you suggested but I fail to see how it is related.
Here’s the visual function code:
visual: e => {
var html = $(`<div><p>${e.dataItem.displayPercent}</p></div>`).appendTo(document.body);
var visual = new kendo.drawing.Group();
var rect = e.rect;
kendo.drawing.drawDOM(html)
.done(function (group) {
html.remove();
//Center the label using Layout
var layout = new kendo.drawing.Layout(rect, {
justifyContent: 'center',
alignItems: 'center'
});
layout.append(group);
layout.reflow();
//Render the content
visual.append(layout);
});
return visual;
}
Thanks,
Ron.
Hi Ron,
From your original request, I got the idea that you are adding a stroke via a visual function:
"Our investigation shows that it is the result of the seriesDefaults holeSize value AND the visual function stroke line width."
This is why I suggested using a border, instead of a stroke and I asked to see the visual function that is defining the series stroke line width. However, the visual function that you have sent me is the one used for the labels, which is something different and not directly related to the current request. Or am I missing something?
So, can you please share with me how you are setting up the stroke line width of the series?
Regards,
Teya
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.
Indeed I sent the labels visual - my mistake.
The following is what we use.
For the chart-area-height we use the following function, based on the device height:
const maxHeight = 660;//decided to use 660 as the max height
const reportsHeaderHeight = 130;
return ((this.deviceAttributes.height - reportsHeaderHeight > maxHeight) ? maxHeight : (this.deviceAttributes.height - reportsHeaderHeight));
For the series-defaults we use the following:
{
type: 'donut',
holeSize: Math.floor(65 / 320 * this.deviceAttributes.width),//ratio is based on working example we reviewed
startAngle: 150,
labels: {
distance: 15,
position: 'outsideEnd',
visible: true,
align: 'circle',
background: 'transparent',
visual: e => {
var html = $(`<div><p>${e.dataItem.displayPercent}</p></div>`).appendTo(document.body);
var visual = new kendo.drawing.Group();
var rect = e.rect;
kendo.drawing.drawDOM(html)
.done(function (group) {
html.remove();
//Center the label using Layout
var layout = new kendo.drawing.Layout(rect, {
justifyContent: 'center',
alignItems: 'center'
});
layout.append(group);
layout.reflow();
//Render the content
visual.append(layout);
});
return visual;
}
},
connectors: {
width: 0
},
visual: e => {
//const width = 18;//original p2h value
const width = Math.floor((18 / 320) * this.deviceAttributes.width);//we use 18/320 to maintain example proportions; integer is required for the chart to render correctly
const space = 6;
const group = new kendo.drawing.Group();
const A = (Math.PI - Math.acos(((width / 2) + space) / 2 / e.radius) * 2) * 180 / Math.PI;
const geometry = new kendo.geometry.Arc([ e.center.x, e.center.y ], {
radiusX: e.radius - width / 2,
radiusY: e.radius - width / 2,
startAngle: e.startAngle + A,
endAngle: e.endAngle - A
});
const arc = new kendo.drawing.Arc(geometry, {
stroke: {
color: e.options.color,
width: width,
lineCap: 'round',
lineJoin: 'round'
}
});
return group.append(arc);
},
highlight: {
visible: false
}
}
Looking forward for your response :)
Hello Ron,
Thank you for the provided code. I managed to reproduce the reported issue. After investigation, I found out where the problem lays. Since you are adding space between the series by changing the start and end values in the visual function, there are cases in which the following calculations:
const A = (Math.PI - Math.acos(((width / 2) + space) / 2 / e.radius) * 2) * 180 / Math.PI;
const geometry = new kendo.geometry.Arc([ e.center.x, e.center.y ], {
radiusX: e.radius - width / 2,
radiusY: e.radius - width / 2,
startAngle: e.startAngle + A,
endAngle: e.endAngle - A
});
result in starting angles bigger than end angles, which is incorrect and this is why these series are drawn as whole circles. This happens when you have series with larger stroke (e.g 23) and small values (e.g .1.1% ), which are visualized with small size. If the size of the series ( e.startAngle - e.endAngle) is less than the calculated A constant, the discrepancy I mentioned happens, which is expected. The size of the visual representation of the series depends on the stroke width and the chart size. In your case, it doesn't depend on the holeSize, as the set value gets overridden by the visual function. Even if the holeSize is set to 0, the donut chart doesn't change its appearance:
https://dojo.telerik.com/IrAMIRuh/3
My advice is to ensure the following:
e.startAngle - e.endAngle > A
If this holds true, then you won't experience the overlaying issues in the Chart.
Regards,
Teya
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.