Update ! |
||
This pie chart compoment has now been moved into the Iceberg Charts project . Please use Iceberg Charts for a more complete charting experience. |
Pie charts are pretty boring. I hadn’t found anything out there which resembled a multi level pie chart. A multi level pie chart, is basically a pie chart with a number of levels (Excel 2016 has something similar called Sunburst charts). Each level is in effect an expansion of the slice below it. A multi level pie chart basically represents a tree structure, where each node has a magnitude. The component I have written requires a tree structure of Segment objects. A typical real world scenario where you would use a multi level pie chart would be to view the disk usage on a computer. A simplistic example I created is shown below.
The code I needed to generate the above chart is just this :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
ArrayList values = new ArrayList(); values.add(new Segment(0, null, 15, "music", Color.RED)); values.add(new Segment(0, null, 52, "photos", Color.BLUE)); values.add(new Segment(0, null, 33, "applications", Color.GREEN)); Color c = Color.BLUE; Segment s0 = values.get(0); Segment s1 = values.get(1); Segment s2 = values.get(2); { c = s0.color; s0.children.add(new Segment(1, s0, 80.0, "jazz", darken(c))); s0.children.add(new Segment(1, s0, 7.0, "rock", darken(darken(c)))); s0.children.add(new Segment(1, s0, 13.0, "classical", darken(darken(darken(c))))); } { c = Color.cyan; s1.children.add(new Segment(1, s1, 80.0, "holiday snaps", darken(c))); s1.children.add(new Segment(1, s1, 7.0, "weddings", darken(darken(c)))); s1.children.add(new Segment(1, s1, 13.0, "baby", darken(darken(darken(c))))); } { c = Color.YELLOW; s2.children.add(new Segment(1, s2, 80.0, "Windows", darken(c))); s2.children.add(new Segment(1, s2, 7.0, "Favourites", darken(darken(c)))); s2.children.add(new Segment(1, s2, 13.0, "Database", darken(darken(darken(c))))); } Segment s20 = s2.children.get(0); { c = Color.PINK; s20.children.add(new Segment(2, s20, 50.0, "Office", darken(c))); s20.children.add(new Segment(2, s20, 7.0, "Visio", darken(darken(c)))); s20.children.add(new Segment(2, s20, 43.0, "Paint", darken(darken(darken(c))))); } Segment s22 = s2.children.get(2); { c = Color.WHITE; s22.children.add(new Segment(2, s22, 50.0, "Oracle", darken(c))); s22.children.add(new Segment(2, s22, 50.0, "Access", darken(darken(c)))); } Segment s200 = s20.children.get(0); { c = Color.ORANGE; s200.children.add(new Segment(3, s200, 10.0, "Word", darken(c))); s200.children.add(new Segment(3, s200, 80.0, "Excel", darken(darken(c)))); s200.children.add(new Segment(3, s200, 5.0, "Access", darken(darken(darken(c))))); s200.children.add(new Segment(3, s200, 5.0, "Powerpoint", darken(darken(darken(darken(c)))))); } Segment s10 = s1.children.get(0); { c = Color.white; s10.children.add(new Segment(2, s10, 30.0, "Rome", darken(c))); s10.children.add(new Segment(2, s10, 20.0, "Paris", darken(darken(c)))); s10.children.add(new Segment(2, s10, 10.0, "London", darken(darken(darken(c))))); s10.children.add(new Segment(2, s10, 10.0, "Beach", darken(darken(darken(darken(c)))))); s10.children.add(new Segment(2, s10, 30.0, "China", darken(darken(darken(darken(c)))))); } PieChart pieChart = new PieChart(values); |
In order for it to not look like a multi colored mess, I have applied a gradient-like effect, by darkening the colors sequentially after the initial color is set for a segment. My darken method is simply :
1 2 3 |
private Color darken(Color c) { return c.darker(); } |
I think this is quite effective, but there may be other ways or algorithms to implement a set of related colors. You could experiment with incrementally adjusting the hue, saturation or a rgb value.
A bit about the design of this component :
For a simple pie chart there are really only three things to consider for a pie slice. They are
- the starting angle (calculated from what slices have previously been drawn),
- the magnitude (if it is a percent it needs to be converted to an angle)
- and of course the color.
This is simple enough to implement. However for a multi level pie slice there are many other things to consider :
- Relative start angle.The start angle needs to be converted, because this pie slice may not be the first level, and therefore a scaling would need to be applied.
- Parent. The slice will have a parent, if it is not on the first level.
- Relative magnitude. The angle, or percent, needs to be scaled based on what its parent is. If the parent represents 50% and the parents parent is on the first level and represents 50%, then the scalings would have to be combined to 25%. This 25% would then have to be applied to the original magnitude.
Also to consider would be
- Circle1 – a circle that represents the outer rim of the slice.
- Circle2 – a circle that would need to be subtracted from the arch created from circle1.
These circles would need to be calculated depending on a number of factors. The extend and starting point would of course need to be taken into account, and the number of circles needed would also depend on the total depth of the tree structure.
Given all these things to consider, the segment is a special type of object. Omitting the getters and setters for clarity, here is the class I came up with for a segment. A lot of the values need to be calculated.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class Segment { double startAngle;//starting angle (calculated) double angle; // from magnitude (calculated) Color color; //color (supplied by user) int level; //level 0 = first level pie chart (supplied by user) Segment parent; //parent segment (supplied by user) Double magnitude; //percent (supplied by user) String name; //name of segment (supplied by user) Area area; //geometric shaped (calculated) Point midpoint; //a calculated midpoint that determines where the text should be drawn (calculated) } |
If you would like to use this component in a project, or would like to look at the source code, please contact me
I need to display some statistics with a multilevel pie but I can not find any example on the Internet, can I have the code for this example it is exactly what I want.
Thank you,
Can I get the source code please????
Can I get the source code please????
Bhargav9900@gmail.com
Hi Bhargav, you will find the multi level charts in icebergCharts here :
http://www.frontangle.com/icharts/#/
There are examples on how to use them