PHP - ImageMagick command line Pie Chart
This code was converted from a bash version to create pie charts. It is much faster and does not require bc on the server.
PHP is used to create the ImageMagick command line.
This code creates pie chart and legend images which can then be placed on a web page or added in to a document.
To call the code, create an array of values, instantiate the GFX objects, establish the label_color_map as an associative array where the label text is the key and the value is a hex color code, and finally create the chart, sending a name and the data array, like so:
$data = array(50, 70, 100, 3, 49);
$chart = new GFX();
$chart->label_color_map(array('one' => '#1c28a1',
'two' => '#600087',
'three' => '#107a3f',
'four' => '#bf0000',
'five' => '#ff6d00'));
$chart->piechart('project',$data);
<?php
Class GFX extends Base {
public function __construct($parms = null) {
$this->_properties = array('centerx','centery','width','height',
'radius');
if (!is_array($parms)) {
$parms['width'] = $parms ['height'] = 330;
$parms['centerx'] = $parms['centery'] = 160;
$parms['radius'] = 135;
}
parent::__construct($parms);
}
public function label_color_map ($map = array()) {
$this->_data['labels'] = array();
foreach ($map as $k => $v) {
$this->_data['labels'][$k] = $v;
}
}
public function piechart($name = null, $data = array()) {
// Thanks to: http://jbkflex.wordpress.com/2011/07/28/creating-a-svg-pie-chart-html5/
if ($name === null) return;
$total = array_sum($data);
$max=0;$kmax='None';
foreach ($data as $k => $v) {
$value[$k] = (int)(($v/$total) * 100);
if ($value[$k] > $max) {
$kmax=$k;
$max=$value[$k];
}
}
while (array_sum($value) < 100) {
$value[$kmax]++;
}
foreach ($data as $k => $v) {
$value[$k] = (int)(($v/$total) * 100);
if ($value[$k] > $max) {
$kmax=$k;
$max=$value[$k];
}
}
while (array_sum($value) < 100) {
$value[$kmax]++;
}
$centerx = $this->_data['centerx'];
$centery = $this->_data['centery'];
$radius= $this->_data['radius'];
$count=0;
$startAngle=0;
$endAngle=0;
$arc=0;
$x1=0;
$x2=0;
$y1=0;
$y2=0;
$pi=pi();
$cmd='convert -size '.$this->_data['width'].'x'.$this->_data['height'].' xc:white -stroke white -strokewidth 5 ';
foreach ($value as $k => $v) {
$startAngle=$endAngle;
$endAngle=$startAngle+(360*$v/100);
$theta = $pi*$startAngle/180;
$x1=$centerx+$radius*cos($theta);
$y1=$centery+$radius*sin($theta);
$theta = $pi*$endAngle/180;
$x2=$centerx+$radius*cos($theta);
$y2=$centery+$radius*sin($theta);
$arc = ($v >= 50) ? '1' : '0';
$cmd.=' -fill "'.$this->_data['labels'][$k].'" -draw "path \'M '.$centerx.','.$centery.' L '.$x1.','.$y1.
' A '.$radius.','.$radius.' 0 '.$arc.',1 '.$x2.','.$y2.' Z"';
$count++;
}
$cmd.=' '.escapeshellarg(_GFX_DIR_.'/'.$name.'_chart.jpg');
`$cmd`;
if (!is_array($this->_data['labels'])) return;
$KEY_SIZE=20;
$MARGIN=5;
$TEXT_X=$KEY_SIZE+$MARGIN;
$height = $TEXT_X * count($value);
$cmd = 'convert -size 135x'.$height.' xc:white -fill white ';
$label = " -font 'Nimbus-Sans-Bold' -stroke none -pointsize 12 ";
$count=0;
$y1=5;
foreach ($value as $k => $v) {
$y2=$y1+$KEY_SIZE;
$y3=$y2-$MARGIN;
$label.=' -fill "'.$this->_data['labels'][$k].'" -draw "rectangle 0,'.$y1.' '.$KEY_SIZE.','.$y2.'"'.
' -draw "text '.$TEXT_X.','.$y3.' '.escapeshellarg(/*$data[$k].' '.*/$v.'% '.$k).'"';
$count++;
$y1=$y1+$KEY_SIZE+$MARGIN;
}
$cmd.= $label.' '.escapeshellarg(_GFX_DIR_.'/'.$name.'_legend.jpg');
`$cmd`;
}
}
<?php
Abstract Class Base {
protected $_properties;
protected $_data;
protected $_valid = false;
protected $_error_message = array();
function __construct($props) {
$this->_data = array_fill_keys($this->_properties, null);
$this->_data = array_merge($this->_data, $props);
}
function __get($property) {
return isset($this->_data[$property]) ? $this->_data[$property] : null;
}
function __set($property, $value) {
$this->_data[$property] = $value;
}
function isValid($property = null) {
if ($property === null)
return $this->_valid || (count($this->_error_message) == 0);
else
return !isset($this->_error_message[$property]);
}
function error($property) {
if (isset($this->_error_message[$property])) {
return $this->_error_message[$property];
} else {
return '';
}
}
}
Many thanks to the link above for the chart algorithm.
This post courtesy of Worktrainer.
Print article | This entry was posted by elvis on 02/11/13 at 06:06:00 pm . Follow any responses to this post through RSS 2.0. |