UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on September 01, 2013, 09:13:58 AM

Title: Drawing A Pie Chart
Post by: kevin on September 01, 2013, 09:13:58 AM
  Drawing A Pie Chart

  Here's an example show a way to drawing a pie chart.  The first builds a direction table from 0 to 360 degrees.  When we render the chart we step through the 2D array of pixels and computes the direction between the middle of the graphic and the current point.   The angle is then used to grab the colour from the table so we can plot the segment colour.  Simple enough and gives a fairly reasonable result.  

  Another method is to use polygons to draw pie fragments, then mask the excess off the same way.


  GetAngle Version

[pbcode]

   // ------------------------------------------------------------------------
   // --[SETUP]----------------------------------------------------------------
   // ------------------------------------------------------------------------

   #include "blitimage"
   
   loadfont "veranda",1,28


   ; Create an image we'll be renderinb the chart on to   
   Image=NewImage(256,256,2)
   MaskImage=NewIMage(256,256,2)
   IMageMaskCOlour MaskIMage,$ff000000

   ; create a circle mask. This is used to shape the final
   ; chart image.  Saves having to compute the spans yourself
   rendertoimage MaskImage
   cls 0
   circlec 128,128,128,true,$ffffffff


   ; each direction (0 to 359) is mapped with a colour in that direction
   ; so the render loop just computes the angle between the current point
   ; and the middle of the chart.  Then it uses this angle to grab the
   ; the colour from this table..  
   Dim ColourDirection(360)

   Setfps 5


   // ------------------------------------------------------------------------
   // --[MAIN]----------------------------------------------------------------
   // ------------------------------------------------------------------------
   Do


      // Render the screen
      rendertoscreen
      cls $304050
   

      // randomly create the direction table and render the percentages
      
      // Each segement in the chart and be between 5 and 90 degrees.
      
      Segments=0
      Angle=0
      repeat
         SegmentSize=rndrange(5,90)

         ThisColour=RndRGB()            

         AngleEnd=cliprange(Angle+SegmentSize,0,360)

         SegmentSize=AngleEnd-Angle
      
         Info$="#"+digits$(Segments,2)+" = %"+str$(360.0/SegmentSize)
      
         Ypos1=100+GetTextHeight("|")*Segments
         Ypos2=100+GetTextHeight("|")*(Segments+1)
         
         Text 400,Ypos1,Info$      
         boxc 400,ypos1,400+(ypos2-ypos1),ypos2,true,ThisCOlour
      

         For lp=Angle to AngleEnd
               ColourDirection(lp)=ThisColour
         next      
         Angle=AngleEnd
         Segments++
      until Angle=>360
   

      rendertoimage Image
      Cx=128
      Cy=128
      lockbuffer      
      thispoint=Point(0,0)
      For ylp=0 to 255
         For xlp=0 to 255
               Angle=getangle2d(xlp,ylp,cx,cy)
               fastDot xlp,ylp,ColourDirection(Angle)
         next   
      next
      unlockbuffer      

      // mult the RGB values from the MASK image over the chart image   
      BlitImageAlphaMultImage(Image,0,0,MaskIMage)


      // set output to the screen
      rendertoscreen

      // draw the Pie chart
      drawimage image,100,100,true

      // draw a message under it
      centertext 100+GetImageWidth(Image)/2,100+GetIMageHeight(image)+10,"Pie Chart"
   
   
      Sync
   loop
      
[/pbcode]



  Polygon Version

[pbcode]


   // ------------------------------------------------------------------------
   // --[SETUP]----------------------------------------------------------------
   // ------------------------------------------------------------------------

   #include "blitimage"
   
   loadfont "veranda",1,28


   ; Create an image we'll be renderinb the chart on to   
   Image=NewImage(256,256,2)
   MaskImage=NewIMage(256,256,2)
   IMageMaskCOlour MaskIMage,$ff000000

   ; create a circle mask. This is used to shape the final
   ; chart image.  Saves having to compute the spans yourself
   rendertoimage MaskImage
   cls 0
   circlec 128,128,128,true,$ffffffff




   // ------------------------------------------------------------------------
   // --[SEGMENT LIST]--------------------------------------------------------
   // ------------------------------------------------------------------------

   Type SegmentInfo
         Size
         Colour   
   endtype

   Dim Segs(360) as segmentINfo

   Setfps 5


   // ------------------------------------------------------------------------
   // --[MAIN]----------------------------------------------------------------
   // ------------------------------------------------------------------------
   Do


      // Render the screen
      rendertoscreen
      cls $304050
   

      // randomly create the direction table and render the percentages
      
      // randomly make the chart so each segment in the is between 5 and 90 degrees.
      
      Segments=0
      Angle=0
      repeat
         SegmentSize   =rndrange(5,90)
         ThisColour   =RndRGB()            
         AngleEnd      =cliprange(Angle+SegmentSize,0,360)
         SegmentSize   =AngleEnd-Angle
      
         Segs(Segments).size=SegmentSize
         Segs(Segments).colour=ThisColour
         
         Info$="#"+digits$(Segments,2)+" = %"+str$(360.0/SegmentSize)
      
         Ypos1=100+GetTextHeight("|")*Segments
         Ypos2=100+GetTextHeight("|")*(Segments+1)
         
         Text 400,Ypos1,Info$      
         boxc 400,ypos1,400+(ypos2-ypos1),ypos2,true,ThisCOlour
      
         Angle=AngleEnd
      
         Segments++
      until Angle=>360
   

      rendertoimage Image
      lockbuffer      

         Angle=0
         x1=128+Cos(Angle)*300
         y1=128+Sin(Angle)*300
   
         For lp =0 to Segments
            
               Size         =Segs(lp).size
               ThisColour   =Segs(lp).colour

               Angle+=Size
               x2=128+Cos(Angle)*300
               y2=128+Sin(Angle)*300

               tric 128,128,x1,y1,x2,y2,ThisCOlour

               x1=x2
               y1=y2
         
         next
      unlockbuffer      

      // mult the RGB values from the MASK image over the chart image   
      BlitImageAlphaMultImage(Image,0,0,MaskIMage)

      // set output to the screen
      rendertoscreen

      // draw the Pie chart
      drawimage image,100,100,true

      // draw a message under it
      centertext 100+GetImageWidth(Image)/2,100+GetIMageHeight(image)+10,"Pie Chart"
   
      Sync
   loop
      
[/pbcode]



Related Articles:

     * Kaleidoscope (optimized) (http://www.underwaredesign.com/forums/index.php?topic=4111.0)