PFont boldFont, normalFont; // holds some custom fonts (bold vs normal weight) void setup() { size(1200, 500); background(255); fill(0); // fixed data for sectors and budgets (extracted from the PDF) String[] sectors = new String[] { "General public services", "Public order and safety", "Education", "Health", "Social security and welfare", "Housing and community amenities", "Recreation and culture", "Fuel and energy", "Agriculture, forestry, fishing and hunting", "Mining and mineral resources other than fuels", "Transport and communications", "Other economic affairs", "Other purposes" }; int[] budgets = new int[] { 408, 1752, 4364, 5618, 1437, 1275, 421, 74, 213, 73, 1219, 390, 766 }; color[] colors = randomColors(budgets.length); // creates desired fonts boldFont = createFont("Arial Bold", 12); normalFont = createFont("Arial", 12); // sets the default (normal weight) font textFont(normalFont); // Stage 1 requirement: renders the data in a grid renderDataAsGrid(sectors, budgets, colors); // Stage 2 requirement: calculate sum of budgets and show it up int totalBudget = sumArray(budgets); renderTotalSum(totalBudget); // Stage 3: display the pie int[] angles = calculateAngles(budgets, totalBudget); pieChart(angles, colors); save("visual1.png"); } /* Calculates the relative angles for all budgets so as they can be used in a pie */ int[] calculateAngles(int[] budgets, int totalBudget) { int[] angles = new int[budgets.length]; int sum = 0; for(int i=0; i < angles.length; i++) { int x = (int)((budgets[i] * 360) / totalBudget); angles[i] = x; sum += x; } if(sum < 360) { // adjust the possible remainder in radians due to previous roundings int diff = 360 - sum; for(int j=1; j <= diff; j++) { angles[j%budgets.length] += 1; // just add 1 angles to every segment till all the diff is used } } return angles; } /* Sets random colors into a lookup table for segments */ color[] randomColors(int len) { int[] colors = new int[len]; for(int i=0; i < colors.length; i++) { colors[i] = color(random(0,255), random(0,255), random(0,255)); } return colors; } /* Renders the total sum of budgets under the grid */ void renderTotalSum(int totalBudget) { textFont(boldFont); int tm = (height / 2) - 150; text("Total budget:", 210, (tm + 40) + (13 * 20)); text(totalBudget, 300, (tm + 40) + (13 * 20)); textFont(normalFont); } /* Calculates the sum of integer values of a given array */ int sumArray(int[] values) { int sum = 0; for(int i=0; i < values.length; i++) { sum += values[i]; } return sum; } /* Display sectors and budgets within a grid on canvas */ void renderDataAsGrid(String[] sectors, int[] budgets, color[] colors) { // captions & basic lines textFont(boldFont); int tm = (height / 2) - 150; line(20, tm, 500, tm); text("Sector", 25, tm+15); text("Budget ($million)", 300, tm+15); text("Color", 455, tm+15); line(20, tm+20, 500, tm+20); textFont(normalFont); line(20, tm, 20, (tm+20) + (13 * 20)); line(295, tm, 295, (tm+20) + (13 * 20)); line(450, tm, 450, (tm+20) + (13 * 20)); line(500, tm, 500, (tm+20) + (13 * 20)); for(int i=0; i < sectors.length; i++) { text(sectors[i], 25, (tm + 35) + (i * 20)); text(budgets[i], 300, (tm + 35) + (i * 20)); fill(colors[i]); rect(452, (tm + 35) + ((i-1) * 20) + 8, 46, 14); fill(0); line(20, (tm + 20) + (i * 20), 500, (tm + 20) + (i * 20)); } line(20, (tm + 20) + (13 * 20), 500, (tm + 20) + (13 * 20)); } /* Creates the pie considering the budgets and colors of segments */ void pieChart(int[] data, color[] colors) { float lastAngle = 0; int diameter = height - 50; for (int i = 0; i < data.length; i++) { fill(colors[i]); arc(550 + (diameter / 2), height/2, diameter, diameter, lastAngle, lastAngle+radians(data[i])); lastAngle += radians(data[i]); } }