I am a newbie in data visualisation. I would like to tweak around a pie chart to come up with an arrow ring chart like in the image below. Thanks for your help
-
Here's something I [built once](https://bl.ocks.org/larsenmtl/1d4b242e86bfde14490ba3ea82261958). – Mark Oct 22 '18 at 11:24
-
For D3, [this](https://stackoverflow.com/a/41194980/7106086) answer is related (arc heads as arrows) and [this](https://bl.ocks.org/Andrew-Reid/51d2665a976266abbaa62eae1ba80cdc) refines linked answer and allows indentation of the arc tails too. – Andrew Reid Oct 22 '18 at 15:16
-
Thank you @AndrewReid...The refine works fine for me – Bryan Nahabwe Oct 23 '18 at 13:30
1 Answers
Highcharts pie chart can be customized to the arrow ring chart. It requires a little custom code but can be done. I prepared you an example of a donut chart where I added a custom symbol (more about custom symbols here), additionally, I overwritten H.SVGRenderer.prototype.arc
to use my custom symbol instead of the default one (arc in a pie chart).
So what you have to add there is an arrow ring path (instead of arc) which is the main issue to solve. Highcharts will use this symbol to plot each point (arrow ring). Try to add an additional path to the existing arc path of the beginning and end of each point. It is a little tricky because you will have to calculate extreme points of each slice (chart point) and angle to render an appropriate path (beginning or end arrow).
Check the demo I posted you below and try to change arc
array there to find out what I'm talking about. Check also the description of Highcharts.SVGRenderer
path method description to know how to create your custom arrow paths.
Demo: jsfiddle
HTML:
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
JS:
// Define a custom symbol path
Highcharts.SVGRenderer.prototype.symbols.arcArrow = function(x, y, w, h, options) {
var start = options.start,
pick = Highcharts.pick,
defined = Highcharts.defined,
rx = options.r || w,
ry = options.r || h || w,
proximity = 0.001,
fullCircle =
Math.abs(options.end - options.start - 2 * Math.PI) <
proximity,
end = options.end - proximity,
innerRadius = options.innerR,
open = pick(options.open, fullCircle),
cosStart = Math.cos(start),
sinStart = Math.sin(start),
cosEnd = Math.cos(end),
sinEnd = Math.sin(end),
// Proximity takes care of rounding errors around PI (#6971)
longArc = options.end - start - Math.PI < proximity ? 0 : 1,
arc;
// Here you can define your arrows path instead of arc
// Try to add additional code to beggining and end of existing arc
arc = [
'M',
x + rx * cosStart,
y + ry * sinStart,
'A', // arcTo
rx, // x radius
ry, // y radius
0, // slanting
longArc, // long or short arc
1, // clockwise
x + rx * cosEnd,
y + ry * sinEnd
];
if (defined(innerRadius)) {
arc.push(
open ? 'M' : 'L',
x + innerRadius * cosEnd,
y + innerRadius * sinEnd,
'A', // arcTo
innerRadius, // x radius
innerRadius, // y radius
0, // slanting
longArc, // long or short arc
0, // clockwise
x + innerRadius * cosStart,
y + innerRadius * sinStart
);
}
arc.push(open ? '' : 'Z'); // close
return arc;
};
if (Highcharts.VMLRenderer) {
Highcharts.VMLRenderer.prototype.symbols.arcArrow = Highcharts.SVGRenderer.prototype.symbols.arcArrow;
}
(function(H) {
H.SVGRenderer.prototype.arc = function(x, y, r, innerR, start, end) {
var arc,
isObject = H.isObject,
options;
if (isObject(x)) {
options = x;
y = options.y;
r = options.r;
innerR = options.innerR;
start = options.start;
end = options.end;
x = options.x;
} else {
options = {
innerR: innerR,
start: start,
end: end
};
}
// Arcs are defined as symbols for the ability to set
// attributes in attr and animate
arc = this.symbol('arcArrow', x, y, r, r, options);
arc.r = r; // #959
return arc;
}
})(Highcharts);
Highcharts.chart('container', {
series: [{
type: 'pie',
innerSize: '70%',
data: [
['Chrome', 58.9],
['Firefox', 13.29],
['Internet Explorer', 13],
['Edge', 3.78],
['Safari', 3.42],
{
name: 'Other',
y: 7.61,
dataLabels: {
enabled: false
}
}
]
}]
});
I hope it will be helpful for you. If you will have any troubles with it or my explanation is too complicated do not hesitate to ask me.

- 7,302
- 1
- 7
- 16
-
Please post the code in your answer, rather than linked in a fiddle. If/when the fiddle is removed, this answer will not be useful to other SO users with similar questions. – i alarmed alien Oct 23 '18 at 19:39
-
1