Hi,

Here's the thing. I have to build a reporting module for an app. This module will have several reports (so each report will have specific data). A report will consist of charted representation of the data, and a html representation of the data. Needless to say I want to query the database only once for each report. The query in each report can be filtered (by periods of time or whatever) from user input. The problem is that each chart in a certain report can be represented in more than one way (pie, bar, etc) also from user input and I can figure out a proper way to achieve this goal. In my current design if I code common characteristics in the concrete ChartType classes (BarChart, PieChart) and I want to overwrite some of these characteristics in a concrete Chart class I cannot switch dynamically between classes because I may need to overwrite a Bar specific property that is not available in Pie. I hope I'm making some sense here (you will find an example at the end of the post)
Here what I got so far

PHP Code:
class Chart {
      
      var 
$ctype;
      var 
$fetcher;
      var 
$gwidth 400;
      var 
$gheight 300;
      var 
$gscale 'textlin';
      
      function 
Chart( &$fetcher ) {
          
$this->fetcher =& $fetcher;
          
$this->ctype =& ChartType::getChartType$this );
      }
      
      function 
buildChart() {
          
$data $this->formatData$this->fetcher->getRawData() );
          
$graph =& $this->graph();
          
$this->addGraphFeatures$graph$data );
          
$plots =& $this->createPlots$data );
          
$this->addPlotsFeatures$plots );
          
$this->finalizePlots$graph$plots );
          
$this->render$graph );
      }
      
      function 
formatData$rawdata ) {}
      
      function &
graph() {
          
$graph =& $this->ctype->createGraph$this->gwidth$this->gheight );
          return 
$graph;
      }
      
      function 
addGraphFeatures( &$graph$data ) {
          return;
      }
      
      function &
createPlots$data ) {
          
$plot =& $this->ctype->createPlots$data );
          return 
$plot;        
      }
      
      function 
addPlotsFeatures( &$plots ) {
          return;    
      }
      
      function 
finalizePlots( &$graph, &$plots ) {
          
$graph->Add$plots );    
      }
  
      function 
render( &$graph ) {
          
$graph->Stroke();    
      }
      
  }
  
  class 
ChartType {
      
      var 
$chart;
      var 
$conf;
      
      function 
ChartType( &$chart ) {
          
$this->chart =& $chart;
          
$this->conf =& $this->chart->fetcher->registry->get('conf');
          require_once(
$this->conf->getConf('jpgraphPath') . '/jpgraph.php');
      }
      
      function &
createGraph$width$height$params 'auto' ) {}
      
      function &
createPlots$data ) {}
      
      function &
getChartType( &$chart ) {
          
$ctype =& new BarChart$chart );
          
$req =& $chart->fetcher->registry->get('req');
          if (
$req->isValid'ctype' ) && $req->getProperty'ctype' ) == 'pie') {
              
$ctype =& new PieChart$chart );
          }
          return 
$ctype;
      }
  }
  
  class 
PieChart extends ChartType {
      
      function 
PieChart( &$chart ) {
          
parent::ChartType$chart );
          require_once(
$this->conf->getConf('jpgraphPath') . '/jpgraph_pie.php');
          require_once(
$this->conf->getConf('jpgraphPath') . '/jpgraph_pie3d.php');
      }
      
      function &
createGraph$width$height ) {
          
$graph =& new PieGraph$width$height );
          return 
$graph;
      }
      
      function &
createPlots$data ) {
          
$plot =& new PiePlot3D$data );
          return 
$plot;
      }
      
  }
  
  class 
BarChart extends ChartType {
      
      function 
BarChart( &$chart ) {
          
parent::ChartType$chart );
          require_once(
$this->conf->getConf('jpgraphPath') . '/jpgraph_bar.php');
      }
      
      function &
createGraph$width$height ) {
          
$graph =& new Graph$width$height'auto' );
          return 
$graph;
      }
      
      function &
createPlots$data ) {
          
$plot =& new BarPlot$data );
          return 
$plot;
      }
      
  } 
Most of design for the Chart class was inspired from this post (thanks again to Jason Sweat).


Concrete Chart class problem:

PHP Code:
class IncidentsByProduct extends Chart {
      
      function 
formatData$rawdata ) {
          
//format the data in some way   
      
}
      
      function 
addGraphFeatures( &$graph ) {
          
//xaxis is a property for Bar charts it does not exists in Pie charts
          //so if I want to represent this chart as a Pie chart (based on what a      //user chooses) I will get an error
          
$graph->xaxis->title->Set('some title');    
      }
  } 
Any advice would be much appreciated