Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Pie chart #2

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
271 changes: 267 additions & 4 deletions GnuPlot.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ class GnuPlot
{
// Values as an array
protected $values = array();

// Values as an array
protected $pieValues = array();

// Time format if X data is time
protected $timeFormat = null;
Expand Down Expand Up @@ -47,6 +50,33 @@ class GnuPlot
protected $process;
protected $stdin;
protected $stdout;

// Pie chart scale
protected $pieScale = 0.25;

// Pie chart position on paper
protected $piePosition = 0.5;

// Pie chart a
protected $pieS = 0.05;

// Pie Chart colors
protected $colors = array('#585C00', '#750400', '#A2A811', '#2474B5', '#F5140C');

// Pie Chart label row height
protected $labelRowHeight = 40;

// Pie Chart label font size
protected $labelFontSize = 16;

// Pie Chart font location
protected $font = ""; //img/fonts/TahomaRegular.ttf

// Pie Chart font color
protected $fontColor = "#333333";

// Pie Chart legend color
protected $legendColor = "#ffffff";

public function __construct()
{
Expand All @@ -57,6 +87,8 @@ public function __construct()
public function __destruct()
{
$this->sendCommand('quit');
fclose($this->stdin);
fclose($this->stdout);
proc_close($this->process);
}

Expand Down Expand Up @@ -192,14 +224,23 @@ protected function sendInit()
/**
* Runs the plot to the given pipe
*/
public function plot($replot = false)
public function plot($pieChart = false, $replot = false)
{
if ($replot) {
$this->sendCommand('replot');
} else {
$this->sendCommand('plot '.$this->getUsings());
if(!$pieChart){
$this->sendCommand('plot '.$this->getUsings());
}
}
$this->plotted = true;

if($pieChart){
$this->sendPieData();
$this->sendCommand('plot '.$this->getUsings($pieChart));
return ;
}

$this->sendData();
}

Expand Down Expand Up @@ -238,6 +279,11 @@ public function get()
return $result;
}


// private function readStream(){
//
// }

/**
* Display the plot
*/
Expand Down Expand Up @@ -312,8 +358,12 @@ public function enableHistogram()
/**
* Gets the "using" line
*/
protected function getUsings()
protected function getUsings($pieChart = false)
{
if($pieChart){
return "2";
}

$usings = array();

for ($i=0; $i<count($this->values); $i++) {
Expand Down Expand Up @@ -371,4 +421,217 @@ protected function openPipe()
$this->stdin = $pipes[0];
$this->stdout = $pipes[1];
}
}

/**
* Sets the pie chart label font size
*/
public function setPieLabelFontSize($labelFontSize){
$this->labelFontSize = $labelFontSize;

return $this;
}

/**
* Sets label of the pie chart data. If index is null it sets last
* inserted data title else it sets title for specified $index data;
*/
public function setPieLabel($title, $index = null){
if(!$index){
$this->titles[] = $title;
return $this;
}

$this->titles[$index] = $title;
return $this;
}

/**
* Sets pie chart scale
*/
public function setPieScale($pieScale){
$this->pieScale = $pieScale;

return $this;
}

/**
* Sets pie chart scale
*/
public function setFontColor($fontColor){
$this->fontColor = $fontColor;

return $this;
}

/**
* Sets pie chart scale
*/
public function setLegendColor($legendColor){
$this->legendColor = $legendColor;

return $this;
}

/**
* Push a new data for pie chart. $value is a float number betwean 0 and 1.
*/
public function pushPie($value, $index = null){
if(!$index){
$this->pieValues[] = $value;
return $this;
}

$this->pieValues[$index] = $value;
return $this;
}


/**
* Sends all the command to the given pipe to give it the
* current data
*/
protected function sendPieData()
{
$lVal = 0;
$cVal = 0;
foreach ($this->values as $index => $value)
{
$cVal = $lVal + $value*360;
if($index == (sizeof($this->values) - 1 ))
$cVal = 360;

$this->sendCommand('set obj ' . ($index+1) . ' circle arc [' . $lVal . ':' . $cVal . '] fc rgb "' . $this->colors[$index] . '" ');
$this->sendCommand('set obj ' . ($index+1) . ' circle at screen ' . $this->piePosition . ',' . $this->piePosition . ' size screen ' . $this->pieScale . ' front');

$lVal = $cVal;
}
$this->sendCommand('e');
}

/**
* Prepares pie chart data to send
*/
protected function preparePieData(){
$sum = 0;
$n = sizeof($this->pieValues);

for($i = 0; $i < $n; $i++){
$sum += $this->pieValues[$i];
}

foreach ($this->pieValues as $key => $value){
$this->values[$key] = ($value/$sum);
}
}

protected function sendPieInit(){
if(!sizeof($this->values))
return false;

if ($this->title) {
$this->sendCommand('set title "'.$this->title.'"');
}

$this->sendCommand('reset');
$this->sendCommand('unset border');
$this->sendCommand('unset tics');
$this->sendCommand('unset key');
$this->sendCommand('set angles degree');
$this->sendCommand('set yrange [0:1]');
$this->sendCommand('set style fill solid 1.0 border -2');
}

/**
* Write the current plot to a file
*/
public function getPieChart()
{
$this->preparePieData();
$this->sendPieInit();
$this->sendCommand('set terminal png size '.$this->width.','.$this->height);
fflush($this->stdout);
$this->plot(true);

// Reading data, timeout=100ms
$result = '';
$timeout = 100;
do {
stream_set_blocking($this->stdout, false);
$data = fread($this->stdout, 128);
$result .= $data;
usleep(5000);
$timeout -= 5;
} while ($timeout>0 || $data);

$imgChart = imagecreatefromstring($result);
$imgLabel = $this->getLabelImg();

$hheight = imagesy($imgLabel);

imagecopy($imgLabel, $imgChart, 0, 0, 0, 0, $this->width, $hheight);

$this->drawLabels($imgLabel);

return imagepng($imgLabel);
}

protected function getLabelImg(){
$height = $this->height + sizeof($this->titles) * $this->labelRowHeight;

$image = imagecreatetruecolor($this->width, $height);
$white = imagecolorallocatealpha($image, 255, 255, 255, 127);
imagefill($image, 0, 0, $white);
return $image;
}

protected function drawLabels($image){
$rgb = $this->hexToRGB($this->fontColor);
$fontColor = imagecolorallocate($image, $rgb['r'], $rgb['g'], $rgb['b']);

$rgb = $this->hexToRGB($this->legendColor);
$legendColor = imagecolorallocate($image, $rgb['r'], $rgb['g'], $rgb['b']);

$x1 = 20;
$x2 = 40;
$labelX = 10;

imagefilledrectangle($image, $labelX, $this->height-$labelX, $this->width - $labelX, imagesy($image)-3, $legendColor);

foreach ($this->titles as $key => $value) {
$rgb = $this->hexToRGB($this->colors[$key]);
$color = imagecolorallocate($image, $rgb['r'], $rgb['g'], $rgb['b']);

$y = $this->height + $key * $this->labelRowHeight;
$y2 = $y + 30;

$value .= ' ' . round($this->values[$key]*100, 2) . '%';

if($this->font){
imagettftext($image, $this->labelFontSize, 0, $x2+8, $y2-7, $fontColor, $this->font, $value);
} else {
imagestring($image, $this->labelFontSize, $x2+8, $y+8, $value, $fontColor);
}

imagefilledrectangle($image, $x1, $y, $x2, $y2, $color);
}
}

protected function hexToRGB ($hexColor){
if( preg_match( '/^#?([a-h0-9]{2})([a-h0-9]{2})([a-h0-9]{2})$/i', $hexColor, $matches ) )
{
return array(
'r' => hexdec( $matches[ 1 ] ),
'g' => hexdec( $matches[ 2 ] ),
'b' => hexdec( $matches[ 3 ] )
);
}
else
{
return array(
'r' => 0,
'g' => 0,
'b' => 0
);
}
}
}
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,24 @@ run `realTime.php` for example:
$plot->refresh();
```

PIE CHART USAGE
===
```php
<?php
$plot = new GnuPlot;

$plot->setHeight(400);
$plot->setWidth(400);

$plot->pushPie(50)->setPieLabel('1950');
$plot->pushPie(100)->setPieLabel('2000');
$plot->pushPie(150)->setPieLabel('2050');

header('Content-type: image/png');
echo $plot->getPieChart();
```


API
===

Expand All @@ -105,6 +123,8 @@ API
* `setHeight($height)`, sets the width of the graph
* `addLabel($x, $y, $text)`, add some label at a point



License
=======

Expand Down