├── .gitignore ├── README.md ├── composer.json └── src └── SamChristy └── PieChart ├── PieChart.php ├── PieChartGD.php ├── PieChartImagick.php ├── documentation ├── 404.html ├── class-PieChart.html ├── class-PieChartColor.html ├── class-PieChartGD.html ├── class-PieChartImagick.html ├── class-SamChristy.PieChart.PieChart.html ├── class-SamChristy.PieChart.PieChartColor.html ├── class-SamChristy.PieChart.PieChartGD.html ├── class-SamChristy.PieChart.PieChartImagick.html ├── elementlist.js ├── function-imageSmoothArc.html ├── function-imageSmoothArcDrawSegment.html ├── index.html ├── namespace-SamChristy.PieChart.html ├── namespace-SamChristy.html ├── package-None.html ├── package-PieChart.html ├── resources │ ├── collapsed.png │ ├── combined.js │ ├── footer.png │ ├── inherit.png │ ├── resize.png │ ├── sort.png │ ├── style.css │ ├── tree-cleaner.png │ ├── tree-hasnext.png │ ├── tree-last.png │ └── tree-vertical.png ├── source-class-PieChart.html ├── source-class-PieChartColor.html ├── source-class-PieChartGD.html ├── source-class-PieChartImagick.html ├── source-class-SamChristy.PieChart.PieChart.html ├── source-class-SamChristy.PieChart.PieChartColor.html ├── source-class-SamChristy.PieChart.PieChartGD.html ├── source-class-SamChristy.PieChart.PieChartImagick.html ├── source-function-imageSmoothArc.html ├── source-function-imageSmoothArcDrawSegment.html └── tree.html ├── example ├── example.php └── example.png └── fonts ├── Open_Sans ├── LICENSE.txt ├── OpenSans-Bold.ttf ├── OpenSans-ExtraBold.ttf ├── OpenSans-Regular.ttf └── OpenSans-Semibold.ttf └── Oswald ├── OFL.txt ├── Oswald-Bold.ttf ├── Oswald-Light.ttf └── Oswald-Regular.ttf /.gitignore: -------------------------------------------------------------------------------- 1 | # OS generated files # 2 | ###################### 3 | .DS_Store 4 | .DS_Store? 5 | ._* 6 | .Spotlight-V100 7 | .Trashes 8 | Icon? 9 | ehthumbs.db 10 | Thumbs.db 11 | 12 | # Project & temporary files # 13 | ############################# 14 | *~ 15 | *.swp 16 | /tags 17 | /TAGS 18 | /cscope.* 19 | /.patches/ 20 | /.idea/ 21 | /nbproject/ 22 | CVS 23 | .DS_Store 24 | /.settings/ 25 | /.project 26 | /.buildpath 27 | /.cache -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PieChart 2 | ======== 3 | [![Latest Stable Version](https://poser.pugx.org/samchristy/piechart/v/stable)](https://packagist.org/packages/samchristy/piechart) [![License](https://poser.pugx.org/samchristy/piechart/license)](https://packagist.org/packages/samchristy/piechart) [![Total Downloads](https://poser.pugx.org/samchristy/piechart/downloads)](https://packagist.org/packages/samchristy/piechart) [![Monthly Downloads](https://poser.pugx.org/samchristy/piechart/d/monthly)](https://packagist.org/packages/samchristy/piechart) 4 | 5 | A reasonably efficient* class for drawing pie charts with ImageMagick or GD in PHP. Intended as a 6 | learning exercise for using the NetBeans IDE and the Xdebug profiler and debugger. The code is 7 | available under the [GNU GPL v3.0](http://www.gnu.org/licenses/gpl-3.0.html), so feel free to use it 8 | with attribution. I recommend using the Imagick version, `PieChartImagick` over the GD version, 9 | `PieChartGD`. 10 | 11 | ### Demonstration ### 12 | Below is the code required to generate a pie chart and echo it to the client's browser. The example 13 | uses the method `outputPNG()` to tell the browser to render the image. Alternatively, the function 14 | `forceDownloadPNG()` can be used to instruct the browser to bring up the save dialog. 15 | 16 | ### Documentation ### 17 | [View the documentation](http://samchristy.github.com/PieChart/documentation/index.html) 18 | (generated with [ApiGen](http://apigen.org/)). 19 | 20 | #### Installation #### 21 | [Use Composer](https://packagist.org/packages/samchristy/piechart)! 22 | 23 | #### Example Usage #### 24 | ````php 25 | setTitle('Browser Usage Statistics (January - April)'); 32 | // Method chaining coming soon! 33 | $chart->addSlice('Google Chrome', 27, '#4A7EBB'); 34 | $chart->addSlice('Mozilla Firefox', 23, '#DA8137'); 35 | $chart->addSlice('Apple Safari', 11, '#9BBB59'); 36 | $chart->addSlice('Opera', 3, '#BE4B48'); 37 | $chart->addSlice('Other', 5, '#7D60A0'); 38 | 39 | $chart->draw(); 40 | $chart->outputPNG(); 41 | ```` 42 | #### Output #### 43 | ![Pie Chart](src/SamChristy/PieChart/example/example.png) 44 | 45 | *This example took 150ms to execute on my laptop (i3-350M @ 2.27 GHz). 46 | 47 | © Sam Christy 2013 48 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "samchristy/piechart", 3 | "type": "library", 4 | "description": "A simple class for drawing pie charts with ImageMagick or GD in PHP.", 5 | "keywords": ["graphics", "pie", "chart"], 6 | "homepage": "https://github.com/SamChristy/PieChart", 7 | "license": "GPL-2.0+", 8 | "authors": [ 9 | { 10 | "name": "Sam Christy", 11 | "email": "sam_christy@hotmail.co.uk", 12 | "homepage": "https://github.com/SamChristy" 13 | } 14 | ], 15 | "require": { 16 | "php": ">=5.3.0" 17 | }, 18 | "autoload": { 19 | "psr-0": { "SamChristy\\PieChart\\": "src/" } 20 | } 21 | } -------------------------------------------------------------------------------- /src/SamChristy/PieChart/PieChart.php: -------------------------------------------------------------------------------- 1 | 9 | * @licence GNU GPL v3.0 10 | * @copyright © Sam Christy 2013 11 | * @package PieChart 12 | * @version v2.0.0 13 | */ 14 | abstract class PieChart { 15 | const FORMAT_GIF = 1; 16 | const FORMAT_JPEG = 2; 17 | const FORMAT_PNG = 3; 18 | const OUTPUT_DOWNLOAD = 1; 19 | const OUTPUT_INLINE = 2; 20 | const OUTPUT_SAVE = 3; 21 | 22 | protected $slices; 23 | protected $width; 24 | protected $height; 25 | protected $title; 26 | protected $hasLegend; 27 | protected $titleFont; 28 | protected $legendFont; 29 | protected $textColor; 30 | protected $backgroundColor; 31 | protected $canvas; 32 | protected $quality; 33 | 34 | /** 35 | * Constructs the PieChart. 36 | * @param int $width The width of the chart, in pixels. 37 | * @param int $height The chart's height, in pixels. 38 | * @param string [$title] The chart's title. 39 | * @param string|int|array [$textColor] The colour of the title and labels. 40 | * @param string|int|array [$backgroundColor] The color for the background. 41 | */ 42 | public function __construct($width = 0, $height = 0, $title = '', $textColor = 0x222222, 43 | $backgroundColor = 0xffffff) { 44 | $this->width = $width; 45 | $this->height = $height; 46 | $this->title = $title; 47 | $this->hasLegend = true; 48 | $this->slices = array(); 49 | $this->quality = 100; 50 | $this->textColor = new PieChartColor($textColor); 51 | $this->backgroundColor = new PieChartColor($backgroundColor); 52 | $this->titleFont = __DIR__ . '/fonts/Open_Sans/OpenSans-Semibold.ttf'; 53 | $this->legendFont = __DIR__ . '/fonts/Open_Sans/OpenSans-Regular.ttf'; 54 | } 55 | 56 | /** 57 | * Frees the memory that was allocated to the image. Use this function to 58 | * clean up after your pie chart when you're finished with it. 59 | */ 60 | public function destroy() {} 61 | 62 | /** 63 | * Sets the title's text. To remove the title, set it to ''. 64 | * @param string $title 65 | * @param string [$titleFont] The name of the font file for the title. 66 | */ 67 | public function setTitle($title, $titleFont = NULL) { 68 | $this->title = $title; 69 | 70 | if($titleFont) 71 | $this->titleFont = $titleFont; 72 | } 73 | 74 | /** 75 | * Add or remove the chart's legend (it is displayed default). 76 | * @param bool $displayLegend Specify false to remove the legend or true to 77 | * add one. 78 | * @param string [$legendFont] The name of the font for the legend's text. 79 | */ 80 | public function setLegend($displayLegend, $legendFont = NULL) { 81 | $this->hasLegend = $displayLegend; 82 | 83 | if($legendFont) 84 | $this->legendFont = $legendFont; 85 | } 86 | 87 | /** 88 | * Set the quality for generating output in lossy formats. 89 | * @param int $quality An integer between 0 and 100 (inclusive). 90 | */ 91 | public function setOutputQuality($quality) { 92 | $this->quality = $quality; 93 | } 94 | 95 | /** 96 | * Adds a new slice to the pie chart. 97 | * @param string $name The name of the slice (used for legend label). 98 | * @param float $value 99 | * @param string|int|array $color The CSS colour, e.g. '#FFFFFF', 'rgb(255, 255, 255)'. 100 | */ 101 | public function addSlice($name, $value, $color) { 102 | $this->slices[$name] = array( 103 | 'value' => $value, 104 | 'color' => new PieChartColor($color) 105 | ); 106 | } 107 | 108 | /** 109 | * Removes the specified slice. 110 | * @param string $name The name of the slice to be removed. 111 | */ 112 | public function removeSlice($name) { 113 | unset($this->slices[$name]); 114 | } 115 | 116 | /** 117 | * Draws the chart so that it is ready for output. 118 | */ 119 | public function draw() {} 120 | 121 | /** 122 | * For child classes to override, so that the output functions work. 123 | * @param int $method 124 | * @param int $format 125 | * @param string $filename 126 | */ 127 | protected function _output($method, $format, $filename) {} 128 | 129 | /** 130 | * Echos the chart as a GIF and instructs the browser to display it inline. 131 | * @param string [$filename] The filename for the picture. 132 | * @return bool true if successful, false otherwise (implementation-dependent). 133 | */ 134 | public function outputGIF($filename = 'pie-chart.gif') { 135 | header('Content-Type: image/gif'); 136 | header("Content-Disposition: inline; filename=\"$filename\""); 137 | 138 | return $this->_output(self::OUTPUT_INLINE, self::FORMAT_GIF, $filename); 139 | } 140 | 141 | /** 142 | * Echos the chart as a JPEG and instructs the browser to display it inline. 143 | * @param string [$filename] The filename for the picture. 144 | * @return bool true if successful, false otherwise (implementation-dependent). 145 | */ 146 | public function outputJPEG($filename = 'pie-chart.jpg') { 147 | header('Content-Type: image/jpeg'); 148 | header("Content-Disposition: inline; filename=\"$filename\""); 149 | 150 | return $this->_output(self::OUTPUT_INLINE, self::FORMAT_JPEG, $filename); 151 | } 152 | 153 | /** 154 | * Echos the chart as a PNG and instructs the browser to display it inline. 155 | * @param string [$filename] The filename for the picture. 156 | * @return bool true if successful, false otherwise (implementation-dependent). 157 | */ 158 | public function outputPNG($filename = 'pie-chart.png') { 159 | header('Content-Type: image/png'); 160 | header("Content-Disposition: inline; filename=\"$filename\""); 161 | 162 | return $this->_output(self::OUTPUT_INLINE, self::FORMAT_PNG, $filename); 163 | } 164 | 165 | /** 166 | * Echos the chart as a GIF and instructs the browser to force the user to 167 | * save it. 168 | * @param string [$filename] The filename for the picture. 169 | * @return bool true if successful, false otherwise (implementation-dependent). 170 | */ 171 | public function forceDownloadGIF($filename = 'pie-chart.gif') { 172 | header("Pragma: public"); 173 | header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 174 | header('Content-Type: application/octet-stream'); 175 | header('Content-Disposition: attachment; filename="'.$filename.'"'); 176 | 177 | return $this->_output(self::OUTPUT_INLINE, self::FORMAT_GIF, $filename); 178 | } 179 | 180 | /** 181 | * Echos the chart as a JPEG and instructs the browser to force the user to 182 | * save it. 183 | * @param string [$filename] The filename for the picture. 184 | * @return bool true if successful, false otherwise (implementation-dependent). 185 | */ 186 | public function forceDownloadJPEG($filename = 'pie-chart.jpg') { 187 | header("Pragma: public"); 188 | header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 189 | header('Content-Type: application/octet-stream'); 190 | header('Content-Disposition: attachment; filename="'.$filename.'"'); 191 | 192 | return $this->_output(self::OUTPUT_INLINE, self::FORMAT_JPEG, $filename); 193 | } 194 | 195 | /** 196 | * Echos the chart as a PNG and instructs the browser to force the user to 197 | * save it. 198 | * @param string [$filename] The filename for the picture. 199 | * @return bool true if successful, false otherwise (implementation-dependent). 200 | */ 201 | public function forceDownloadPNG($filename = 'pie-chart.png') { 202 | header("Pragma: public"); 203 | header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 204 | header('Content-Type: application/octet-stream'); 205 | header('Content-Disposition: attachment; filename="'.$filename.'"'); 206 | 207 | return $this->_output(self::OUTPUT_DOWNLOAD, self::FORMAT_PNG, $filename); 208 | } 209 | 210 | /** 211 | * Saves the chart as a GIF, in the specified location. 212 | * @param string $filename 213 | * @return int true if successful, false otherwise (implementation-dependent).. 214 | */ 215 | public function saveGIF($filename) { 216 | return $this->_output(self::OUTPUT_SAVE, self::FORMAT_GIF, $filename); 217 | } 218 | 219 | /** 220 | * Saves the chart as a JPEG, in the specified location. 221 | * @param string $filename 222 | * @return int true if successful, false otherwise (implementation-dependent). 223 | */ 224 | public function saveJPEG($filename) { 225 | return $this->_output(self::OUTPUT_SAVE, self::FORMAT_JPEG, $filename); 226 | } 227 | 228 | /** 229 | * Saves the chart as a PNG, in the specified location. 230 | * @param string $filename 231 | * @return int true if successful, false otherwise (implementation-dependent). 232 | */ 233 | public function savePNG($filename) { 234 | return $this->_output(self::OUTPUT_SAVE, self::FORMAT_PNG, $filename); 235 | } 236 | } 237 | 238 | /** 239 | * Utility class for storing colours in a library-agnostic format. 240 | * @package PieChart 241 | */ 242 | class PieChartColor { 243 | public $r; 244 | public $g; 245 | public $b; 246 | 247 | /** 248 | * Sets the colour using {@link setColor()}, if an argument is provided. 249 | * @param array|int|string [$color] 250 | */ 251 | public function __construct($color = NULL) { 252 | if (!is_null($color)) { 253 | $this->setColor($color); 254 | } 255 | } 256 | 257 | /** 258 | * Sets the colour, using one of the following formats: '#FFFFFF', '#fff', 259 | * 'rgb(255, 255, 255)', [$r, $g, $b] or ARGB 260 | * ({@link http://en.wikipedia.org/wiki/ARGB#ARGB}). 261 | * @param array|int|string $color 262 | */ 263 | public function setColor($color) { 264 | 265 | switch (getType($color)) { 266 | case 'array': 267 | $this->r = $color[0]; 268 | $this->g = $color[1]; 269 | $this->b = $color[2]; 270 | break; 271 | 272 | case 'integer': // ARGB format 273 | $this->r = $color >> 16 & 0xFF; 274 | $this->g = $color >> 8 & 0xFF; 275 | $this->b = $color & 0xFF; 276 | break; 277 | 278 | case 'string': 279 | $length = strLen($color); 280 | 281 | if ($length == 7) { 282 | // e.g. '#FFFFFF'. 283 | $this->r = hexDec(subStr($color, 1, 2)); 284 | $this->g = hexDec(subStr($color, 3, 2)); 285 | $this->b = hexDec(subStr($color, 5, 2)); 286 | 287 | } else if ($length == 4) { 288 | // e.g. '#FFF'. 289 | $this->r = hexDec(subStr($color, 1, 1)) * 17; 290 | $this->g = hexDec(subStr($color, 2, 1)) * 17; 291 | $this->b = hexDec(subStr($color, 3, 1)) * 17; 292 | 293 | } else if (strToLower(subStr($color, 0, 4)) == 'rgb(') { 294 | // e.g. 'rgb(255, 255, 255)'. 295 | $listOfColors = subStr($color, 4, -1); 296 | $arrayOfColors = explode(',', $listOfColors); 297 | 298 | $this->r = intVal($arrayOfColors[0]); 299 | $this->g = intVal($arrayOfColors[1]); 300 | $this->b = intVal($arrayOfColors[2]); 301 | } 302 | break; 303 | } 304 | } 305 | 306 | /** 307 | * Returns the colour as an integer, in the ARGB format 308 | * ({@link http://en.wikipedia.org/wiki/ARGB#ARGB}). 309 | * @return int 310 | */ 311 | public function toInt() { 312 | $color = 0; 313 | 314 | $color |= $this->r << 16; 315 | $color |= $this->g << 8; 316 | $color |= $this->b; 317 | 318 | return $color; 319 | } 320 | 321 | /** 322 | * Returns the colour in the RGB string format, e.g. 'rgb(0,0,0)'. 323 | * @return string 324 | */ 325 | public function toRGB() { 326 | return 'rgb(' . $this->r . ',' . $this->g . ',' . $this->b . ')'; 327 | } 328 | 329 | /** 330 | * Returns the color in the CSS hexadecimal format, e.g. '#000000'. 331 | * @return string 332 | */ 333 | public function toHex() { 334 | return sprintf('#%02s%02s%02s', decHex($this->r), decHex($this->g), decHex($this->b)); 335 | } 336 | } -------------------------------------------------------------------------------- /src/SamChristy/PieChart/PieChartGD.php: -------------------------------------------------------------------------------- 1 | & Alex Paredes 8 | * @licence GNU GPL v3.0 9 | * @copyright © Sam Christy 2013 10 | * @package PieChart 11 | * @version v2.0.1 12 | */ 13 | class PieChartGD extends PieChart { 14 | public function destroy() { 15 | imageDestroy($this->canvas); 16 | } 17 | 18 | /** 19 | * Draws the pie chart, with optional supersampled anti-aliasing. 20 | * @param int $aa 21 | */ 22 | public function draw($aa = 4, $transparentBackground = true) { 23 | $this->canvas = imageCreateTrueColor($this->width, $this->height); 24 | 25 | // Set anti-aliasing for the pie chart. 26 | imageAntiAlias($this->canvas, true); 27 | 28 | $transparency = null; 29 | if($transparentBackground){ 30 | imagealphablending($this->canvas, false); 31 | $transparency = imagecolorallocatealpha($this->canvas, 0, 0, 0, 127); 32 | imagefill($this->canvas, 0, 0, $transparency); 33 | imagesavealpha($this->canvas, true); 34 | } 35 | 36 | 37 | imageFilledRectangle($this->canvas, 0, 0, $this->width, $this->height, 38 | $transparency === null ? $this->_convertColor($this->backgroundColor) : $transparency); 39 | 40 | $total = 0; 41 | $sliceStart = -90; // Start at 12 o'clock. 42 | 43 | $titleHeight = $this->_drawTitle(); 44 | $legendWidth = $this->_drawLegend($titleHeight); 45 | 46 | // Account for the space occupied by the legend and its padding. 47 | $pieCentreX = ($this->width - $legendWidth) / 2; 48 | 49 | // Account for the space occupied by the title. 50 | $pieCentreY = $titleHeight + ($this->height - $titleHeight) / 2; 51 | 52 | // 10% padding on the top and bottom of the pie. 53 | $pieDiameter = round( 54 | min($this->width - $legendWidth, $this->height - $titleHeight) * 0.85 55 | ); 56 | 57 | foreach ($this->slices as $slice) 58 | $total += $slice['value']; 59 | 60 | // If anti-aliasing is enabled, we supersample the pie to work around 61 | // the fact that GD does not provide anti-aliasing natively. 62 | if ($aa > 0) { 63 | $ssDiameter = $pieDiameter * $aa; 64 | $ssCentreX = $ssCentreY = $ssDiameter / 2 ; 65 | $superSample = imageCreateTrueColor($ssDiameter, $ssDiameter); 66 | 67 | if($transparentBackground){ 68 | imagefill($superSample, 0, 0, $transparency); 69 | imagesavealpha($superSample, true); 70 | } 71 | 72 | imageFilledRectangle($superSample, 0, 0, $ssDiameter, $ssDiameter, 73 | $transparency === null ? $this->_convertColor($this->backgroundColor) : $transparency); 74 | 75 | foreach ($this->slices as $slice) { 76 | $sliceWidth = 360 * $slice['value'] / $total; 77 | 78 | // Skip slices that are too small to draw / be visible. 79 | if ($sliceWidth == 0) 80 | continue; 81 | 82 | $sliceEnd = $sliceStart + $sliceWidth; 83 | 84 | imageFilledArc( 85 | $superSample, 86 | $ssCentreX, 87 | $ssCentreY, 88 | $ssDiameter, 89 | $ssDiameter, 90 | $sliceStart, 91 | $sliceEnd, 92 | $this->_convertColor($slice['color']), 93 | IMG_ARC_PIE 94 | ); 95 | 96 | // Move along to the next slice. 97 | $sliceStart = $sliceEnd; 98 | } 99 | 100 | imageCopyResampled( 101 | $this->canvas, $superSample, 102 | $pieCentreX - $pieDiameter / 2, $pieCentreY - $pieDiameter / 2, 103 | 0, 0, 104 | $pieDiameter, $pieDiameter, 105 | $ssDiameter, $ssDiameter 106 | ); 107 | 108 | imageDestroy($superSample); 109 | } 110 | else { 111 | // Draw the slices. 112 | foreach ($this->slices as $slice) { 113 | $sliceWidth = 360 * $slice['value'] / $total; 114 | 115 | // Skip slices that are too small to draw / be visible. 116 | if ($sliceWidth == 0) 117 | continue; 118 | 119 | $sliceEnd = $sliceStart + $sliceWidth; 120 | 121 | imageFilledArc( 122 | $this->canvas, 123 | $pieCentreX, 124 | $pieCentreY, 125 | $pieDiameter, 126 | $pieDiameter, 127 | $sliceStart, 128 | $sliceEnd, 129 | $this->_convertColor($slice['color']), 130 | IMG_ARC_PIE 131 | ); 132 | 133 | // Move along to the next slice. 134 | $sliceStart = $sliceEnd; 135 | } 136 | } 137 | } 138 | 139 | protected function _output($method, $format, $filename) { 140 | switch ($format) { 141 | case parent::FORMAT_GIF: 142 | if ($method == parent::OUTPUT_INLINE || $method == parent::OUTPUT_DOWNLOAD) { 143 | return imageGIF($this->canvas); 144 | } 145 | else if ($method == parent::OUTPUT_SAVE) { 146 | return imageGIF($this->canvas, $filename); 147 | } 148 | break; 149 | 150 | case parent::FORMAT_JPEG: 151 | if ($method == parent::OUTPUT_INLINE || $method == parent::OUTPUT_DOWNLOAD) { 152 | return imageJPEG($this->canvas, NULL, $this->quality); 153 | } 154 | else if ($method == parent::OUTPUT_SAVE) { 155 | return imageJPEG($this->canvas, $filename, $this->quality); 156 | } 157 | break; 158 | 159 | case parent::FORMAT_PNG: 160 | if ($method == parent::OUTPUT_INLINE || $method == parent::OUTPUT_DOWNLOAD) { 161 | return imagePNG($this->canvas); 162 | } 163 | else if ($method == parent::OUTPUT_SAVE) { 164 | return imagePNG($this->canvas, $filename); 165 | } 166 | break; 167 | } 168 | 169 | return false; // The output method or format is missing! 170 | } 171 | 172 | /** 173 | * Draws the legend for the pieChart, if $this->hasLegend is true. 174 | * @param int $legendOffset The number of pixels the legend is offset by the title. 175 | * @return int The width of the legend and its padding. 176 | */ 177 | protected function _drawLegend($legendOffset) { 178 | if (!$this->hasLegend) 179 | return 0; 180 | 181 | // Determine the ideal font size for the legend text; 182 | $legendFontSize = $this->width * 0.022; 183 | 184 | // If the legend's font size is too small, we won't bother drawing it. 185 | if (ceil($legendFontSize) < 8) 186 | return 0; 187 | 188 | // Calculate the size and padding for the color squares. 189 | $squareSize = $this->height * 0.060; 190 | $squarePadding = $this->height * 0.025; 191 | $labelPadding = $this->height * 0.025; 192 | 193 | $sliceCount = count($this->slices); 194 | 195 | $legendPadding = 0.05 * $this->width; 196 | 197 | // Determine the width and height of the legend. 198 | $legendWidth = $squareSize + $labelPadding + $this->_maxLabelWidth($legendFontSize); 199 | $legendHeight = $sliceCount * ($squareSize + $squarePadding) - $squarePadding; 200 | 201 | // If the legend and its padding occupy too much space, we will not draw it. 202 | if ($legendWidth + $legendPadding * 2 > $this->width / 2) // Too wide. 203 | return 0; 204 | 205 | if ($legendHeight > $this->height - $legendOffset - $legendPadding * 2) // Too high. 206 | return 0; 207 | 208 | $legendX = $this->width - $legendWidth - $legendPadding; 209 | $legendY = ($this->height - $legendOffset) / 2 + $legendOffset - $legendHeight / 2; 210 | 211 | $i = 0; 212 | foreach ($this->slices as $sliceName => $slice) { 213 | // Move down... 214 | $OffsetY = $i++ * ($squareSize + $squarePadding); 215 | 216 | $this->_drawLegendKey( 217 | $legendX, 218 | $legendY + $OffsetY, 219 | $slice['color'], 220 | $sliceName, 221 | $squareSize, 222 | $labelPadding, 223 | $legendFontSize 224 | ); 225 | } 226 | 227 | return $legendWidth + $legendPadding * 2; 228 | } 229 | 230 | /** 231 | * Draws the legend key at the specific location. 232 | * @param int $x The x coordinate for the key's top, left corner. 233 | * @param int $y The y coordinate for the key's top, left corner. 234 | * @param object $color The GD colour identifier, created with imageColorAllocate(). 235 | * @param string $label 236 | * @param int $squareSize The size of the square, in pixels. 237 | * @param int $labelPadding 238 | * @param int $fontSize 239 | */ 240 | protected function _drawLegendKey($x, $y, $color, $label, $squareSize, $labelPadding, 241 | $fontSize) { 242 | $labelX = $x + $squareSize + $labelPadding; 243 | 244 | // Centre the label vertically to the square. 245 | $labelBBox = imageTTFBBox($fontSize, 0, $this->legendFont, $label); 246 | $labelHeight = abs($labelBBox[7] - $labelBBox[1]); 247 | 248 | $labelY = $y + $squareSize / 2 - $labelHeight / 2; 249 | 250 | imageFilledRectangle( 251 | $this->canvas, $x, $y, $x + $squareSize, $y + $squareSize, $this->_convertColor($color) 252 | ); 253 | 254 | imageTTFText( 255 | $this->canvas, 256 | $fontSize, 257 | 0, 258 | $labelX + abs($labelBBox[0]), // Eliminate left overhang. 259 | $labelY + abs($labelBBox[7]), // Eliminate area above the baseline. 260 | $this->_convertColor($this->textColor), 261 | $this->legendFont, 262 | $label 263 | ); 264 | } 265 | 266 | /** 267 | * Returns the width, in pixels, of the chart's widest label. 268 | * @return int 269 | */ 270 | protected function _maxLabelWidth($fontSize) { 271 | $widestLabelWidth = 0; 272 | 273 | foreach ($this->slices as $sliceName => $slice) { 274 | // Measure the label. 275 | $boundingBox = imageTTFBBox($fontSize, 0, $this->legendFont, $sliceName); 276 | $labelWidth = $boundingBox[2] - $boundingBox[0]; 277 | 278 | if ($labelWidth > $widestLabelWidth) 279 | $widestLabelWidth = $labelWidth; 280 | } 281 | 282 | return $widestLabelWidth; 283 | } 284 | 285 | /** 286 | * Draws and returns the height of the title and its padding (in pixels). If no title is 287 | * specified, then nothing is drawn and 0 is returned. 288 | * @var float x location 289 | * @var float y location 290 | * @return int The height of the title + padding. 291 | */ 292 | protected function _drawTitle($x = 0, $y = 0) { 293 | if (!$this->title) 294 | return 0; 295 | 296 | $titleColor = $this->_convertColor($this->textColor); 297 | 298 | // Determine ideal font size for the title. 299 | $titleSize = 0.0675 * $this->height; // The largest sensible value. 300 | $minTitleSize = 10; // The smallest legible value. 301 | 302 | do { 303 | $titleBBox = imageTTFBBox($titleSize, 0, $this->titleFont, $this->title); 304 | $titleWidth = $titleBBox[2] - $titleBBox[0]; 305 | 306 | // If we can fit the title in, with 5% padding on each side, then we can 307 | // draw it. 308 | if ($titleWidth <= ($this->width * 0.9)) 309 | break; 310 | 311 | $titleSize -= 0.5; // Try a smaller font size. 312 | } while ($titleSize >= $minTitleSize); 313 | 314 | // If the title is simply too long to be drawn legibly, then we will simply not 315 | // draw it. 316 | if ($titleSize < $minTitleSize) 317 | return 0; 318 | 319 | $titleHeight = abs($titleBBox[7] - $titleBBox[1]); 320 | 321 | // Give the title 7.5% top padding. 322 | $titleTopPadding = 0.075 * $this->height; 323 | 324 | // Centre the title. 325 | $x = $this->width / 2 - $titleWidth / 2; 326 | $y = $titleTopPadding; 327 | 328 | imageTtfText( 329 | $this->canvas, $titleSize, 330 | 0, 331 | $x + abs($titleBBox[0]), // Account for left overhang. 332 | $y + abs($titleBBox[7]), // Account for the area above the baseline. 333 | $titleColor, 334 | $this->titleFont, 335 | $this->title 336 | ); 337 | 338 | return $titleHeight + $titleTopPadding; 339 | } 340 | 341 | /** 342 | * A convenience function for converting PieChartColor objects to the format 343 | * that GD requires. 344 | */ 345 | private function _convertColor(PieChartColor $color) { 346 | // Interestingly, GD uses the ARGB format internally, so 347 | // PieChartColor::toInt() would actually work for everything but GIFs... 348 | return imageColorAllocate($this->canvas, $color->r, $color->g, $color->b); 349 | } 350 | } -------------------------------------------------------------------------------- /src/SamChristy/PieChart/PieChartImagick.php: -------------------------------------------------------------------------------- 1 | 11 | * @licence GNU GPL v3.0 12 | * @copyright © Sam Christy 2013 13 | * @package PieChart 14 | * @version v2.0.0 15 | */ 16 | class PieChartImagick extends PieChart { 17 | public function destroy() { 18 | $this->canvas->destroy(); 19 | } 20 | 21 | public function draw() { 22 | $this->canvas = new Imagick; 23 | $this->canvas->newImage($this->width, $this->height, $this->backgroundColor->toHex()); 24 | 25 | $total = 0; 26 | $sliceStart = -90; // Start at 12 o'clock. 27 | 28 | $titleHeight = $this->_drawTitle(); 29 | $legendWidth = $this->_drawLegend($titleHeight); 30 | 31 | // Account for the space occupied by the legend and its padding. 32 | $pieCenterX = ($this->width - $legendWidth) / 2; 33 | 34 | // Account for the space occupied by the title. 35 | $pieCenterY = $titleHeight + ($this->height - $titleHeight) / 2; 36 | 37 | // Give the pie 7.5% padding on either side. 38 | $pieDiameter = round( 39 | min($this->width - $legendWidth, $this->height - $titleHeight) * 0.85 40 | ); 41 | 42 | $pieRadius = $pieDiameter / 2; 43 | 44 | foreach ($this->slices as $slice) 45 | $total += $slice['value']; 46 | 47 | // Draw the slices. 48 | foreach ($this->slices as &$slice) { 49 | $sliceWidth = 360 * $slice['value'] / $total; 50 | 51 | // Skip slices that are too small to draw / be visible. 52 | if ($sliceWidth == 0) continue; 53 | 54 | $sliceEnd = $sliceStart + $sliceWidth; 55 | 56 | $this->_drawSlice( 57 | array('x' => $pieCenterX, 'y' => $pieCenterY), 58 | $pieRadius, 59 | $sliceStart, 60 | $sliceEnd, 61 | $slice['color'] 62 | ); 63 | 64 | // Move along to the next slice. 65 | $sliceStart = $sliceEnd; 66 | } 67 | } 68 | 69 | protected function _output($method, $format, $filename) { 70 | switch ($format) { 71 | case parent::FORMAT_GIF: 72 | $this->canvas->setImageFormat('gif'); 73 | 74 | if ($method == parent::OUTPUT_INLINE || $method == parent::OUTPUT_DOWNLOAD) { 75 | return print $this->canvas; 76 | } 77 | else if ($method == parent::OUTPUT_SAVE) { 78 | return $this->canvas->writeImage($filename); 79 | } 80 | break; 81 | 82 | case parent::FORMAT_JPEG: 83 | $this->canvas->setImageFormat('jpeg'); 84 | $this->canvas->setImageCompression(imagick::COMPRESSION_JPEG); 85 | $this->canvas->setImageCompressionQuality($this->quality); 86 | 87 | if ($method == parent::OUTPUT_INLINE || $method == parent::OUTPUT_DOWNLOAD) { 88 | return print $this->canvas; 89 | } 90 | else if ($method == parent::OUTPUT_SAVE) { 91 | return $this->canvas->writeImage($filename); 92 | } 93 | break; 94 | 95 | case parent::FORMAT_PNG: 96 | $this->canvas->setImageFormat('png'); 97 | 98 | if ($method == parent::OUTPUT_INLINE || $method == parent::OUTPUT_DOWNLOAD) { 99 | return print $this->canvas; 100 | } 101 | else if ($method == parent::OUTPUT_SAVE) { 102 | return $this->canvas->writeImage($filename); 103 | } 104 | break; 105 | } 106 | 107 | return false; // The output method or format is missing! 108 | } 109 | 110 | /** 111 | * Draws the legend for the pieChart, if $this->hasLegend is true. 112 | * @param int $legendOffset The number of pixels the legend is offset by the title. 113 | * @return int The width of the legend and its padding. 114 | */ 115 | protected function _drawLegend($legendOffset) { 116 | if (!$this->hasLegend) 117 | return 0; 118 | 119 | // Determine the ideal font size for the legend text; 120 | $legendFontSize = $this->width * 0.0325; 121 | 122 | // If the legend's font size is too small, we won't bother drawing it. 123 | if (ceil($legendFontSize) < 8) 124 | return 0; 125 | 126 | // Calculate the size and padding for the color squares. 127 | $squareSize = $this->height * 0.060; 128 | $squarePadding = $this->height * 0.025; 129 | $labelPadding = $this->height * 0.025; 130 | 131 | $sliceCount = count($this->slices); 132 | 133 | $legendPadding = 0.075 * $this->width; 134 | 135 | // Get the width of the legend's widest label. 136 | $maxLabelWidth = $this->_maxLabelWidth($legendFontSize); 137 | 138 | // Determine the width and height of the legend. 139 | $legendWidth = $squareSize + $labelPadding + $maxLabelWidth; 140 | $legendHeight = $sliceCount * ($squareSize + $squarePadding) - $squarePadding; 141 | 142 | // If the legend and its padding occupy too much space, we will not draw it. 143 | if ($legendWidth + $legendPadding * 2 > $this->width / 2) // Too wide. 144 | return 0; 145 | 146 | if ($legendHeight > $this->height - $legendOffset - $legendPadding * 2) // Too high. 147 | return 0; 148 | 149 | $legendX = $this->width - $legendWidth - $legendPadding; 150 | $legendY = ($this->height - $legendOffset) / 2 + $legendOffset - $legendHeight / 2; 151 | 152 | $labelSettings = new ImagickDraw; 153 | 154 | $labelSettings->setFont($this->legendFont); 155 | $labelSettings->setFillColor($this->textColor->toHex()); 156 | $labelSettings->setFontSize($legendFontSize); 157 | $labelSettings->setGravity(Imagick::GRAVITY_NORTHWEST); 158 | 159 | $i = 0; 160 | foreach ($this->slices as $sliceName => $slice) { 161 | // Move down... 162 | $OffsetY = $i++ * ($squareSize + $squarePadding); 163 | 164 | $keyPosX = $legendX; 165 | $keyPosY = $legendY + $OffsetY; 166 | 167 | // 1. Draw the key's colour square. 168 | $keySquare = new ImagickDraw; 169 | $keySquare->setFillColor($slice['color']->toHex()); 170 | $keySquare->rectangle( 171 | $keyPosX, 172 | $keyPosY, 173 | $keyPosX + $squareSize, 174 | $keyPosY + $squareSize 175 | ); 176 | 177 | $this->canvas->drawImage($keySquare); 178 | 179 | // 2. Draw the key's label. 180 | $labelMetrics = $this->canvas->queryFontMetrics($labelSettings, $sliceName); 181 | 182 | $this->canvas->annotateImage( 183 | $labelSettings, 184 | $keyPosX + $squareSize + $squarePadding, 185 | $keyPosY + $labelMetrics['descender'] / 2, 186 | 0, 187 | $sliceName 188 | ); 189 | } 190 | 191 | return $legendWidth + $legendPadding; 192 | } 193 | 194 | protected function _drawSlice($center, $radius, $start, $end, $color){ 195 | // Fine tuning, for a smoother edge. 196 | $radius -= 1; 197 | $center['x'] -= 1; 198 | $center['y'] -= 1; 199 | 200 | // 1. Drawn the curved part. 201 | $arc = new ImagickDraw; 202 | $color = $color->toHex(); 203 | 204 | $arc->setFillColor($color); 205 | $arc->setStrokeColor($color); 206 | $arc->setStrokeWidth(1); 207 | 208 | $arc->arc( 209 | $center['x'] - $radius, 210 | $center['y'] - $radius, 211 | $center['x'] + $radius, 212 | $center['y'] + $radius, 213 | $start, 214 | $end 215 | ); 216 | 217 | $this->canvas->drawImage($arc); 218 | 219 | // 2. Draw the triangular part. 220 | $startRadians = deg2rad($start); 221 | $endRadians = deg2rad($end); 222 | 223 | // Calculate position for start of slice. 224 | $startPosition = array( 225 | 'x' => $center['x'] + $radius * cos($startRadians), 226 | 'y' => $center['y'] + $radius * sin($startRadians) 227 | ); 228 | 229 | // Calculate position for end of slice. 230 | $endPosition = array( 231 | 'x' => $center['x'] + $radius * cos($endRadians), 232 | 'y' => $center['y'] + $radius * sin($endRadians) 233 | ); 234 | 235 | $trianglePoints = array($startPosition, $endPosition, $center); 236 | 237 | $triangle = new ImagickDraw; 238 | 239 | $triangle->setFillColor($color); 240 | $triangle->setStrokeColor($color); 241 | $triangle->setStrokeWidth(1); 242 | 243 | $triangle->polygon($trianglePoints); 244 | 245 | $this->canvas->drawImage($triangle); 246 | } 247 | 248 | /** 249 | * Returns the width, in pixels, of the chart's widest label. 250 | * @return int 251 | */ 252 | protected function _maxLabelWidth($fontSize) { 253 | $labelSettings = new ImagickDraw; 254 | $labelSettings->setFontSize($fontSize); 255 | $widestLabelWidth = 0; 256 | 257 | foreach ($this->slices as $sliceName => $slice) { 258 | // Measure the label. 259 | $labelMetrics = $this->canvas->queryFontMetrics($labelSettings, $sliceName); 260 | $labelWidth = $labelMetrics['textWidth']; 261 | 262 | if ($labelWidth > $widestLabelWidth) 263 | $widestLabelWidth = $labelWidth; 264 | } 265 | 266 | return $widestLabelWidth; 267 | } 268 | 269 | /** 270 | * Draws and returns the height of the title and its padding (in pixels). If no title is 271 | * specified, then nothing is drawn and 0 is returned. 272 | * @return int The height of the title + padding. 273 | */ 274 | protected function _drawTitle() { 275 | if (!$this->title) return 0; 276 | 277 | $titleSettings = new ImagickDraw; 278 | 279 | $titleSettings->setFont($this->titleFont); 280 | $titleSettings->setFillColor($this->textColor->toHex()); 281 | $titleSettings->setGravity(Imagick::GRAVITY_NORTH); 282 | 283 | // Determine ideal font size for the title. 284 | $titleSize = 0.08 * $this->height; // The largest sensible value. 285 | $minTitleSize = 10; // The smallest legible value. 286 | 287 | do { 288 | $titleSettings->setFontSize($titleSize); 289 | 290 | // Measure the text. 291 | $titleBBox = $this->canvas->queryFontMetrics($titleSettings, $this->title); 292 | $titleWidth = $titleBBox['textWidth']; 293 | 294 | // If we can fit the title in, with 5% padding on each side, then we can draw it. 295 | if ($titleWidth <= ($this->width * 0.9)) 296 | break; 297 | 298 | $titleSize -= 0.5; // Try a smaller font size. 299 | } while ($titleSize >= $minTitleSize); 300 | 301 | $titleHeight = $titleBBox['textHeight']; 302 | 303 | // If the title is simply too long to be drawn legibly, then we will simply not draw it. 304 | if ($titleSize < $minTitleSize) return 0; 305 | 306 | // Give the title 7.5% top padding. 307 | $titleTopPadding = 0.075 * $this->height; 308 | 309 | // Draw the title (centre-top). 310 | $this->canvas->annotateImage($titleSettings, 0, $titleTopPadding, 0, $this->title); 311 | 312 | return $titleHeight + $titleTopPadding; 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Page not found 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 51 |
52 | 53 |
54 | 55 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/class-PieChart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Class PieChart | PieChart 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 49 |
50 | 51 |
52 | 53 | 1273 | 1274 | 1275 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/class-PieChartColor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Class PieChartColor | PieChart 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 49 |
50 | 51 |
52 | 53 | 400 | 401 | 402 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/class-PieChartGD.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Class PieChartGD | PieChart 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 49 |
50 | 51 |
52 | 53 | 505 | 506 | 507 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/class-PieChartImagick.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Class PieChartImagick | PieChart 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 49 |
50 | 51 |
52 | 53 | 480 | 481 | 482 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/class-SamChristy.PieChart.PieChartColor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Class SamChristy\PieChart\PieChartColor 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 50 |
51 | 52 |
53 | 54 | 401 | 402 | 403 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/class-SamChristy.PieChart.PieChartGD.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Class SamChristy\PieChart\PieChartGD 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 50 |
51 | 52 |
53 | 54 | 511 | 512 | 513 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/class-SamChristy.PieChart.PieChartImagick.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Class SamChristy\PieChart\PieChartImagick 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 50 |
51 | 52 |
53 | 54 | 481 | 482 | 483 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/elementlist.js: -------------------------------------------------------------------------------- 1 | 2 | var ApiGen = ApiGen || {}; 3 | ApiGen.elements = [["c","SamChristy\\PieChart\\PieChart"],["c","SamChristy\\PieChart\\PieChartColor"],["c","SamChristy\\PieChart\\PieChartGD"],["c","SamChristy\\PieChart\\PieChartImagick"]]; 4 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/function-imageSmoothArc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Function imageSmoothArc | PieChart 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 47 |
48 | 49 |
50 | 51 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/function-imageSmoothArcDrawSegment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Function imageSmoothArcDrawSegment | PieChart 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 47 |
48 | 49 |
50 | 51 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Overview 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 49 |
50 | 51 |
52 | 53 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/namespace-SamChristy.PieChart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Namespace SamChristy\PieChart 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 50 |
51 | 52 |
53 | 54 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/namespace-SamChristy.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Namespace SamChristy 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 42 |
43 | 44 |
45 | 46 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/package-None.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | No package | PieChart 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 47 |
48 | 49 |
50 | 51 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/package-PieChart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Package PieChart | PieChart 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 49 |
50 | 51 |
52 | 53 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/resources/collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/documentation/resources/collapsed.png -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/resources/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/documentation/resources/footer.png -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/resources/inherit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/documentation/resources/inherit.png -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/resources/resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/documentation/resources/resize.png -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/resources/sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/documentation/resources/sort.png -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/resources/style.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * ApiGen 2.8.0 - API documentation generator for PHP 5.3+ 3 | * 4 | * Copyright (c) 2010-2011 David Grudl (http://davidgrudl.com) 5 | * Copyright (c) 2011-2012 Jaroslav Hanslík (https://github.com/kukulich) 6 | * Copyright (c) 2011-2012 Ondřej Nešpor (https://github.com/Andrewsville) 7 | * 8 | * For the full copyright and license information, please view 9 | * the file LICENSE.md that was distributed with this source code. 10 | */ 11 | 12 | body { 13 | font: 13px/1.5 Verdana, 'Geneva CE', lucida, sans-serif; 14 | margin: 0; 15 | padding: 0; 16 | background: #ffffff; 17 | color: #333333; 18 | } 19 | 20 | h1, h2, h3, h4, caption { 21 | font-family: 'Trebuchet MS', 'Geneva CE', lucida, sans-serif; 22 | color: #053368; 23 | } 24 | 25 | h1 { 26 | color: #1e5eb6; 27 | font-size: 230%; 28 | font-weight: normal; 29 | margin: .3em 0; 30 | } 31 | 32 | h2 { 33 | color: #1e5eb6; 34 | font-size: 150%; 35 | font-weight: normal; 36 | margin: -.3em 0 .3em 0; 37 | } 38 | 39 | h3 { 40 | font-size: 1.6em; 41 | font-weight: normal; 42 | margin-bottom: 2px; 43 | } 44 | 45 | h4 { 46 | font-size: 100%; 47 | font-weight: bold; 48 | padding: 0; 49 | margin: 0; 50 | } 51 | 52 | caption { 53 | border: 1px solid #cccccc; 54 | background: #ecede5; 55 | font-weight: bold; 56 | font-size: 1.2em; 57 | padding: 3px 5px; 58 | text-align: left; 59 | margin-bottom: 0; 60 | } 61 | 62 | p { 63 | margin: .7em 0 1em; 64 | padding: 0; 65 | } 66 | 67 | hr { 68 | margin: 2em 0 1em; 69 | border: none; 70 | border-top: 1px solid #cccccc; 71 | height: 0; 72 | } 73 | 74 | a { 75 | color: #006aeb; 76 | padding: 3px 1px; 77 | text-decoration: none; 78 | } 79 | 80 | h1 a { 81 | color: #1e5eb6; 82 | } 83 | 84 | a:hover, a:active, a:focus, a:hover b, a:hover var { 85 | background-color: #006aeb; 86 | color: #ffffff !important; 87 | } 88 | 89 | code, var, pre { 90 | font-family: monospace; 91 | } 92 | 93 | var { 94 | font-weight: bold; 95 | font-style: normal; 96 | color: #ca8a04; 97 | } 98 | 99 | pre { 100 | margin: 0; 101 | } 102 | 103 | code a b { 104 | color: #000000; 105 | } 106 | 107 | .deprecated { 108 | text-decoration: line-through; 109 | } 110 | 111 | .invalid { 112 | color: #e71818; 113 | } 114 | 115 | .hidden { 116 | display: none; 117 | } 118 | 119 | /* Left side */ 120 | #left { 121 | overflow: auto; 122 | width: 270px; 123 | height: 100%; 124 | position: fixed; 125 | } 126 | 127 | /* Menu */ 128 | #menu { 129 | padding: 10px; 130 | } 131 | 132 | #menu ul { 133 | list-style: none; 134 | padding: 0; 135 | margin: 0; 136 | } 137 | 138 | #menu ul ul { 139 | padding-left: 10px; 140 | } 141 | 142 | #menu li { 143 | white-space: nowrap; 144 | position: relative; 145 | } 146 | 147 | #menu a { 148 | display: block; 149 | padding: 0 2px; 150 | } 151 | 152 | #menu .active > a, #menu > span { 153 | color: #333333; 154 | background: none; 155 | font-weight: bold; 156 | } 157 | 158 | #menu .active > a.invalid { 159 | color: #e71818; 160 | } 161 | 162 | #menu .active > a:hover, #menu .active > a:active, #menu .active > a:focus { 163 | background-color: #006aeb; 164 | } 165 | 166 | #menu #groups span { 167 | position: absolute; 168 | top: 4px; 169 | right: 2px; 170 | cursor: pointer; 171 | display: block; 172 | width: 12px; 173 | height: 12px; 174 | background: url('collapsed.png') transparent 0 0 no-repeat; 175 | } 176 | 177 | #menu #groups span:hover { 178 | background-position: -12px 0; 179 | } 180 | 181 | #menu #groups span.collapsed { 182 | background-position: 0 -12px; 183 | } 184 | 185 | #menu #groups span.collapsed:hover { 186 | background-position: -12px -12px; 187 | } 188 | 189 | #menu #groups ul.collapsed { 190 | display: none; 191 | } 192 | 193 | /* Right side */ 194 | #right { 195 | overflow: auto; 196 | margin-left: 275px; 197 | height: 100%; 198 | position: fixed; 199 | left: 0; 200 | right: 0; 201 | } 202 | 203 | #rightInner { 204 | max-width: 1000px; 205 | min-width: 350px; 206 | } 207 | 208 | /* Search */ 209 | #search { 210 | float: right; 211 | margin: 3px 8px; 212 | } 213 | 214 | #search input.text { 215 | padding: 3px 5px; 216 | width: 250px; 217 | } 218 | 219 | /* Autocomplete */ 220 | .ac_results { 221 | padding: 0; 222 | border: 1px solid #cccccc; 223 | background-color: #ffffff; 224 | overflow: hidden; 225 | z-index: 99999; 226 | } 227 | 228 | .ac_results ul { 229 | width: 100%; 230 | list-style-position: outside; 231 | list-style: none; 232 | padding: 0; 233 | margin: 0; 234 | } 235 | 236 | .ac_results li { 237 | margin: 0; 238 | padding: 2px 5px; 239 | cursor: default; 240 | display: block; 241 | font: 12px 'Trebuchet MS', 'Geneva CE', lucida, sans-serif; 242 | line-height: 16px; 243 | overflow: hidden; 244 | white-space: nowrap; 245 | } 246 | 247 | .ac_results li strong { 248 | color: #000000; 249 | } 250 | 251 | .ac_odd { 252 | background-color: #eeeeee; 253 | } 254 | 255 | .ac_over { 256 | background-color: #006aeb; 257 | color: #ffffff; 258 | } 259 | 260 | .ac_results li.ac_over strong { 261 | color: #ffffff; 262 | } 263 | 264 | /* Navigation */ 265 | #navigation { 266 | padding: 3px 8px; 267 | background-color: #f6f6f4; 268 | height: 26px; 269 | } 270 | 271 | #navigation ul { 272 | list-style: none; 273 | margin: 0 8px 4px 0; 274 | padding: 0; 275 | overflow: hidden; 276 | float: left; 277 | } 278 | 279 | #navigation ul + ul { 280 | border-left: 1px solid #000000; 281 | padding-left: 8px; 282 | } 283 | 284 | #navigation ul li { 285 | float: left; 286 | margin: 2px; 287 | padding: 0 3px; 288 | font-family: Verdana, 'Geneva CE', lucida, sans-serif; 289 | color: #808080; 290 | } 291 | 292 | #navigation ul li.active { 293 | background-color: #053368; 294 | color: #ffffff; 295 | font-weight: bold; 296 | } 297 | 298 | #navigation ul li a { 299 | color: #000000; 300 | font-weight: bold; 301 | padding: 0; 302 | } 303 | 304 | #navigation ul li span { 305 | float: left; 306 | padding: 0 3px; 307 | } 308 | 309 | #navigation ul li a:hover span, #navigation ul li a:active span, #navigation ul li a:focus span { 310 | background-color: #006aeb; 311 | } 312 | 313 | /* Content */ 314 | #content { 315 | clear: both; 316 | padding: 5px 15px; 317 | } 318 | 319 | .description pre { 320 | padding: .6em; 321 | background: #fcfcf7; 322 | } 323 | 324 | #content > .description { 325 | background: #ecede5; 326 | padding: 1px 8px; 327 | margin: 1.2em 0; 328 | } 329 | 330 | #content > .description pre { 331 | margin: .5em 0; 332 | } 333 | 334 | dl.tree { 335 | margin: 1.2em 0; 336 | } 337 | 338 | dl.tree dd { 339 | margin: 0; 340 | padding: 0; 341 | } 342 | 343 | .info { 344 | margin: 1.2em 0; 345 | } 346 | 347 | .summary { 348 | border: 1px solid #cccccc; 349 | border-collapse: collapse; 350 | font-size: 1em; 351 | width: 100%; 352 | margin: 1.2em 0 2.4em; 353 | } 354 | 355 | .summary caption { 356 | border-width: 1px 1px 0; 357 | } 358 | 359 | .summary caption.switchable { 360 | background: #ecede5 url('sort.png') no-repeat center right; 361 | cursor: pointer; 362 | } 363 | 364 | .summary td { 365 | border: 1px solid #cccccc; 366 | margin: 0; 367 | padding: 3px 10px; 368 | font-size: 1em; 369 | vertical-align: top; 370 | } 371 | 372 | .summary td:first-child { 373 | text-align: right; 374 | } 375 | 376 | #packages.summary td:first-child, #namespaces.summary td:first-child, .inherited.summary td:first-child, .used.summary td:first-child { 377 | text-align: left; 378 | } 379 | 380 | .summary tr:hover td { 381 | background: #f6f6f4; 382 | } 383 | 384 | .summary .description pre { 385 | border: .5em solid #ecede5; 386 | } 387 | 388 | .summary .description p { 389 | margin: 0; 390 | } 391 | 392 | .summary .description p + p, .summary .description ul { 393 | margin: 3px 0 0 0; 394 | } 395 | 396 | .summary .description.detailed h4 { 397 | margin-top: 3px; 398 | } 399 | 400 | .summary dl { 401 | margin: 0; 402 | } 403 | 404 | .summary dd { 405 | margin: 0 0 0 25px; 406 | } 407 | 408 | .name, .attributes { 409 | white-space: nowrap; 410 | } 411 | 412 | .value { 413 | white-space: pre-wrap; 414 | } 415 | 416 | td.name, td.attributes { 417 | width: 1%; 418 | } 419 | 420 | .class #methods .name { 421 | width: auto; 422 | white-space: normal; 423 | } 424 | 425 | .class #methods .name > div > code { 426 | white-space: pre-wrap; 427 | } 428 | 429 | .class #methods .name > div > code span, .function .value > code { 430 | white-space: nowrap; 431 | } 432 | 433 | .class #methods td.name > div, .class td.description > div { 434 | position: relative; 435 | padding-right: 1em; 436 | } 437 | 438 | .anchor { 439 | position: absolute; 440 | top: 0; 441 | right: 0; 442 | line-height: 1; 443 | font-size: 85%; 444 | margin: 0; 445 | color: #006aeb !important; 446 | } 447 | 448 | .list { 449 | margin: 0 0 5px 25px; 450 | } 451 | 452 | div.invalid { 453 | background-color: #fae4e0; 454 | padding: 10px; 455 | } 456 | 457 | /* Splitter */ 458 | #splitter { 459 | position: fixed; 460 | height: 100%; 461 | width: 5px; 462 | left: 270px; 463 | background: #1e5eb6 url('resize.png') left center no-repeat; 464 | cursor: e-resize; 465 | } 466 | 467 | #splitter.active { 468 | opacity: .5; 469 | } 470 | 471 | /* Footer */ 472 | #footer { 473 | border-top: 1px solid #e9eeef; 474 | clear: both; 475 | color: #a7a7a7; 476 | font-size: 8pt; 477 | text-align: center; 478 | padding: 20px 0 0; 479 | margin: 3em 0 0; 480 | height: 90px; 481 | background: #ffffff url('footer.png') no-repeat center top; 482 | } 483 | 484 | /* Tree */ 485 | div.tree ul { 486 | list-style: none; 487 | background: url('tree-vertical.png') left repeat-y; 488 | padding: 0; 489 | margin-left: 20px; 490 | } 491 | 492 | div.tree li { 493 | margin: 0; 494 | padding: 0; 495 | } 496 | 497 | div.tree div { 498 | padding-left: 30px; 499 | } 500 | 501 | div.tree div.notlast { 502 | background: url('tree-hasnext.png') left 10px no-repeat; 503 | } 504 | 505 | div.tree div.last { 506 | background: url('tree-last.png') left -240px no-repeat; 507 | } 508 | 509 | div.tree li.last { 510 | background: url('tree-cleaner.png') left center repeat-y; 511 | } 512 | 513 | div.tree span.padding { 514 | padding-left: 15px; 515 | } 516 | 517 | /* Source code */ 518 | .php-keyword1 { 519 | color: #e71818; 520 | font-weight: bold; 521 | } 522 | 523 | .php-keyword2 { 524 | font-weight: bold; 525 | } 526 | 527 | .php-var { 528 | color: #d59401; 529 | font-weight: bold; 530 | } 531 | 532 | .php-num { 533 | color: #cd0673; 534 | } 535 | 536 | .php-quote { 537 | color: #008000; 538 | } 539 | 540 | .php-comment { 541 | color: #929292; 542 | } 543 | 544 | .xlang { 545 | color: #ff0000; 546 | font-weight: bold; 547 | } 548 | 549 | span.l { 550 | display: block; 551 | } 552 | 553 | span.l.selected { 554 | background: #f6f6f4; 555 | } 556 | 557 | span.l a { 558 | color: #333333; 559 | } 560 | 561 | span.l a:hover, div.l a:active, div.l a:focus { 562 | background: transparent; 563 | color: #333333 !important; 564 | } 565 | 566 | span.l .php-var a { 567 | color: #d59401; 568 | } 569 | 570 | span.l .php-var a:hover, span.l .php-var a:active, span.l .php-var a:focus { 571 | color: #d59401 !important; 572 | } 573 | 574 | span.l a.l { 575 | padding-left: 2px; 576 | color: #c0c0c0; 577 | } 578 | 579 | span.l a.l:hover, span.l a.l:active, span.l a.l:focus { 580 | background: transparent; 581 | color: #c0c0c0 !important; 582 | } 583 | 584 | #rightInner.medium #navigation { 585 | height: 52px; 586 | } 587 | 588 | #rightInner.medium #navigation ul:first-child + ul { 589 | clear: left; 590 | border: none; 591 | padding: 0; 592 | } 593 | 594 | #rightInner.medium .name, #rightInner.medium .attributes { 595 | white-space: normal; 596 | } 597 | 598 | #rightInner.small #search { 599 | float: left; 600 | } 601 | 602 | #rightInner.small #navigation { 603 | height: 78px; 604 | } 605 | 606 | #rightInner.small #navigation ul:first-child { 607 | clear: both; 608 | } 609 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/resources/tree-cleaner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/documentation/resources/tree-cleaner.png -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/resources/tree-hasnext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/documentation/resources/tree-hasnext.png -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/resources/tree-last.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/documentation/resources/tree-last.png -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/resources/tree-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/documentation/resources/tree-vertical.png -------------------------------------------------------------------------------- /src/SamChristy/PieChart/documentation/tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Tree 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 50 |
51 | 52 |
53 | 54 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/example/example.php: -------------------------------------------------------------------------------- 1 | setTitle($title, '../fonts/Oswald/Oswald-Regular.ttf'); 20 | 21 | $chart->addSlice('Google Chrome', 27, '#4A7EBB'); 22 | $chart->addSlice('Mozilla Firefox', 23, '#DA8137'); 23 | $chart->addSlice('Apple Safari', 11, '#9BBB59'); 24 | $chart->addSlice('Opera', 3, '#BE4B48'); 25 | $chart->addSlice('Other', 5, '#7D60A0'); 26 | 27 | $chart->draw(); 28 | $chart->outputPNG(); -------------------------------------------------------------------------------- /src/SamChristy/PieChart/example/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/example/example.png -------------------------------------------------------------------------------- /src/SamChristy/PieChart/fonts/Open_Sans/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/fonts/Open_Sans/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/fonts/Open_Sans/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /src/SamChristy/PieChart/fonts/Open_Sans/OpenSans-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/fonts/Open_Sans/OpenSans-ExtraBold.ttf -------------------------------------------------------------------------------- /src/SamChristy/PieChart/fonts/Open_Sans/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/fonts/Open_Sans/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /src/SamChristy/PieChart/fonts/Open_Sans/OpenSans-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/fonts/Open_Sans/OpenSans-Semibold.ttf -------------------------------------------------------------------------------- /src/SamChristy/PieChart/fonts/Oswald/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Vernon Adams (vern@newtypography.co.uk), 2 | with Reserved Font Name Oswald 3 | 4 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 5 | This license is copied below, and is also available with a FAQ at: 6 | http://scripts.sil.org/OFL 7 | 8 | 9 | ----------------------------------------------------------- 10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 11 | ----------------------------------------------------------- 12 | 13 | PREAMBLE 14 | The goals of the Open Font License (OFL) are to stimulate worldwide 15 | development of collaborative font projects, to support the font creation 16 | efforts of academic and linguistic communities, and to provide a free and 17 | open framework in which fonts may be shared and improved in partnership 18 | with others. 19 | 20 | The OFL allows the licensed fonts to be used, studied, modified and 21 | redistributed freely as long as they are not sold by themselves. The 22 | fonts, including any derivative works, can be bundled, embedded, 23 | redistributed and/or sold with any software provided that any reserved 24 | names are not used by derivative works. The fonts and derivatives, 25 | however, cannot be released under any other type of license. The 26 | requirement for fonts to remain under this license does not apply 27 | to any document created using the fonts or their derivatives. 28 | 29 | DEFINITIONS 30 | "Font Software" refers to the set of files released by the Copyright 31 | Holder(s) under this license and clearly marked as such. This may 32 | include source files, build scripts and documentation. 33 | 34 | "Reserved Font Name" refers to any names specified as such after the 35 | copyright statement(s). 36 | 37 | "Original Version" refers to the collection of Font Software components as 38 | distributed by the Copyright Holder(s). 39 | 40 | "Modified Version" refers to any derivative made by adding to, deleting, 41 | or substituting -- in part or in whole -- any of the components of the 42 | Original Version, by changing formats or by porting the Font Software to a 43 | new environment. 44 | 45 | "Author" refers to any designer, engineer, programmer, technical 46 | writer or other person who contributed to the Font Software. 47 | 48 | PERMISSION & CONDITIONS 49 | Permission is hereby granted, free of charge, to any person obtaining 50 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 51 | redistribute, and sell modified and unmodified copies of the Font 52 | Software, subject to the following conditions: 53 | 54 | 1) Neither the Font Software nor any of its individual components, 55 | in Original or Modified Versions, may be sold by itself. 56 | 57 | 2) Original or Modified Versions of the Font Software may be bundled, 58 | redistributed and/or sold with any software, provided that each copy 59 | contains the above copyright notice and this license. These can be 60 | included either as stand-alone text files, human-readable headers or 61 | in the appropriate machine-readable metadata fields within text or 62 | binary files as long as those fields can be easily viewed by the user. 63 | 64 | 3) No Modified Version of the Font Software may use the Reserved Font 65 | Name(s) unless explicit written permission is granted by the corresponding 66 | Copyright Holder. This restriction only applies to the primary font name as 67 | presented to the users. 68 | 69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 70 | Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except to acknowledge the contribution(s) of the 72 | Copyright Holder(s) and the Author(s) or with their explicit written 73 | permission. 74 | 75 | 5) The Font Software, modified or unmodified, in part or in whole, 76 | must be distributed entirely under this license, and must not be 77 | distributed under any other license. The requirement for fonts to 78 | remain under this license does not apply to any document created 79 | using the Font Software. 80 | 81 | TERMINATION 82 | This license becomes null and void if any of the above conditions are 83 | not met. 84 | 85 | DISCLAIMER 86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 94 | OTHER DEALINGS IN THE FONT SOFTWARE. 95 | -------------------------------------------------------------------------------- /src/SamChristy/PieChart/fonts/Oswald/Oswald-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/fonts/Oswald/Oswald-Bold.ttf -------------------------------------------------------------------------------- /src/SamChristy/PieChart/fonts/Oswald/Oswald-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/fonts/Oswald/Oswald-Light.ttf -------------------------------------------------------------------------------- /src/SamChristy/PieChart/fonts/Oswald/Oswald-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamChristy/PieChart/98b3f01526f5d24c072b2b2228762133bc5dd069/src/SamChristy/PieChart/fonts/Oswald/Oswald-Regular.ttf --------------------------------------------------------------------------------