Jump to content

Graph Problem


johnnybenimble

Recommended Posts

Hi everyone,

 

Newish to PHP and I'm sure this is a simple thing but I was hoping someone could help me out.

 

I have a php file that draws a graph for me (it takes in the coordinates from a text file). What I want to do is insert a red line at the top of the graph (not from start to finish, but starting at a certain point in the graph and finishing at another point).

 

This php code achieves the line I would like to insert into the graph:

<?php
$canvas = imagecreatetruecolor(1000, 10);

// Allocate colors
$red = imagecolorallocate($canvas, 255, 0, 0);

ImageFilledRectangle($canvas, 0, 0, 1000, 10, $red);


// Output and free from memory
header('Content-Type: image/jpeg');

imagejpeg($canvas);
imagedestroy($canvas);
?>

 

I need to insert this into this php script:

<?php
$width = 1000; //width and height of the resulting image
$height = 230;

$drawLastLine = false; //draw 9th line or not
$testMode = false; //render only 10 images



//returns directory with cached images by name of text file
function getCacheDirectory($fname)
{
    $mod = filemtime($fname);
    $dirname = "cache/" . $fname . "." . $mod . "/";
    return $dirname;
}

//checks if specified txt file is cached
function isCached($fname)
{
    $dirname = getCacheDirectory($fname);
    return file_exists($dirname);
}

//calculated y-coordinates of base-lines for all 9 lines, returns an array
function initStart($height, $number = 9)
{
    $d = $number + 1;
    $t = $height / $d;
    $res = array();
    $c = 0;
    for ($i = 0; $i < $number; $i++)
    {
        $c += $t;
        $res[$i] = $c;
    }
    return $res;
}


//draws vertical grey line with specified coordinate
function drawVerticalLine($img, $x)
{
    $grey = imagecolorallocate($img, 80, 80, 80);
    $h = imagesy($img);
    imagesetthickness($img, 3);
    imageline($img, $x, 0, $x, $h, $grey);
    imagesetthickness($img, 0.1);
}

//cuts unfilled part of image in the right, making its width equal to $realW
function cutRight($img, $realW)
{
    $h = imagesy($img);
    $new = imagecreatetruecolor($realW, $h);
    imagecopy($new, $img, 0, 0, 0, 0, $realW, $h);
    return $new;
}

//makes up an array of required colors
function allocateColors($img)
{
    $result = array();
    $result['blue'] = imagecolorallocate($img, 0, 0, 255);
    $result['red'] = imagecolorallocate($img, 255, 0, 0);
    $result['black'] = imagecolorallocate($img, 0, 0, 0);
    $result['white'] = imagecolorallocate($img, 255, 255, 241);
    return $result;
}

//main function which generates all the images
function generateImages($fname)
{
    
    set_time_limit(0); //there's no time limit, because it's long process
    global $width, $height, $start, $testMode, $drawLastLine;
    
    $lines = 9;
    $start = initStart($height, $drawLastLine ? $lines : $lines - 1);

    //colors of line from top bo bottom
    $lineCol = array('blue', 'blue', 'red', 'red', 'blue', 'blue', 'black', 'red', 'red');
    
    $fp = fopen($fname, "r"); //we open our file with data
    $header = fgets($fp);

    $curX = 0;
    $sumX = 0;
    $imgNum = 1;

    $colors = false;
    $const = 1.0; //that's the constant which can be used to multiply by y-coordinates, i.e. making our graphs scalable by y-coordinate

    $prevY = array();
    for ($i = 0; $i < $lines; $i++)
    {
        $prevY[$i] = 0;
    }

    $dir = getCacheDirectory($fname);
    mkdir($dir);
    $img = false;

  //  $maximumImages = 10;

    //if we are testing, we will do just 10 images, else we will work until the file ends
    while ((!$testMode || ($testMode && $imgNum < $maximumImages)) && $line = fgets($fp))
    {
        //if it's time to make up a new image
        if ($sumX % $width == 0)
        {
            //we save old one to file
            if ($img)
            {
                imagegif($img, $dir . $imgNum . ".gif");
                $imgNum++;
            }
            //and create a new one, along with allocating colors and so on
            $img = imagecreatetruecolor($width, $height);
            $colors = allocateColors($img);
            imagefill($img, 0, 0, $colors['white']);
            $curX = 0;
        }
        $data = explode(",", $line);
        $time = array_shift($data);

        $linesCount = $drawLastLine ? $lines : $lines - 1;
        //we loop through our lines
        for ($i = 0; $i < $linesCount; $i++)
        {
            
            $ly = $data[$i] * $const; //it's the new Y coordinate, and we counts from baseline with y = 0
            $realTo = $start[$i] + $ly; //now we count the baseline too

            $realFrom = $start[$i] + $prevY[$i]; //that's the previous step's y-coordinate
            $prevY[$i] = $ly; //we remember current coordinate to draw line on next step

            $x1 = $curX - 1;
            $y1 = $realFrom;
            $x2 = $curX;
            $y2 = $realTo;
            //we draw line finally with needed color
            imageline($img, $x1, $y1, $x2, $y2, $colors[$lineCol[$i]]);
        }

        //if the time looks like 235.000000, we need to draw vertical line
        if (round($time) == $time)
        {
            drawVerticalLine($img, $curX);
        }

        //we increase both curX (which is used for drawing) and overall x (it indicates how much lines we've processed)
        $curX++;
        $sumX++;

    }

    // if we didn't save all lines to .gifs, we need to save leftovers
    if ($curX > 0)
    {
        $img = cutRight($img, $curX);
        imagegif($img, $dir . $imgNum . ".gif");
        $imgNum++;
    }

    //saving numbers of pictures rendered
    file_put_contents($dir . "info.txt", ($imgNum - 1));

}

$fname = $_GET['file'];

//there should be no slashes in filename and it should end with .txt
if (strpos($fname, "/") !== false || strpos($fname, "\\") !== false || strpos($fname, ".txt") === false)
{
    echo "Security error!";
    die;
}

//it should exist
if (!file_exists($fname))
{
    echo "No such file!";
    die;
}

//if there are no images cached for our file, we need to generate them
if (!isCached($fname))
{
    generateImages($fname);
}

$page = 1;
$dirname = getCacheDirectory($fname);
$maxPages = file_get_contents($dirname . "info.txt");
//$maxPages = 10;
$uniqid = uniqid();
$img = $dirname . $page . ".gif?" . uniqid();

include("templates/show2.php.inc");

 

 

I'm just lost as to how I achive this line in the longer php script. I've tried creating my own function, and then calling it further down but this just breaks it. Any help is appreciated!!

Link to comment
Share on other sites

When you say "it breaks it" what exactly do you mean? What happens?

 

As in I get a server error and nothing at all displays.

 

I know it's probably just as simple as creating a function, and calling the function somewhere in the script, I'm just not sure where.

 

It would be helpful if you told us the type of error message you are receiving ;)

Link to comment
Share on other sites

Apologies. I played around with it an awful lot so I was getting a few different errors.

 

Sometimes it was an internal server error 500...

 

Then sometimes it was a mega long text error..but I know this was after I created the drawHorizontalLine function I wasn't including the correct parameters.

 

The code above for that actually draws the red line..would it be possible to include all that into a function e.g. function drawHorizontalLine...and then call it later on in the script?

Link to comment
Share on other sites

Apologies. I played around with it an awful lot so I was getting a few different errors.

 

Sometimes it was an internal server error 500...

 

Then sometimes it was a mega long text error..but I know this was after I created the drawHorizontalLine function I wasn't including the correct parameters.

 

The code above for that actually draws the red line..would it be possible to include all that into a function e.g. function drawHorizontalLine...and then call it later on in the script?

 

Yes. Just a suggestion though. I recommend that you do the image creating outside of the function. Make this be like a drawline function that takes, as an argument, a $canvas variable that already exists with your graph on it. Then the function will modify that canvas by adding the horizontal line. Then after your call to that function you will output the image.

Link to comment
Share on other sites

Hmm

 

I have tried this

 

function drawHorizontalLine($canvas)
{
// Create a 1000 x 10 image
$canvas = imagecreatetruecolor(1000, 10);

// Allocate colors
$red = imagecolorallocate($canvas, 255, 0, 0);

ImageFilledRectangle($canvas, 0, 0, 1000, 10, $red);


// Output and free from memory
header('Content-Type: image/jpeg');

imagejpeg($canvas);
imagedestroy($canvas);
}

 

And then further down in my script I have called drawHorizontalLine($canvas); But I get the 500- Internal Server Error. Is the function okay? I'm thinking it's just the way I'm calling it.

Link to comment
Share on other sites

Hmm

 

I have tried this

 

function drawHorizontalLine($canvas)
{
// Create a 1000 x 10 image
$canvas = imagecreatetruecolor(1000, 10);

// Allocate colors
$red = imagecolorallocate($canvas, 255, 0, 0);

ImageFilledRectangle($canvas, 0, 0, 1000, 10, $red);


// Output and free from memory
header('Content-Type: image/jpeg');

imagejpeg($canvas);
imagedestroy($canvas);
}

 

And then further down in my script I have called drawHorizontalLine($canvas); But I get the 500- Internal Server Error. Is the function okay? I'm thinking it's just the way I'm calling it.

 

Looks like you are still creating the image inside of the function. You should take the image creation outside of it. Also you need to pass a reference to the original canvas object to the function instead of creating a new instance. If you don't already know how to do reference variables then google it. There's lots of information. I believe PHP uses the & symbol to pass reference variables like most other languages :)

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.