Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Plotting Utility #170

Open
wants to merge 59 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
37f3a54
Added Canvas class
jakobsandberg Oct 9, 2016
98e5ffe
Added constructor and parameter visibility
jakobsandberg Oct 9, 2016
fdb8063
Added addPlot() method
jakobsandberg Oct 9, 2016
356bcd3
Added Plot class
jakobsandberg Oct 9, 2016
d6b3bca
Added basic draw() method
jakobsandberg Oct 9, 2016
6208f65
Added constructor to Plot and method visibility
jakobsandberg Oct 9, 2016
63fee35
Added setPadding() method to Plot
jakobsandberg Oct 9, 2016
2338c4b
Added save() method to Canvas
jakobsandberg Oct 9, 2016
acf8b41
Added comments to map out development of Plot class
jakobsandberg Oct 9, 2016
f8c1253
Added convenience variables for canvas/plot measures
jakobsandberg Oct 9, 2016
4bd2b00
Added rectangle for plot axes
jakobsandberg Oct 9, 2016
19d52db
Defined input function and function domain
jakobsandberg Oct 9, 2016
d3b765c
Calculated graph step size and function step size
jakobsandberg Oct 9, 2016
1bc8e41
Calculate function values, min, max, and function scale
jakobsandberg Oct 9, 2016
ff51fd2
Draw y-axis values and dashes
jakobsandberg Oct 9, 2016
f4f8e95
Draw x-axis values and grid
jakobsandberg Oct 9, 2016
c387295
Draw x-axis values and grid
jakobsandberg Oct 9, 2016
aab8930
Added section to fetch object parameters
jakobsandberg Oct 9, 2016
3853e6a
Draw graph
jakobsandberg Oct 9, 2016
47f19a2
Moved padding to Plot class, removed canvas size from draw method
jakobsandberg Oct 9, 2016
fd79f1b
Added grid() method
jakobsandberg Oct 10, 2016
16e9194
Added yLabel() method
jakobsandberg Oct 10, 2016
48fb58b
Added xLabel() method
jakobsandberg Oct 10, 2016
97a5661
Added title() method
jakobsandberg Oct 10, 2016
b92dbcb
Added color() method to Plot
jakobsandberg Oct 10, 2016
2b146bf
Refactored Plot to use imagestring instead of imagefttext
jakobsandberg Oct 10, 2016
462ad3a
Centered axis points
jakobsandberg Oct 10, 2016
b2b95e1
Centered title and axis labels
jakobsandberg Oct 10, 2016
5d68ad4
Centered title and axis labels
jakobsandberg Oct 10, 2016
ac00cd5
Added class description for Plots
jakobsandberg Oct 10, 2016
7288859
Added class description for Plots
jakobsandberg Oct 10, 2016
17a7f66
Added canvas width and height into new Plot() class within addPlot
jakobsandberg Oct 10, 2016
0803a19
Added parent classes width and height into constructor
jakobsandberg Oct 10, 2016
e6fdca9
Added parent classes width and height into constructor
jakobsandberg Oct 10, 2016
9c2b063
Updated default canvas size to 700 x 500
jakobsandberg Oct 10, 2016
9e1b298
Add method descriptions to Canvas class
jakobsandberg Oct 13, 2016
ea6639e
Add description to Canvas Class
jakobsandberg Oct 13, 2016
2a5aabf
Added description to Plot class
jakobsandberg Oct 13, 2016
13ae056
Added type checking for method outputs in Canvas class
jakobsandberg Oct 13, 2016
4a3d3fa
Added exception if input in draw() is not a GD resource
jakobsandberg Oct 13, 2016
d8d9a0b
Added method descriptions for Plot class
jakobsandberg Oct 13, 2016
c28cde5
Added xRange() method to Plot class
jakobsandberg Oct 13, 2016
c56feb7
Added conditional statements and exception to validate start and end …
jakobsandberg Oct 13, 2016
e6683f3
Moved the interval validation as a sharable component in the Canvas c…
jakobsandberg Oct 13, 2016
6ee3bff
Added Exception to grid() method if either grid line count is negative
jakobsandberg Oct 13, 2016
77a5d37
Added validateSize() method to Canvas
jakobsandberg Oct 13, 2016
81e9fef
Added Exception if input is negative
jakobsandberg Oct 13, 2016
f41612a
Added test for Plots class
jakobsandberg Oct 13, 2016
df279f4
Added test to Plots for validateSize() exceptions
jakobsandberg Oct 13, 2016
f5143e2
Added test to Canvas for validateInterval() Exceptions
jakobsandberg Oct 13, 2016
8635ec5
Added additional tests for validateSize() exceptions
jakobsandberg Oct 13, 2016
c120d76
Split exception tests so there is only one exception in each
jakobsandberg Oct 13, 2016
2942c97
Added test for Plot Class
jakobsandberg Oct 13, 2016
62e4513
Added test for grid exception
jakobsandberg Oct 13, 2016
b7acb7d
Added test for thickness exception
jakobsandberg Oct 13, 2016
60795b2
Added test for Plot() Exception
jakobsandberg Oct 13, 2016
96e3a0e
Added catch to ensure is a resource before checking its type
jakobsandberg Oct 13, 2016
2206166
PSR
jakobsandberg Oct 13, 2016
3e1bba4
Added catch if GD extension is not loaded
jakobsandberg Oct 13, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions src/Plots/Canvas.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<?php

namespace MathPHP\Plots;

/**
* Plotting Canvas
*
* The base class for the plotting utility.
*
* This is the parent class for our plotting utility. To create a plot image,
* you first start with this class to build the foundation for our plot. This
* will create an environment for which you can add a single plot or, in the
* future, multiple plots.
*
* This class currently supports the following methods:
* - addPlot(): add a single plot objects (graphs) to our canvas
* - size(): adjust the size of our canvas
* - save(): draw the current
*
* Example: Plot the graph f(x) = x over [0, 100]
* $canvas = new Canvas(1000, 500);
* $canvas->addPlot(function ($x) { return $x; }, 0, 100);
* $canvas->save();
*
*/
class Canvas
{
protected $width;
protected $height;
private $plot;

/**
* Construct a new plotting canvas.
*
* The input arguments refer to the size of the canvas in pixels. Thus,
* when you run the save() method, the size of the resulting image file
* will be determined by these parameters. For example, running
* (new Canvas())->save() will produce an image with a default size of
* 700px by 500px.
*
* @param int $width The width of our canvas, in pixels
* @param int $height The height of our canvas, in pixels
*/
public function __construct(int $width = 700, int $height = 500)
{
if (!extension_loaded('gd')) {
if (!dl('gd.so')) {
echo "GD extension is not installed/loaded. Ensure it is setup
property and then try again";
exit;
}
}

$this->validateSize($width, $height);

$this->width = $width;
$this->height = $height;
}

/**
* Add a single plot to our canvas object.
*
* This method is used when we are including a single plot in a canvas
* object. To add multiple plots to a single canvas, use the addSubplot()
* method (to be added in a future release).
*
* The default interval of our plot is [0, 10].
*
* @param callable $function The callback function we are plotting
* @param number $start The start of our plotting interval
* @param number $end The end of the plotting interval
*
* @return object The resulting Plot object constructed from our inputs
* and the parameters of the parent canvas object
*/
public function addPlot(callable $function, $start = 0, $end = 10): Plot
{
$width = $this->width;
$height = $this->height;

list($start, $end) = $this->validateInterval($start, $end);
$this->plot = new Plot($function, $start, $end, $width, $height);

return $this->plot;
}

/**
* Modify the size of our canvas.
*
* Refer to the __construct() method for for further understanding of
* canvas sizes.
*
* @param int $width The width of our canvas, in pixels
* @param int $height The height of our canvas, in pixels
*/
public function size(int $width, int $height)
{
$this->validateSize($width, $height);

$this->width = $width;
$this->height = $height;

// If we've already added a plot to the canvas, adjust it's size as well
if (isset($this->plot)) {
$this->plot->size($width, $height);
}
}

/**
* Draw plot(s) and output resulting canvas.
*
* Draw the plot object(s) stored within our canvas' plot parameter. Then,
* output the resulting canvas in a certain format. Currently, only
* JPG outputs are supported. More support should be added soon, such as
* outputting directly to a webpage, different file formats, etc.
*
* By default, this gives our canvas a white background.
*/
public function save()
{
header('Content-type: image/png');

$canvas = imagecreate($this->width, $this->height);
imagecolorallocate($canvas, 255, 255, 255);

if (isset($this->plot)) {
$canvas = $this->plot->draw($canvas);
}

imagejpeg($canvas, 'image-' . rand() . '.jpg');
}

/**
* Validate the input size of our canvus
*
* @throws Exception if $width or $height is negative
*/
public function validateSize(int $width, int $height)
{
if ($width < 0 || $height < 0) {
throw new \Exception("Canvas dimensions cannot be negative");
}
}

/**
* Valide that our input is a proper interval (not just a point).
*
* If the start point is greater than the input, swap the variables.
*
* @throws Exception if $start = $end (not an interval, just a point)
*/
public function validateInterval(int $start, int $end)
{
if ($start === $end) {
throw new \Exception("Start and end points the interval of our
graph cannot be the same. Your current input
would produce a graph over the interval
[{$start}, {$end}], which is just a single
point");
}

// Swap variables if start point is greater than end point
if ($start > $end) {
list($start, $end) = [$end, $start];
}

return [$start, $end];
}
}
Loading