PageRenderTime 53ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/artichow/inc/Label.class.php

https://bitbucket.org/jstechnologies/cats
PHP | 679 lines | 275 code | 136 blank | 268 comment | 35 complexity | 0d4a408d1889aeb3c84e93ba0602ea67 MD5 | raw file
  1. <?php
  2. /*
  3. * This work is hereby released into the Public Domain.
  4. * To view a copy of the public domain dedication,
  5. * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
  6. * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
  7. *
  8. */
  9. /**
  10. * Draw labels
  11. *
  12. * @package Artichow
  13. */
  14. class awLabel implements awPositionable {
  15. /**
  16. * Label border
  17. *
  18. * @var int
  19. */
  20. public $border;
  21. /**
  22. * Label texts
  23. *
  24. * @var array
  25. */
  26. protected $texts;
  27. /**
  28. * Text font
  29. *
  30. * @var int
  31. */
  32. protected $font;
  33. /**
  34. * Text angle
  35. *
  36. * @var int
  37. */
  38. protected $angle = 0;
  39. /**
  40. * Text color
  41. *
  42. * @var Color
  43. */
  44. protected $color;
  45. /**
  46. * Text background
  47. *
  48. * @var Color, Gradient
  49. */
  50. private $background;
  51. /**
  52. * Callback function
  53. *
  54. * @var string
  55. */
  56. private $function;
  57. /**
  58. * Padding
  59. *
  60. * @var int
  61. */
  62. private $padding;
  63. /**
  64. * Move position from this vector
  65. *
  66. * @var Point
  67. */
  68. protected $move;
  69. /**
  70. * Label interval
  71. *
  72. * @var int
  73. */
  74. protected $interval = 1;
  75. /**
  76. * Horizontal align
  77. *
  78. * @var int
  79. */
  80. protected $hAlign = awLabel::CENTER;
  81. /**
  82. * Vertical align
  83. *
  84. * @var int
  85. */
  86. protected $vAlign = awLabel::MIDDLE;
  87. /**
  88. * Hide all labels ?
  89. *
  90. * @var bool
  91. */
  92. protected $hide = FALSE;
  93. /**
  94. * Keys to hide
  95. *
  96. * @var array
  97. */
  98. protected $hideKey = array();
  99. /**
  100. * Values to hide
  101. *
  102. * @var array
  103. */
  104. protected $hideValue = array();
  105. /**
  106. * Hide first label
  107. *
  108. * @var bool
  109. */
  110. protected $hideFirst = FALSE;
  111. /**
  112. * Hide last label
  113. *
  114. * @var bool
  115. */
  116. protected $hideLast = FALSE;
  117. /**
  118. * Build the label
  119. *
  120. * @param string $label First label
  121. */
  122. public function __construct($label = NULL, $font = NULL, $color = NULL, $angle = 0) {
  123. if(is_array($label)) {
  124. $this->set($label);
  125. } else if(is_string($label)) {
  126. $this->set(array($label));
  127. }
  128. if($font === NULL) {
  129. $font = new awFont2;
  130. }
  131. $this->setFont($font);
  132. $this->setAngle($angle);
  133. if($color instanceof awColor) {
  134. $this->setColor($color);
  135. } else {
  136. $this->setColor(new awColor(0, 0, 0));
  137. }
  138. $this->move = new awPoint(0, 0);
  139. $this->border = new awBorder;
  140. $this->border->hide();
  141. }
  142. /**
  143. * Get an element of the label from its key
  144. *
  145. * @param int $key Element key
  146. * @return string A value
  147. */
  148. public function get($key) {
  149. return array_key_exists($key, $this->texts) ? $this->texts[$key] : NULL;
  150. }
  151. /**
  152. * Get all labels
  153. *
  154. * @return array
  155. */
  156. public function all() {
  157. return $this->texts;
  158. }
  159. /**
  160. * Set one or several labels
  161. *
  162. * @param array $labels Array of string or a string
  163. */
  164. public function set($labels) {
  165. if(is_string($labels)) {
  166. $this->texts = array($labels);
  167. } else if(is_array($labels)) {
  168. $this->texts = $labels;
  169. }
  170. }
  171. /**
  172. * Count number of texts in the label
  173. *
  174. * @return int
  175. */
  176. public function count() {
  177. return is_array($this->texts) ? count($this->texts) : 0;
  178. }
  179. /**
  180. * Set a callback function for labels
  181. *
  182. * @param string $function
  183. */
  184. public function setCallbackFunction($function) {
  185. $this->function = is_null($function) ? $function : (string)$function;
  186. }
  187. /**
  188. * Return the callback function for labels
  189. *
  190. * @return string
  191. */
  192. public function getCallbackFunction() {
  193. return $this->function;
  194. }
  195. /**
  196. * Change labels format
  197. *
  198. * @param string $format New format (printf style: %.2f for example)
  199. */
  200. public function setFormat($format) {
  201. $function = 'label'.time().'_'.(microtime() * 1000000);
  202. eval('function '.$function.'($value) {
  203. return sprintf("'.addcslashes($format, '"').'", $value);
  204. }');
  205. $this->setCallbackFunction($function);
  206. }
  207. /**
  208. * Change font for label
  209. *
  210. * @param awFont $font New font
  211. * @param awColor $color Font color (can be NULL)
  212. */
  213. public function setFont(awFont $font, $color = NULL) {
  214. $this->font = $font;
  215. if($color instanceof awColor) {
  216. $this->setColor($color);
  217. }
  218. }
  219. /**
  220. * Change font angle
  221. *
  222. * @param int $angle New angle
  223. */
  224. public function setAngle($angle) {
  225. $this->angle = (int)$angle;
  226. }
  227. /**
  228. * Change font color
  229. *
  230. * @param awColor $color
  231. */
  232. public function setColor($color) {
  233. $this->color = $color;
  234. }
  235. /**
  236. * Change text background
  237. *
  238. * @param mixed $background
  239. */
  240. public function setBackground($background) {
  241. $this->background = $background;
  242. }
  243. /**
  244. * Change text background color
  245. *
  246. * @param Color
  247. */
  248. public function setBackgroundColor(awColor $color) {
  249. $this->background = $color;
  250. }
  251. /**
  252. * Change text background gradient
  253. *
  254. * @param Gradient
  255. */
  256. public function setBackgroundGradient(awGradient $gradient) {
  257. $this->background = $gradient;
  258. }
  259. /**
  260. * Change padding
  261. *
  262. * @param int $left Left padding
  263. * @param int $right Right padding
  264. * @param int $top Top padding
  265. * @param int $bottom Bottom padding
  266. */
  267. public function setPadding($left, $right, $top, $bottom) {
  268. $this->padding = array((int)$left, (int)$right, (int)$top, (int)$bottom);
  269. }
  270. /**
  271. * Hide all labels ?
  272. *
  273. * @param bool $hide
  274. */
  275. public function hide($hide = TRUE) {
  276. $this->hide = (bool)$hide;
  277. }
  278. /**
  279. * Show all labels ?
  280. *
  281. * @param bool $show
  282. */
  283. public function show($show = TRUE) {
  284. $this->hide = (bool)!$show;
  285. }
  286. /**
  287. * Hide a key
  288. *
  289. * @param int $key The key to hide
  290. */
  291. public function hideKey($key) {
  292. $this->hideKey[$key] = TRUE;
  293. }
  294. /**
  295. * Hide a value
  296. *
  297. * @param int $value The value to hide
  298. */
  299. public function hideValue($value) {
  300. $this->hideValue[] = $value;
  301. }
  302. /**
  303. * Hide first label
  304. *
  305. * @param bool $hide
  306. */
  307. public function hideFirst($hide) {
  308. $this->hideFirst = (bool)$hide;
  309. }
  310. /**
  311. * Hide last label
  312. *
  313. * @param bool $hide
  314. */
  315. public function hideLast($hide) {
  316. $this->hideLast = (bool)$hide;
  317. }
  318. /**
  319. * Set label interval
  320. *
  321. * @param int
  322. */
  323. public function setInterval($interval) {
  324. $this->interval = (int)$interval;
  325. }
  326. /**
  327. * Change label position
  328. *
  329. * @param int $x Add this interval to X coord
  330. * @param int $y Add this interval to Y coord
  331. */
  332. public function move($x, $y) {
  333. $this->move = $this->move->move($x, $y);
  334. }
  335. /**
  336. * Change alignment
  337. *
  338. * @param int $h Horizontal alignment
  339. * @param int $v Vertical alignment
  340. */
  341. public function setAlign($h = NULL, $v = NULL) {
  342. if($h !== NULL) {
  343. $this->hAlign = (int)$h;
  344. }
  345. if($v !== NULL) {
  346. $this->vAlign = (int)$v;
  347. }
  348. }
  349. /**
  350. * Get a text from the labele
  351. *
  352. * @param mixed $key Key in the array text
  353. * @return Text
  354. */
  355. public function getText($key) {
  356. if(is_array($this->texts) and array_key_exists($key, $this->texts)) {
  357. $value = $this->texts[$key];
  358. if(is_string($this->function)) {
  359. $value = call_user_func($this->function, $value);
  360. }
  361. $text = new awText($value);
  362. $text->setFont($this->font);
  363. $text->setAngle($this->angle);
  364. $text->setColor($this->color);
  365. if($this->background instanceof awColor) {
  366. $text->setBackgroundColor($this->background);
  367. } else if($this->background instanceof awGradient) {
  368. $text->setBackgroundGradient($this->background);
  369. }
  370. $text->border = $this->border;
  371. if($this->padding !== NULL) {
  372. call_user_func_array(array($text, 'setPadding'), $this->padding);
  373. }
  374. return $text;
  375. } else {
  376. return NULL;
  377. }
  378. }
  379. /**
  380. * Get max width of all texts
  381. *
  382. * @param awDrawer $drawer A drawer
  383. * @return int
  384. */
  385. public function getMaxWidth(awDrawer $drawer) {
  386. return $this->getMax($drawer, 'getTextWidth');
  387. }
  388. /**
  389. * Get max height of all texts
  390. *
  391. * @param awDrawer $drawer A drawer
  392. * @return int
  393. */
  394. public function getMaxHeight(awDrawer $drawer) {
  395. return $this->getMax($drawer, 'getTextHeight');
  396. }
  397. /**
  398. * Draw the label
  399. *
  400. * @param awDrawer $drawer
  401. * @param awPoint $p Label center
  402. * @param int $key Text position in the array of texts (default to zero)
  403. */
  404. public function draw(awDrawer $drawer, awPoint $p, $key = 0) {
  405. if(($key % $this->interval) !== 0) {
  406. return;
  407. }
  408. // Hide all labels
  409. if($this->hide) {
  410. return;
  411. }
  412. // Key is hidden
  413. if(array_key_exists($key, $this->hideKey)) {
  414. return;
  415. }
  416. // Hide first label
  417. if($key === 0 and $this->hideFirst) {
  418. return;
  419. }
  420. // Hide last label
  421. if($key === count($this->texts) - 1 and $this->hideLast) {
  422. return;
  423. }
  424. $text = $this->getText($key);
  425. if($text !== NULL) {
  426. // Value must be hidden
  427. if(in_array($text->getText(), $this->hideValue)) {
  428. return;
  429. }
  430. $x = $p->x;
  431. $y = $p->y;
  432. // Get padding
  433. list($left, $right, $top, $bottom) = $text->getPadding();
  434. $font = $text->getFont();
  435. $width = $font->getTextWidth($text);
  436. $height = $font->getTextHeight($text);
  437. switch($this->hAlign) {
  438. case awLabel::RIGHT :
  439. $x -= ($width + $right);
  440. break;
  441. case awLabel::CENTER :
  442. $x -= ($width - $left + $right) / 2;
  443. break;
  444. case awLabel::LEFT :
  445. $x += $left;
  446. break;
  447. }
  448. switch($this->vAlign) {
  449. case awLabel::TOP :
  450. $y -= ($height + $bottom);
  451. break;
  452. case awLabel::MIDDLE :
  453. $y -= ($height - $top + $bottom) / 2;
  454. break;
  455. case awLabel::BOTTOM :
  456. $y += $top;
  457. break;
  458. }
  459. $drawer->string($text, $this->move->move($x, $y));
  460. }
  461. }
  462. /**
  463. * Draw the label
  464. *
  465. * @param awDrawer $drawer
  466. * @param awPoint $p Label center
  467. * @param int $key Text position in the array of texts (default to zero)
  468. */
  469. public function drawSpecial(awDrawer $drawer, awPoint $p, $key = 0, $theText) {
  470. $theTextAW = new awText($theText);
  471. if(($key % $this->interval) !== 0) {
  472. return;
  473. }
  474. // Hide all labels
  475. if($this->hide) {
  476. return;
  477. }
  478. // Key is hidden
  479. if(array_key_exists($key, $this->hideKey)) {
  480. return;
  481. }
  482. // Hide first label
  483. if($key === 0 and $this->hideFirst) {
  484. return;
  485. }
  486. // Hide last label
  487. if($key === count($this->texts) - 1 and $this->hideLast) {
  488. return;
  489. }
  490. $text = $theTextAW;
  491. if($text !== NULL) {
  492. // Value must be hidden
  493. if(in_array($text->getText(), $this->hideValue)) {
  494. return;
  495. }
  496. $x = $p->x;
  497. $y = $p->y;
  498. // Get padding
  499. list($left, $right, $top, $bottom) = $text->getPadding();
  500. $font = $text->getFont();
  501. $width = $font->getTextWidth($text);
  502. $height = $font->getTextHeight($text);
  503. switch($this->hAlign) {
  504. case awLabel::RIGHT :
  505. $x -= ($width + $right);
  506. break;
  507. case awLabel::CENTER :
  508. $x -= ($width - $left + $right) / 2;
  509. break;
  510. case awLabel::LEFT :
  511. $x += $left;
  512. break;
  513. }
  514. switch($this->vAlign) {
  515. case awLabel::TOP :
  516. $y -= ($height + $bottom);
  517. break;
  518. case awLabel::MIDDLE :
  519. $y -= ($height - $top + $bottom) / 2;
  520. break;
  521. case awLabel::BOTTOM :
  522. $y += $top;
  523. break;
  524. }
  525. $drawer->string($theTextAW, $this->move->move($x, $y));
  526. }
  527. }
  528. protected function getMax(awDrawer $drawer, $function) {
  529. $max = NULL;
  530. foreach($this->texts as $key => $text) {
  531. $text = $this->getText($key);
  532. $font = $text->getFont();
  533. if(is_null($max)) {
  534. $max = $font->{$function}($text);
  535. } else {
  536. $max = max($max, $font->{$function}($text));
  537. }
  538. }
  539. return $max;
  540. }
  541. }
  542. registerClass('Label');
  543. ?>