Home  >  

3D Charts Using PaperVision3D

Author photo
AddThis Social Bookmark Button
I haven't touched PaperVision3D in a while, and some of the recent articles here on insideria.com motivated me to dive in and take a look around. Here's what I came up with after sitting down with it for an evening...

I'm always looking for interesting ways to visualize data, and have built some interesting 3D charting using PaperVision3D in the past. Now, its time to dive in using the latest "Great White" build of PaperVision3D, which has some interesting new features.

One of the features in "GreatWhite" that intrigued me the most is the new Line3D class. You can use Line3D to draw lines in a three dimensional space. This enables a lot with respect to data visualization. You can use the three dimensional lines to create interactive 3d charting, modeling, or graphing components.

This example shows a really basic rotating 3D chart. There are two important things that it shows.

1) A three dimensional scatter plot.
2) A three dimensional line chart


The data points between the scatter plot and line chart are exactly the same. The combined effect is a 3D scatter plot with lines connecting each data point.

Here's the example:



The first thing this example does is setup the axes:
The x axis is red. The y axis green. The z axis is blue.

The next thing that it to does is setup the lines container and randomly add the data points. This could be changed to be dynamic based on collections, or specified through a public getter/setter, but for this example its just random. Perhaps in a later blog post I'll elaborate on it further. For each data point, it adds a sphere object, and a line3D object. The line3D objects will connect the sphere.

Once all of the data objects and 3d structures are setup, it enters a rendering cycle based on "enterframe" events. On every frame instance, it will rotate the chart around the y axis, and redraw the chart "scene".

And here's the code that makes it work:
 
package  
{
  
   import flash.events.Event;
   
   import org.papervision3d.core.geom.Lines3D;
   import org.papervision3d.core.geom.renderables.Line3D;
   import org.papervision3d.core.geom.renderables.Vertex3D;
   import org.papervision3d.materials.ColorMaterial;
   import org.papervision3d.materials.special.LineMaterial;
   import org.papervision3d.objects.DisplayObject3D;
   import org.papervision3d.objects.primitives.Sphere;
   import org.papervision3d.view.BasicView;
  
    [SWF(backgroundColor="#000000",width="425",height="350")]
   public class Line3DChart extends BasicView 
   {
      public var chartContainer:DisplayObject3D;
      public var chart:DisplayObject3D;
      private var dataPoints : Array;
         
       private static const RADIUS : int = 20;
       private static const MAX_SIZE : int = 600; 
       private static const AXIS_SIZE : int = 800; 
   
      public function Line3DChart()
      {
         super(stage.stageWidth, stage.stageHeight, false, true);
         init(); 
       }
   
      private function init():void
      {
    
         chartContainer = new DisplayObject3D("Chart Container");
         chart = new DisplayObject3D("Chart");
         
         chartContainer.rotationY=-15;
         chartContainer.rotationX=-15;
         dataPoints = new Array(); 
    
          var defaultMaterial : LineMaterial = new LineMaterial(0xFFFFFF, .1);
          var xAxisMaterial : LineMaterial = new LineMaterial( 0xFF0000, .75 );
          var yAxisMaterial : LineMaterial = new LineMaterial( 0x00FF00, .75 );
          var zAxisMaterial : LineMaterial = new LineMaterial( 0x0000FF, .75 );
          var dataMaterial : ColorMaterial = new ColorMaterial( 0xFFFFFF, .65, false );
        
          var axes : Lines3D = new Lines3D( defaultMaterial, "Axes" );
          axes.addLine( new Line3D( axes, xAxisMaterial, 2, new Vertex3D( -AXIS_SIZE,0,0 ), new Vertex3D( AXIS_SIZE,0,0 ) ));
          axes.addLine( new Line3D( axes, yAxisMaterial, 2, new Vertex3D( 0,-AXIS_SIZE,0 ), new Vertex3D( 0,AXIS_SIZE,0 ) ));
          axes.addLine( new Line3D( axes, zAxisMaterial, 2, new Vertex3D( 0,0,-AXIS_SIZE ), new Vertex3D( 0,0,AXIS_SIZE ) ));
          
          var lines : Lines3D = new Lines3D( defaultMaterial, "Lines" );
          
          chart.addChild( axes );
          chart.addChild( lines );
          
          var lastVertex : Vertex3D;
          var currentVertex : Vertex3D = new Vertex3D();
          
         for(var i:int = 0; i<50; i++)
         {
            lastVertex = currentVertex;
            currentVertex = new Vertex3D();
            
            currentVertex.x = Math.random() * MAX_SIZE * positiveOrNegative();
            currentVertex.y = Math.random() * MAX_SIZE * positiveOrNegative();
            currentVertex.z = Math.random() * MAX_SIZE * positiveOrNegative();
            
            var point : Sphere = new Sphere( dataMaterial, RADIUS );
            point.x = currentVertex.x;
            point.y = currentVertex.y;
            point.z = currentVertex.z;
            
            chart.addChild( point ); 
            
            var line : Line3D = new Line3D( lines, defaultMaterial, 3, lastVertex, currentVertex );
            lines.addLine( line );
          }
    
          chartContainer.addChild(chart);
         scene.addChild(chartContainer); 
    
         singleRender(); 
    
         addEventListener(Event.ENTER_FRAME, onEnterFrame); 
       }
   
      private function onEnterFrame(e:Event): void 
      {
         chart.rotationY+=1; 
         singleRender(); 
       }
      
      private function positiveOrNegative() : int
      {
         var seed : Number = Math.random() * 100;
         if ( seed > 50 )
           return 1;
         else 
           return -1;
       }
    }
}

You can find more information on PaperVision 3D at:
PaperVision3D Blog
PaperVision3D Downloads
PaperVision3D Wiki
PaperVision3D Forums

You can view this application in a new window at:
http://www.tricedesigns.com/portfolio/pv3dchart/Line3DChart.html

You can view the source at:
http://www.tricedesigns.com/portfolio/pv3dchart/srcview/

Update:
Here's a better example of what can be done with this. I just changed the random placement to be programmatic.



The only different is in the placement of the vertices:
 
currentVertex.x = i;
currentVertex.y = Math.cos( i )* i;
currentVertex.z = Math.sin( i )* i;


___________________________________
Andrew Trice
Principal Architect
Cynergy Systems http://www.cynergysystems.com

Read more from Andrew Trice. Andrew Trice's Atom feed

Comments

10 Comments

ajitpal said:

well its really a nice example... to start with charting in 3d.. thax for such anice example..... i have one problem.. .could you tell me how to add different images tp same sphere

Andrew Trice said:

Here's a post showing actual application of the concepts in this blog post, with live data: http://www.cynergysystems.com/blogs/page/andrewtrice?entry=visualizing_data_in_multiple_dimensions

Hi Andrew,

I was looking your implementation, the link that you post above, and something came to my mind.

In this examples are you using flex chart class to calculate the positions of the 3d objects ?

Thanks,

Andrew Trice said:

No, it is calculating the vertex coordinates on its own. They are the same data values, so the will have the same shape, but the actual layout and rendering is completely separate.

raj said:

Hi,
I am new bee into world of actionscript.
Can you please tell me how to integrate this example in a mxml project?

Jeff said:

I'm looking at doing something like this on a larger scale. Any thoughts to the amount of objects (nodes) that could be handled by PaperVision? 100,000 or more... I'm currently using Partiview, but am looking at alternatives. OpenSceneGraph was one... and PaperVision3d looks like it could be another and perhaps the easiest to work with.

Jaibabu said:

Hi,

I am trying to implement 3d chart for the OLAP Cube Data in Flex. Is it possible todo it in PaperVision3D. If yes please provide me some details and samples.

Thanks

Is the distortion of circular objects at the edge of your chart a result of camera depth of field? Seems like PV3d does it to everything.
If you increase the camera distance and the zoom, you might get a bit less distortion.

I wonder if similar or better results could be obtained with simple 3d transforms in actionscript, rather than this more complex approach.

I have a simple javascript planet simulation which uses flat images with 3d transforms. I am still not impressed with the speed or compatibility with older browsers of cs4 and flash10.

Raghvender said:

It looks very good...Could you please help me how can we draw 3d pie chart?

britt said:

Did you ever make the source for your other examples available.

http://www.cynergysystems.com/blogs/page/andrewtrice?entry=visualizing_data_in_multiple_dimensions

I am starting to think about how to build a cluster chart in Flex and your examples would be helpful.

Leave a comment


Tag Cloud

Question of the Week: Open Source Flex Projects

What would you say are the 5 most prominent open source projects in the Flex world?

Answer

Latest Features

Recommended for You

@InsideRIA on Twitter

Archives

  • Or, visit our complete archive.  

About This Site

Welcome to the premiere community site for all things RIA sponsored by O'Reilly Media and Adobe Systems Incorporated.