123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979 |
- <?php
- /**
- * The ChartMancer class automates the generation of graphs based on data provided in an array.
- * It utilizes the GD library to create visually appealing charts, allowing developers to easily
- * visualize and display data trends. With ChartMancer, you can customize various aspects of the
- * graph, such as colors, labels, and other chart properties, providing a versatile tool
- * for data representation in PHP applications.
- *
- * @package ChartMancer
- * @author Rostyslav Haitkulov <info@ubilling.net.ua>
- * @see https://github.com/nightflyza/ChartMancer
- * @license MIT
- */
- class ChartMancer {
- /**
- * Custom chart chart title
- *
- * @var string
- */
- protected $chartTitle = '';
- /**
- * Custom colors palette modifier
- *
- * @var string
- */
- protected $palette = 'O-M-G';
- /**
- * Image dimensions, width in px
- *
- * @var int
- */
- protected $imageWidth = 1540;
- /**
- * Image dimensions, height in px
- *
- * @var int
- */
- protected $imageHeight = 400;
- /**
- * Grid dimensions and placement within chart, top side, px
- *
- * @var int
- */
- protected $gridTop = 40;
- /**
- * Grid dimensions and placement within chart, left side, px
- * @var int
- */
- protected $gridLeft = 50;
- /**
- * Grid line width in px
- *
- * @var int
- */
- protected $lineWidth = 1;
- /**
- * Bar default width in px
- *
- * @var int
- */
- protected $barWidth = 5;
- /**
- * Margin between label and axis in px
- *
- * @var int
- */
- protected $labelMargin = 8;
- /**
- * Contains optional chart legend
- *
- * @var array
- */
- protected $chartLegend = array();
- /**
- * Contains default base color RGB decimal values
- *
- * @var array
- */
- protected $baseColor = array(
- 'r' => 47,
- 'g' => 133,
- 'b' => 217
- );
- /**
- * Contains default background color RGB decimal values. White by default.
- *
- * @var array
- */
- protected $backGroundColor = array(
- 'r' => 255,
- 'g' => 255,
- 'b' => 255
- );
- /**
- * Contains default grid color RGB decimal values.
- *
- * @var array
- */
- protected $gridColor = array(
- 'r' => 212,
- 'g' => 212,
- 'b' => 212
- );
- /**
- * Contains default axis color RGB decimal values.
- *
- * @var array
- */
- protected $axisColor = array(
- 'r' => 85,
- 'g' => 85,
- 'b' => 85
- );
- /**
- * Contains default text color RGB decimal values.
- *
- * @var array
- */
- protected $textColor = array(
- 'r' => 85,
- 'g' => 85,
- 'b' => 85
- );
- /**
- * Dynamic palette overrides
- *
- * @var array
- */
- protected $overrideColors = array();
- /**
- * Transparent background transparency flag
- *
- * @var bool
- */
- protected $backgroundTransparent = false;
- /**
- * TTF font path
- *
- * @var string
- */
- protected $font = 'skins/OpenSans-Regular.ttf';
- /**
- * Font size in pt.
- *
- * @var int
- */
- protected $fontSize = 10;
- /**
- * Maximum length of x-Axis label text
- *
- * @var int
- */
- protected $xLabelLen = 5;
- /**
- * Contains X-axis labels count
- *
- * @var int
- */
- protected $xAxisLabelCount = 20;
- /**
- * Contains cutted string suffix
- *
- * @var string
- */
- protected $cutSuffix = '...';
- /**
- * Render maximum dataset value on chart?
- *
- * @var bool
- */
- protected $displayPeakValue = false;
- /**
- * Contains custom Y-axis label
- *
- * @var string
- */
- protected $yAxisName = '';
- /**
- * Rendering debug flag
- *
- * @var bool
- */
- protected $debug = false;
- /**
- * Bar automatic width modifier depend on data set size
- *
- * @var bool
- */
- protected $barAutoWidth = true;
- /**
- * Contains y-max ratio offset from max dataset value to upper grid limit
- *
- * @var float
- */
- protected $yMaxValueRatio = 0.1;
- /**
- * X-Axis text labels rendering flag
- *
- * @var bool
- */
- protected $xLabelRender = true;
- /**
- * Y-Axis text labels rendering flag
- *
- * @var bool
- */
- protected $yLabelRender = true;
- /**
- * Prevents first (totals) data column from marking as already drawn
- *
- * @var bool
- */
- protected $drawFirstColumnAlways = true;
- public function __construct() {
- //what are you expecting to see here?
- }
- /**
- * Returns a decimal RGB color based on text string as array(r/g/b)
- *
- * @param $text Some string of text
- * @param $palette palette string
- *
- * @return array
- */
- protected function getColorFromText($text) {
- $result = array();
- $hash = md5($this->palette . $text);
- $result['r'] = hexdec(substr($hash, 0, 2));
- $result['g'] = hexdec(substr($hash, 2, 2));
- $result['b'] = hexdec(substr($hash, 4, 2));
- return ($result);
- }
- /**
- * Checks is array contains valid RGB values or not?
- *
- * @return bool
- */
- protected function checkColor($colorArray) {
- $result = false;
- if (isset($colorArray['r']) and isset($colorArray['g']) and isset($colorArray['b'])) {
- if (is_numeric($colorArray['r']) and is_numeric($colorArray['g']) and is_numeric($colorArray['b'])) {
- $result = true;
- }
- }
- return ($result);
- }
- /**
- * Set bar automatic width modifier depend on data set size
- *
- * @param bool $barAutoWidth Bar automatic width modifier depend on data set size
- *
- * @return void
- */
- public function setBarAutoWidth($barAutoWidth) {
- $this->barAutoWidth = $barAutoWidth;
- }
- /**
- * Set custom colors palette modifier
- *
- * @param string $palette Custom colors palette modifier
- *
- * @return void
- */
- public function setPalette($palette) {
- $this->palette = $palette;
- }
- /**
- * Set image dimensions, width in px
- *
- * @param int $imageWidth Image dimensions, width in px
- *
- * @return void
- */
- public function setImageWidth($imageWidth) {
- $this->imageWidth = $imageWidth;
- }
- /**
- * Set image dimensions, height in px
- *
- * @param int $imageHeight Image dimensions, height in px
- *
- * @return void
- */
- public function setImageHeight($imageHeight) {
- $this->imageHeight = $imageHeight;
- }
- /**
- * Set bar default width in px
- *
- * @param int $barWidth Bar default width in px
- *
- * @return void
- */
- public function setBarWidth($barWidth) {
- $this->barWidth = $barWidth;
- }
- /**
- * Set default base color RGB decimal values
- *
- * @param array $baseColor Contains default base color RGB decimal values
- *
- * @return void
- */
- public function setBaseColor($baseColor) {
- if ($this->checkColor($baseColor)) {
- $this->baseColor = $baseColor;
- }
- }
- /**
- * Set default background color RGB decimal values. White by default.
- *
- * @param array $backGroundColor Contains default background color RGB decimal values.
- *
- * @return void
- */
- public function setBackGroundColor($backGroundColor) {
- if ($this->checkColor($backGroundColor)) {
- $this->backGroundColor = $backGroundColor;
- }
- }
- /**
- * Set default grid color RGB decimal values.
- *
- * @param array $gridColor Contains default grid color RGB decimal values.
- *
- * @return void
- */
- public function setGridColor($gridColor) {
- if ($this->checkColor($gridColor)) {
- $this->gridColor = $gridColor;
- }
- }
- /**
- * Set default axis color RGB decimal values.
- *
- * @param array $axisColor Contains default axis color RGB decimal values.
- *
- * @return void
- */
- public function setAxisColor($axisColor) {
- if ($this->checkColor($axisColor)) {
- $this->axisColor = $axisColor;
- }
- }
- /**
- * Sets X-axis labels length in bytes
- *
- * @param int $len
- *
- * @return void
- */
- public function setXLabelLen($len = 5) {
- $this->xLabelLen = $len;
- }
- /**
- * Sets X-axis labels count
- *
- * @param int $count
- *
- * @return void
- */
- public function setXLabelsCount($count = 20) {
- $this->xAxisLabelCount = $count;
- }
- /**
- * Sets cutted labels suffix value
- *
- * @param string $value
- *
- * @return void
- */
- public function setCutSuffix($value = '...') {
- $this->cutSuffix = $value;
- }
- /**
- * Set transparent background transparency flag
- *
- * @param bool $backgroundTransparent Transparent background transparency flag
- *
- * @return void
- */
- public function setBackgroundTransparent($backgroundTransparent) {
- $this->backgroundTransparent = $backgroundTransparent;
- }
- /**
- * Set TTF font path
- *
- * @param string $font TTF font path
- *
- * @return void
- */
- public function setFont($font) {
- $this->font = $font;
- }
- /**
- * Set font size in pt.
- *
- * @param int $fontSize Font size in pt.
- *
- * @return void
- */
- public function setFontSize($fontSize) {
- $this->fontSize = $fontSize;
- }
- /**
- * Sets rendering debug flag
- *
- * @param bool $debug Rendering debug flag
- *
- * @return void
- */
- public function setDebug($debug) {
- $this->debug = $debug;
- }
- /**
- * Set default text color RGB decimal values.
- *
- * @param array $textColor default text color RGB decimal values.
- *
- * @return self
- */
- public function setTextColor(array $textColor) {
- if ($this->checkColor($textColor)) {
- $this->textColor = $textColor;
- }
- }
- /**
- * Sets chart chartTitle
- *
- * @param string $chartTitle Chart chartTitle
- *
- * @return void
- */
- public function setChartTitle($chartTitle) {
- $this->chartTitle = $chartTitle;
- }
- /**
- * Sets maximum dataset value rendering on chart flag
- *
- * @return void
- */
- public function setDisplayPeakValue($displayPeakValue) {
- $this->displayPeakValue = $displayPeakValue;
- }
- /**
- * Sets optional chart legend
- *
- * @param array $chartLegend
- *
- * @return void
- */
- public function setChartLegend($chartLegend) {
- if (is_array($chartLegend)) {
- $this->chartLegend = $chartLegend;
- }
- }
- /**
- * Sets custom Y-axis name
- *
- * @param string $yAxisName
- *
- * @return void
- */
- public function setChartYaxisName($yAxisName) {
- $this->yAxisName = $yAxisName;
- }
- /**
- * Sets custom colors overrides as array of RGB decimal values.
- *
- * @return void
- */
- public function setOverrideColors($customColors) {
- $this->overrideColors = $customColors;
- }
- /**
- * Sets the maximum value ratio for the y-axis.
- *
- * This method allows you to set the maximum value ratio for the y-axis in the chart.
- * The ratio determines the maximum value displayed on the y-axis as a additional percentage of the actual maximum dataset value.
- *
- * @param float $ratio The maximum value ratio for the y-axis like 0.1 for 10% or 0.2 for 20%.
- *
- * @return void
- */
- public function setYMaxValueRatio($ratio) {
- $this->yMaxValueRatio = $ratio;
- }
- /**
- * Sets the state of drawing the explict first (totals) column flag.
- *
- * @param bool $state The state to set for drawing the first column.
- * @return void
- */
- public function setDrawFirstColumn($state) {
- $this->drawFirstColumnAlways = $state;
- }
- /**
- * Sets X-Axis text labels rendering flag
- *
- * @param bool $state X-Axis text labels rendering state
- *
- * @return void
- */
- public function setXLabelRender($state) {
- $this->xLabelRender = $state;
- }
- /**
- * Sets Y-Axis text labels rendering flag
- *
- * @param bool $state Y-Axis text labels rendering state
- *
- * @return void
- */
- public function setYLabelRender($state) {
- $this->yLabelRender = $state;
- }
- /**
- * Renders chart as PNG image into browser or into specified file
- *
- * @param array $data chart dataset
- * @param string $filename filename to export chart. May be empty for rendering to browser
- * may contain name of .png file to save as file on FS, or be like
- * base64 or base64html to return chart as base64 encoded string
- *
- * @return bool|string
- */
- public function renderChart($data, $fileName = '') {
- if ($this->debug) {
- //chart generation start timing
- $starttime = explode(' ', microtime());
- $starttime = $starttime[1] + $starttime[0];
- }
- $dataMax = 0;
- $nestedData = false;
- $nestedDepth = 0;
- $dataSize = sizeof($data);
- $dataSize = ($dataSize == 0) ? 1 : $dataSize;
- $result = false;
- $xAxisLabelCount = $this->xAxisLabelCount;
- if ($dataSize < 10) {
- $xAxisLabelCount = 10;
- }
- // Avoid non array input data usage
- if (!is_array($data)) {
- $data = array();
- }
- // Basic data preprocessing
- if (!empty($data)) {
- foreach ($data as $key => $value) {
- if (is_array($value)) {
- $nestedData = true;
- $nestedDepth = sizeof($value);
- foreach ($value as $io => $subVal) {
- if ($subVal > $dataMax) {
- $dataMax = $subVal;
- }
- }
- } else {
- if ($value > $dataMax) {
- $dataMax = $value;
- }
- }
- }
- }
- // Calculating grid dimensions and placement within image
- $gridBottom = $this->imageHeight - $this->gridTop;
- $gridRight = $this->imageWidth - $this->gridLeft;
- $gridHeight = $gridBottom - $this->gridTop;
- $gridWidth = $gridRight - $this->gridLeft;
- // Max value on y-axis
- $yMaxValue = 200;
- // Setting yMaxValue depend of data values
- if ($dataMax) {
- $yMaxValue = round($dataMax + ($dataMax * $this->yMaxValueRatio));
- $yMaxValue = ($yMaxValue != 0) ? $yMaxValue : 2; //preventing division by zero
- }
- // Distance between grid lines on y-axis
- $yLabelSpan = 20;
- if ($dataMax) {
- if ($dataMax <= 20) {
- $yLabelSpan = 1;
- } else {
- if ($dataMax <= 100) {
- $yLabelSpan = 5;
- } else {
- $yLabelSpan = 10;
- }
- }
- if ($dataMax >= 200) {
- $yLabelSpan = round($dataMax / 10);
- }
- }
- // Bar width based on data set size?
- if ($this->barAutoWidth) {
- if ($dataSize <= 50) {
- $this->barWidth = round(($this->imageWidth - $this->gridLeft) / ($dataSize * 1.2));
- }
- }
- // Init image
- $chart = imagecreate($this->imageWidth, $this->imageHeight);
- // Chart backgroun color setup
- if ($this->backgroundTransparent) {
- imagealphablending($chart, false);
- $backgroundColor = imagecolorallocatealpha($chart, 255, 255, 255, 127);
- imagesavealpha($chart, true);
- } else {
- $backgroundColor = imagecolorallocate($chart, $this->backGroundColor['r'], $this->backGroundColor['g'], $this->backGroundColor['b']);
- }
- // Chart base, axis, labels and grid colors setup
- $baseColor = imagecolorallocate($chart, $this->baseColor['r'], $this->baseColor['g'], $this->baseColor['b']);
- $axisColor = imagecolorallocate($chart, $this->axisColor['r'], $this->axisColor['g'], $this->axisColor['b']);
- $labelColor = imagecolorallocate($chart, $this->textColor['r'], $this->textColor['g'], $this->textColor['b']);
- $gridColor = imagecolorallocate($chart, $this->gridColor['r'], $this->gridColor['g'], $this->gridColor['b']);
- $customColors = array();
- $customColors[0] = $baseColor;
- // Nested colors palette generation here
- if ($nestedData) {
- for ($i = 1; $i <= $nestedDepth; $i++) {
- if (isset($this->overrideColors[$i])) {
- //use color override
- $randomColor = $this->overrideColors[$i];
- } else {
- //or generating new
- $randomColor = $this->getColorFromText($i);
- }
- $customColors[$i] = imagecolorallocate($chart, $randomColor['r'], $randomColor['g'], $randomColor['b']);
- }
- }
- imagefill($chart, 0, 0, $backgroundColor);
- imagesetthickness($chart, $this->lineWidth);
- /*
- * Print grid lines bottom up
- */
- for ($i = 0; $i <= $yMaxValue; $i += $yLabelSpan) {
- $y = $gridBottom - $i * $gridHeight / $yMaxValue;
- // Draw the line
- imageline($chart, $this->gridLeft, (int) $y, $gridRight, (int) $y, $gridColor);
- // Draw right aligned label
- $labelBox = imagettfbbox($this->fontSize, 0, $this->font, strval($i));
- $labelWidth = $labelBox[4] - $labelBox[0];
- //drawing Y axis labels
- if ($this->yLabelRender) {
- $labelX = $this->gridLeft - $labelWidth - $this->labelMargin;
- $labelY = $y + $this->fontSize / 2;
- $labelX = (int) $labelX;
- $labelY = (int) $labelY;
- imagettftext($chart, $this->fontSize, 0, $labelX, $labelY, $labelColor, $this->font, strval($i));
- }
- }
- /*
- * Draw x- and y-axis
- */
- imageline($chart, $this->gridLeft, $this->gridTop, $this->gridLeft, $gridBottom, $axisColor);
- imageline($chart, $this->gridLeft, $gridBottom, $gridRight, $gridBottom, $axisColor);
- /*
- * Draw the bars with labels
- */
- $barSpacing = $gridWidth / $dataSize;
- //that 4px avoids round overflow issues with grid on large datasets
- $itemX = $this->gridLeft + $barSpacing / 2 + 4;
- $index = 0;
- //invisible bars control
- $renderedBars = array();
- $drawCalls = 0;
- $drawSkip = 0;
- foreach ($data as $key => $value) {
- /**
- * Draw the bars
- */
- if (is_array($value)) {
- //nested data rendering here
- $i = sizeof($value) - 1;
- $zBuffer = array();
- foreach (array_reverse($value, true) as $io => $subVal) {
- $x1 = $itemX - $this->barWidth / 2;
- $y1 = $gridBottom - $subVal / $yMaxValue * $gridHeight;
- $x2 = $itemX + $this->barWidth / 2;
- $y2 = $gridBottom - 1;
- $x1 = (int) $x1;
- $y1 = (int) $y1;
- $x2 = (int) $x2;
- $y2 = (int) $y2;
- if (!isset($renderedBars[$x1 . '|' . $y1 . '|' . $x2 . '|' . $y2])) {
- @$rValue = (isset($zBuffer[$subVal])) ? $subVal . '_' : $subVal;
- @$zBuffer[$rValue] = array(
- 'value' => $subVal,
- 'x1' => $x1,
- 'y1' => $y1,
- 'x2' => $x2,
- 'y2' => $y2,
- 'colorIdx' => $i
- );
- //thats prevents overdraw folloving values with first (totals) column
- if ($this->drawFirstColumnAlways) {
- if ($i != 0) {
- $renderedBars[$x1 . '|' . $y1 . '|' . $x2 . '|' . $y2] = '1';
- }
- } else {
- //just set bar as rendered in some area
- $renderedBars[$x1 . '|' . $y1 . '|' . $x2 . '|' . $y2] = '1';
- }
- } else {
- $drawSkip++;
- }
- $i--; //color index changes anyway
- }
- if (!empty($zBuffer)) {
- krsort($zBuffer);
- foreach ($zBuffer as $subValue => $rParams) {
- if ($rParams['value'] > 0) {
- imagefilledrectangle($chart, $rParams['x1'], $rParams['y1'], $rParams['x2'], $rParams['y2'], $customColors[$rParams['colorIdx']]);
- $drawCalls++;
- }
- }
- }
- } else {
- // raw key=>val dataset
- $x1 = $itemX - $this->barWidth / 2;
- $y1 = $gridBottom - $value / $yMaxValue * $gridHeight;
- $x2 = $itemX + $this->barWidth / 2;
- $y2 = $gridBottom - 1;
- //explict conversion to avoid implict precision warnings
- $x1 = (int) $x1;
- $y1 = (int) $y1;
- $x2 = (int) $x2;
- $y2 = (int) $y2;
- if ($value > 0) {
- if (!isset($renderedBars[$x1 . '|' . $y1 . '|' . $x2 . '|' . $y2])) {
- imagefilledrectangle($chart, $x1, $y1, $x2, $y2, $customColors[0]);
- $renderedBars[$x1 . '|' . $y1 . '|' . $x2 . '|' . $y2] = '1';
- $drawCalls++;
- } else {
- $drawSkip++;
- }
- }
- }
- $index++;
- if ($this->xLabelRender) {
- // Skipping some labels display?
- if ($dataSize > 10) {
- $labelIterator = (int) ($dataSize / $xAxisLabelCount);
- $labelIterator = ($labelIterator == 0) ? 1 : $labelIterator; //prevents mod by zero
- if (($index) % $labelIterator == 0) {
- // Draw the label if its renderable
- $labelBox = imagettfbbox($this->fontSize, 0, $this->font, $key);
- $labelWidth = $labelBox[4] - $labelBox[0];
- $labelX = $itemX - $labelWidth / 2;
- $labelY = $gridBottom + $this->labelMargin + $this->fontSize;
- $labelX = (int) $labelX;
- $labelY = (int) $labelY;
- $labelText = (((mb_strlen($key, 'UTF-8') > $this->xLabelLen))) ? mb_substr($key, 0, $this->xLabelLen, 'utf-8') . $this->cutSuffix : $key;
- imagettftext($chart, $this->fontSize, 0, $labelX, $labelY, $labelColor, $this->font, $labelText);
- }
- } else {
- // or just draw each column label
- $labelBox = imagettfbbox($this->fontSize, 0, $this->font, $key);
- $labelWidth = $labelBox[4] - $labelBox[0];
- $labelX = $itemX - $labelWidth / 2;
- $labelY = $gridBottom + $this->labelMargin + $this->fontSize;
- $labelX = (int) $labelX;
- $labelY = (int) $labelY;
- $labelText = (((mb_strlen($key, 'UTF-8') > $this->xLabelLen))) ? mb_substr($key, 0, $this->xLabelLen, 'utf-8') . $this->cutSuffix : $key;
- imagettftext($chart, $this->fontSize, 0, $labelX, $labelY, $labelColor, $this->font, $labelText);
- }
- }
- $itemX += $barSpacing;
- }
- // Optional chart chartTitle?
- if ($this->chartTitle) {
- $titleX = ($this->imageWidth - $this->gridLeft) / 2.3;
- imagettftext($chart, $this->fontSize + 8, 0, (int) $titleX, 24, $labelColor, $this->font, $this->chartTitle);
- }
- // Rendering custom Y-axis label
- if ($this->yAxisName) {
- $yAxisX = $this->gridLeft - 40;
- $yAxisY = (int) $this->gridTop - 10;
- imagettftext($chart, $this->fontSize, 0, $yAxisX, $yAxisY, $labelColor, $this->font, $this->yAxisName);
- }
- // Rendering of data set peak value?
- if ($this->displayPeakValue) {
- $peakX = (int) ($this->imageWidth - $this->gridLeft) - 150;
- $peakY = (int) $this->imageHeight - ($this->fontSize * 0.5);
- $peakLabel = ($this->yAxisName) ? round($dataMax, 3) . ' ' . $this->yAxisName : round($dataMax, 3);
- imagettftext($chart, $this->fontSize, 0, $peakX, $peakY, $labelColor, $this->font, 'Max: ' . $peakLabel);
- }
- // Rendering chart legend
- if (!empty($this->chartLegend)) {
- $lWidth = 20;
- foreach ($customColors as $colorIndex => $customColor) {
- if (isset($this->chartLegend[$colorIndex])) {
- $rawLabel = $this->chartLegend[$colorIndex];
- $legendText = (((mb_strlen($rawLabel, 'UTF-8') > $this->xLabelLen + 3))) ? mb_substr($rawLabel, 0, $this->xLabelLen + 3, 'utf-8') . '...' : $rawLabel;
- $offset = $colorIndex * 10;
- $y1 = $this->imageHeight - 5;
- $y2 = $this->imageHeight - 20;
- $x1 = $offset * 10 + $lWidth;
- $x2 = $x1 + $lWidth;
- $x1 = (int) $x1;
- $y1 = (int) $y1;
- $x2 = (int) $x2;
- $y2 = (int) $y2;
- $labelX = $x2 + 5;
- imagefilledrectangle($chart, $x1, $y1, $x2, $y2, $customColor);
- imagettftext($chart, $this->fontSize, 0, $labelX, $y1 - 2, $labelColor, $this->font, $legendText);
- }
- }
- }
- if ($this->debug) {
- //chart generation end timing
- $mtime = explode(' ', microtime());
- $totaltime = $mtime[0] + $mtime[1] - $starttime;
- $debugX = $this->imageWidth - 150;
- $totalBars = $drawCalls + $drawSkip;
- $totalBars = ($totalBars != 0) ? $totalBars : 1;
- $skipPercent = round((($drawCalls / $totalBars) * 100), 2);
- imagettftext($chart, 8, 0, $debugX, 10, $labelColor, $this->font, 'DS: ' . $dataSize . ' items');
- imagettftext($chart, 8, 0, $debugX, 22, $labelColor, $this->font, 'DC: ' . $drawCalls . ' bars (' . $skipPercent . '%)');
- imagettftext($chart, 8, 0, $debugX, 34, $labelColor, $this->font, 'GT: ' . round($totaltime, 5) . ' sec.');
- }
- if (empty($fileName)) {
- //browser output
- header('Content-Type: image/png');
- $result = imagepng($chart);
- imagedestroy($chart);
- die();
- } else {
- if (strpos($fileName, 'base64') !== false) {
- //encode image as base64 data
- $htmlOutput = (strpos($fileName, 'base64html') !== false) ? true : false;
- $result = $this->getChartBase($chart, $htmlOutput);
- } else {
- //just save as PNG file
- $result = imagepng($chart, $fileName);
- imagedestroy($chart);
- }
- }
- return ($result);
- }
- /**
- * Returns current chart as base64 encoded text
- *
- * @param GdImage $image chart image instance to export
- * @param bool $htmlData data ready to embed as img src HTML base64 data (data URI scheme)
- *
- * @return void
- */
- public function getChartBase($image, $htmlData = false) {
- $result = '';
- $type = 'png';
- $quality = -1;
- if ($image) {
- ob_start();
- imagesavealpha($image, true);
- $result = imagepng($image, null, $quality);
- imagedestroy($image);
- $imageBody = ob_get_contents();
- ob_end_clean();
- if (!empty($imageBody)) {
- $result = base64_encode($imageBody);
- }
- //optional html embed data
- if ($htmlData) {
- $result = 'data:image/' . $type . ';charset=utf-8;base64,' . $result;
- }
- } else {
- throw new Exception('EX_VOID_CHART');
- }
- return ($result);
- }
- }
|