REBOL [ Title: Generate pie chart ] ;; [---------------------------------------------------------------------------] ;; [ This is a function to make a pie chart out of some input data. ] ;; [ It saves the chart to a png file of a specified name. ] ;; [ The input data is a block of pairs of values. ] ;; [ The first item of a pair is a number. This is some quantity that is ] ;; [ to be shown as a slice of the pie chart. One of these numbers, ] ;; [ divided by the total of all the numbers, will form a fraction that is ] ;; [ the size of the pie slice. Multiplying that fraction by 360 degrees ] ;; [ will give an angle for drawing the slice. ] ;; [ The second item of a pair is a REBOL color word, which will be used ] ;; [ to color the slice. ] ;; [ Also specified with the data block is a file name that will be the ] ;; [ name of a file that will contain the image of the pie chart. ] ;; [ It should be a ".png" file name. ] ;; [ This function is only semi-general. ] ;; [ You will want to change some items at the front that control the ] ;; [ size of the image. ] ;; [---------------------------------------------------------------------------] GEN-PIECHART: func [ ;; Input data for the chart. ;; This is a block of repeating pairs of items. ;; The first item of a pair is the amount being turned into a slice. ;; We chose to supply amounts instead of percentages because it ;; seemed like that was the most likely data to be available. ;; The second item of a pair is the color for this slice (a 'word). ;; The second argument it the name of the file for saving the image. SLICE-DATA PIECHART-FILENAME ] [ ;; Change these to change the size of the chart. BOX-SIZE: 400x400 ;; Size of box holding chart. PIE-CENTER: 200x200 ;; Center of pie in the box. PIE-RADIUS: 200x200 ;; Radius of pie chart (X and Y). START-ANGLE: 0 ;; Starting angle of first slice. ;; This block will hold the draw commands that we generate. DRAW-BLOCK: [] ;; Working items. SLICE-START: 0 ;; Start angle of current slice. SLICE-LENGTH: 0 ;; Length of current slice. SLICE-TOTAL: 0 ;; Total of all amounts in the input data. ;; Using the SLICE-DATA, generate the DRAW-BLOCK. ;; Remeber, the slice length is an angle, so for each slice ;; we add its length to its start to get the start of the ;; next slice. We make two passes through the input. ;; The first pass adds up all the numbers so we can generate ;; the fractions for each slice. SLICE-TOTAL: 0 foreach [AMOUNT COLOR] SLICE-DATA [ SLICE-TOTAL: SLICE-TOTAL + AMOUNT ] SLICE-START: START-ANGLE foreach [AMOUNT COLOR] SLICE-DATA [ SLICE-LENGTH: (AMOUNT / SLICE-TOTAL) * 360 append DRAW-BLOCK reduce [ 'fill-pen COLOR 'arc PIE-CENTER PIE-RADIUS SLICE-START SLICE-LENGTH 'closed ] SLICE-START: SLICE-START + SLICE-LENGTH ] PIECHART: layout [ CHART-BOX: box BOX-SIZE white effect [draw DRAW-BLOCK] ] save/png PIECHART-FILENAME to-image CHART-BOX ] ;; -- Uncomment to test ;GEN-PIECHART [25 'red 50 'green 10 'blue] %piechart.png