Search code examples
phpcakephp-2.0jpgraph

cakephp 2.0 jpgraph


I have had a difficult time getting jpgraph to work with cakephp. I have a Controller called "Graphs" and all it does is display the view. View/Graphs/index.ctp is very simple:

echo "This is an image of my report";
echo "<img src='/<projectbase>/reports/index'></img>";

which I believe tries to get the information from the ReportsController and then its view called index. I then have a ReportsController:

<?php
class ReportsController extends AppController {
    var $name = 'Reports';
    function index() {
        $this->layout='ajax';
    }
}

which just calls the index view in Reports and this returns ajax information. I then have the View/Reports/index.ctp:

App::import('Vendor', 'jpgraph/jpgraph');
App::import('Vendor', 'jpgraph/jpgraph_line');

// Some data
$ydata = array(11,3,8,12,5,1,9,13,5,7);

// Create the graph. These two calls are always required
$graph = new Graph(350,250);
$graph->SetScale('textlin');

// Create the linear plot
$lineplot=new LinePlot($ydata);
$lineplot->SetColor('blue');

// Add the plot to the graph
$graph->Add($lineplot);

// Display the graph
$graph->Stroke();

Now based on this link the View/Graphs/index.ctp has an image link that calls the View/Reports/index.ctp and tells it to return the jpgraph that I want. When I run this code, I get an error "Resource interpreted as Image but transferred with MIME type text/html". If I go to the link directly (localhost//reports/index) it spits out a lot of funky characters, and PNG is near the beginning. I believe this is binary that was generated from the jpgraph stuff so I believe SOMETHING is being generated but it isnt being rendered correctly, nor brought into the View/Graps/index.ctp correctly.

I feel like unless I am missing something really small, I stole this essentially verbatim from the link in the question so its annoying it isnt working. Am I missing something? Is there an easier way to plot in cakephp?

My theory on this is that there is something weird about how I am grabbing the data from the view and also how the App::Vendor() call is working in cake php. When I tell an image to look outside the cakephp structure for the jpgraph it generates it with no problem:

echo "<img src='/jpgraph/Examples/example0.php'></img>";

and when i go to this page directly it is able to generate the graph with no problem.

Thanks for the help!


Solution

  • Alright I believe I have come to a hack solution for using jpgraph. The problem is with how it is streamed. What I do is I have my Graphs Controller below:

    <?php
    class GraphsController extends AppController {
    var $name = 'Graphs';
    
    function index() {
        // call Reports view to generate new graph
        //$var = ClassRegistry::init('Reports')->index();
        //$this->set(compact('var'));
        $this->generateGraph();
    }
    
    /*
     * This function generates the grph to be displayed.  It is a little bit of a hack:
     * I save the image to a file, then in the index.ctp I extract that image.  For now,
     * that is the only way I can get jpgraph to work.
     */
    function generateGraph() {
        App::import('Vendor', 'jpgraph/jpgraph');
        App::import('Vendor', 'jpgraph/jpgraph_line');
    
        // Some data
        $ydata = array(11,3,8,12,5,1,9,13,5,7);
    
        // Create the graph. These two calls are always required
        $graph = new Graph(350,250);
        $graph->SetScale('textlin');
    
        // Create the linear plot
        $lineplot=new LinePlot($ydata);
        $lineplot->SetColor('blue');
    
        // Add the plot to the graph
        $graph->Add($lineplot);
    
        // Get the handler to prevent the library from sending the
        // image to the browser
        $gdImgHandler = $graph->Stroke(_IMG_HANDLER);
    
        // Stroke image to a file
    
        // Default is PNG so use ".png" as suffix
        $fileName = "imagefile.png";
        $graph->img->Stream($fileName);
    
        // Send it back to browser
        //$graph->img->Headers();
        //$graph->img->Stream();
    }
    }
    

    Where I call the Graphs index function which then calls the View/Graphs/index.ctp. In the controller above I call a function generateGraph() which does exactly that and stores the image to a file in app/webroot. Then I have the View/Graphs/index.ctp below:

    <?php
    echo "<img src='imagefile.png'></img>";
    ?>
    

    which looks in the app/webroot directory for the image I just generated. I know this is a hack and if anyone knows how to do this more gracefully, I am willing to try that when I get some extra time!