PageRenderTime 44ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/MantisBT/library/ezc/Graph/src/charts/pie.php

https://bitbucket.org/crypticrod/sr_wp_code
PHP | 308 lines | 147 code | 32 blank | 129 comment | 14 complexity | fcf789b1debe650156989e6796cea3bc MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0, LGPL-2.1, GPL-3.0, LGPL-2.0, AGPL-3.0
  1. <?php
  2. /**
  3. * File containing the ezcGraphPieChart class
  4. *
  5. * @package Graph
  6. * @version 1.5
  7. * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
  8. * @license http://ez.no/licenses/new_bsd New BSD License
  9. */
  10. /**
  11. * Class for pie charts. Can only use one dataset which will be dispalyed as a
  12. * pie chart.
  13. *
  14. * <code>
  15. * // Create a new pie chart
  16. * $chart = new ezcGraphPieChart();
  17. *
  18. * // Add data to line chart
  19. * $chart->data['sample dataset'] = new ezcGraphArrayDataSet(
  20. * array(
  21. * 'one' => 1.2,
  22. * 'two' => 43.2,
  23. * 'three' => -34.14,
  24. * 'four' => 65,
  25. * 'five' => 123,
  26. * )
  27. * );
  28. *
  29. * // Render chart with default 2d renderer and default SVG driver
  30. * $chart->render( 500, 200, 'pie_chart.svg' );
  31. * </code>
  32. *
  33. * Each chart consists of several chart elements which represents logical
  34. * parts of the chart and can be formatted independently. The pie chart
  35. * consists of:
  36. * - title ( {@link ezcGraphChartElementText} )
  37. * - legend ( {@link ezcGraphChartElementLegend} )
  38. * - background ( {@link ezcGraphChartElementBackground} )
  39. *
  40. * All elements can be configured by accessing them as properties of the chart:
  41. *
  42. * <code>
  43. * $chart->legend->position = ezcGraph::RIGHT;
  44. * </code>
  45. *
  46. * The chart itself also offers several options to configure the appearance.
  47. * The extended configure options are available in
  48. * {@link ezcGraphPieChartOptions} extending the {@link ezcGraphChartOptions}.
  49. *
  50. * @property ezcGraphPieChartOptions $options
  51. * Chart options class
  52. *
  53. * @version 1.5
  54. * @package Graph
  55. * @mainclass
  56. */
  57. class ezcGraphPieChart extends ezcGraphChart
  58. {
  59. /**
  60. * Constructor
  61. *
  62. * @param array $options Default option array
  63. * @return void
  64. * @ignore
  65. */
  66. public function __construct( array $options = array() )
  67. {
  68. $this->options = new ezcGraphPieChartOptions( $options );
  69. parent::__construct( $options );
  70. $this->data = new ezcGraphChartSingleDataContainer( $this );
  71. }
  72. /**
  73. * Render the assigned data
  74. *
  75. * Will renderer all charts data in the remaining boundings after drawing
  76. * all other chart elements. The data will be rendered depending on the
  77. * settings in the dataset.
  78. *
  79. * @param ezcGraphRenderer $renderer Renderer
  80. * @param ezcGraphBoundings $boundings Remaining boundings
  81. * @return void
  82. */
  83. protected function renderData( ezcGraphRenderer $renderer, ezcGraphBoundings $boundings )
  84. {
  85. // Only draw the first (and only) dataset
  86. $dataset = $this->data->rewind();
  87. $datasetName = $this->data->key();
  88. $this->driver->options->font = $this->options->font;
  89. // Calculate sum of all values to be able to calculate percentage
  90. $sum = 0;
  91. foreach ( $dataset as $name => $value )
  92. {
  93. if ( $value < 0 )
  94. {
  95. throw new ezcGraphInvalidDataException( "Values >= 0 required, '$name' => '$value'." );
  96. }
  97. $sum += $value;
  98. }
  99. if ( $this->options->sum !== false )
  100. {
  101. $sum = max( $sum, $this->options->sum );
  102. }
  103. if ( $sum <= 0 )
  104. {
  105. throw new ezcGraphInvalidDataException( "Pie charts require a value sum > 0, your value: '$sum'." );
  106. }
  107. $angle = 0;
  108. foreach ( $dataset as $label => $value )
  109. {
  110. // Skip rendering values which equals 0
  111. if ( $value <= 0 )
  112. {
  113. continue;
  114. }
  115. switch ( $dataset->displayType->default )
  116. {
  117. case ezcGraph::PIE:
  118. $displayLabel = ( $this->options->labelCallback !== null
  119. ? call_user_func( $this->options->labelCallback, $label, $value, $value / $sum )
  120. : sprintf( $this->options->label, $label, $value, $value / $sum * 100 ) );
  121. $renderer->drawPieSegment(
  122. $boundings,
  123. new ezcGraphContext( $datasetName, $label, $dataset->url[$label] ),
  124. $dataset->color[$label],
  125. $angle,
  126. $angle += $value / $sum * 360,
  127. $displayLabel,
  128. $dataset->highlight[$label]
  129. );
  130. break;
  131. default:
  132. throw new ezcGraphInvalidDisplayTypeException( $dataset->displayType->default );
  133. break;
  134. }
  135. }
  136. }
  137. /**
  138. * Returns the default display type of the current chart type.
  139. *
  140. * @return int Display type
  141. */
  142. public function getDefaultDisplayType()
  143. {
  144. return ezcGraph::PIE;
  145. }
  146. /**
  147. * Apply tresh hold
  148. *
  149. * Iterates over the dataset and applies the configured tresh hold to
  150. * the datasets data.
  151. *
  152. * @return void
  153. */
  154. protected function applyThreshold()
  155. {
  156. if ( $this->options->percentThreshold || $this->options->absoluteThreshold )
  157. {
  158. $dataset = $this->data->rewind();
  159. $sum = 0;
  160. foreach ( $dataset as $value )
  161. {
  162. $sum += $value;
  163. }
  164. if ( $this->options->sum !== false )
  165. {
  166. $sum = max( $sum, $this->options->sum );
  167. }
  168. $unset = array();
  169. foreach ( $dataset as $label => $value )
  170. {
  171. if ( $label === $this->options->summarizeCaption )
  172. {
  173. continue;
  174. }
  175. if ( ( $value <= $this->options->absoluteThreshold ) ||
  176. ( ( $value / $sum ) <= $this->options->percentThreshold ) )
  177. {
  178. if ( !isset( $dataset[$this->options->summarizeCaption] ) )
  179. {
  180. $dataset[$this->options->summarizeCaption] = $value;
  181. }
  182. else
  183. {
  184. $dataset[$this->options->summarizeCaption] += $value;
  185. }
  186. $unset[] = $label;
  187. }
  188. }
  189. foreach ( $unset as $label )
  190. {
  191. unset( $dataset[$label] );
  192. }
  193. }
  194. }
  195. /**
  196. * Renders the basic elements of this chart type
  197. *
  198. * @param int $width
  199. * @param int $height
  200. * @return void
  201. */
  202. protected function renderElements( $width, $height )
  203. {
  204. if ( !count( $this->data ) )
  205. {
  206. throw new ezcGraphNoDataException();
  207. }
  208. // Set image properties in driver
  209. $this->driver->options->width = $width;
  210. $this->driver->options->height = $height;
  211. // Apply tresh hold
  212. $this->applyThreshold();
  213. // Generate legend
  214. $this->elements['legend']->generateFromDataSet( $this->data->rewind() );
  215. // Get boundings from parameters
  216. $this->options->width = $width;
  217. $this->options->height = $height;
  218. $boundings = new ezcGraphBoundings();
  219. $boundings->x1 = $this->options->width;
  220. $boundings->y1 = $this->options->height;
  221. // Render subelements
  222. foreach ( $this->elements as $name => $element )
  223. {
  224. // Skip element, if it should not get rendered
  225. if ( $this->renderElement[$name] === false )
  226. {
  227. continue;
  228. }
  229. $this->driver->options->font = $element->font;
  230. $boundings = $element->render( $this->renderer, $boundings );
  231. }
  232. // Render graph
  233. $this->renderData( $this->renderer, $boundings );
  234. }
  235. /**
  236. * Render the pie chart
  237. *
  238. * Renders the chart into a file or stream. The width and height are
  239. * needed to specify the dimensions of the resulting image. For direct
  240. * output use 'php://stdout' as output file.
  241. *
  242. * @param int $width Image width
  243. * @param int $height Image height
  244. * @param string $file Output file
  245. * @apichange
  246. * @return void
  247. */
  248. public function render( $width, $height, $file = null )
  249. {
  250. $this->renderElements( $width, $height );
  251. if ( !empty( $file ) )
  252. {
  253. $this->renderer->render( $file );
  254. }
  255. $this->renderedFile = $file;
  256. }
  257. /**
  258. * Renders this chart to direct output
  259. *
  260. * Does the same as ezcGraphChart::render(), but renders directly to
  261. * output and not into a file.
  262. *
  263. * @param int $width
  264. * @param int $height
  265. * @apichange
  266. * @return void
  267. */
  268. public function renderToOutput( $width, $height )
  269. {
  270. // @TODO: merge this function with render an deprecate ommit of third
  271. // argument in render() when API break is possible
  272. $this->renderElements( $width, $height );
  273. $this->renderer->render( null );
  274. }
  275. }
  276. ?>