PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.7.5
GiveWP – Donation Plugin and Fundraising Platform v2.7.5
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / libraries / googlechartlib / GoogleChartData.php
give / includes / libraries / googlechartlib Last commit date
icons 8 years ago markers 8 years ago GoogleChart.php 8 years ago GoogleChartApi.php 8 years ago GoogleChartAxis.php 8 years ago GoogleChartData.php 8 years ago GoogleChartIcon.php 8 years ago GoogleChartMarker.php 8 years ago LICENSE 8 years ago
GoogleChartData.php
718 lines
1 <?php
2
3 /** @file
4 * This file is part of Google Chart PHP library.
5 *
6 * Copyright (c) 2010 Rémi Lanvin <remi@cloudconnected.fr>
7 *
8 * Licensed under the MIT license.
9 *
10 * For the full copyright and license information, please view the LICENSE file.
11 */
12
13 /**
14 * A data serie.
15 *
16 * This class implement every feature that is directly related to a data serie
17 * or its representation in the chart.
18 *
19 * Some method won't work for all charts, but won't produce an error.
20 */
21 class GoogleChartData
22 {
23 /**
24 * An array of the values of the data serie.
25 */
26 protected $values = null;
27 /**
28 * The name of the data serie to be displayed as legend.
29 */
30 protected $legend = null;
31 /**
32 * The label of the values of the data serie. Pie Chart only.
33 */
34 protected $labels = null;
35
36 /**
37 * Indicate if the color has been overridden.
38 * This variable is used to minimize the request. If no custom color has
39 * been providen, then the @c cho parameter is not triggered.
40 */
41 protected $chco = false;
42 /**
43 * Color of the data serie (string or array)
44 * Default color by Google Chart API is ffcc33
45 */
46 protected $color = 'ffcc33';
47
48 /**
49 * Indicate if @c chls parameter is needed
50 */
51 protected $chls = false;
52
53 /**
54 * Thickness of the line. Line Chart only. (@c chls)
55 */
56 protected $thickness = 2;
57
58 /**
59 * Length of the dash. Line Chart only. (@c chls)
60 */
61 protected $dash_length = null;
62
63 /**
64 * Length of the spaces between dashes. Line Chart only. (@c chls)
65 */
66 protected $space_length = null;
67
68 /**
69 * Line fill values (to fill area below a line). (@c chm)
70 */
71 protected $fill = null;
72
73 protected $fill_slices = array();
74
75 /**
76 * bool Whether to calculate scale automatically or not.
77 */
78 protected $autoscale = true;
79 /**
80 * array The scale, as specified by the user with setScale
81 */
82 protected $scale = null;
83
84 /**
85 * int Holds the index of the data serie in the chart. Null if not added.
86 */
87 protected $index = null;
88
89 /**
90 * Create a new data serie.
91 */
92 public function __construct($values)
93 {
94 if ( $values !== null && ! is_array($values) )
95 throw new InvalidArgumentException('Invalid values (must be an array or null)');
96
97 $this->values = $values;
98 }
99
100 /**
101 * Returns the values of this dataserie
102 * @return array (or null)
103 */
104 public function getValues()
105 {
106 return $this->values;
107 }
108
109 /**
110 * @since 0.5
111 */
112 public function hasValues()
113 {
114 return $this->values !== null && ! empty($this->values);
115 }
116
117 /**
118 * @since 0.5
119 */
120 public function computeChd($encoding = GoogleChart::TEXT, $scale = null)
121 {
122 // If scale is null, it means that there is not "global" scale for the chart
123 // Hence we need to determine the scale for this data only
124 if ( $scale === null ) {
125 $scale = $this->getScale();
126 }
127
128 switch ( $encoding ) {
129 case GoogleChart::TEXT :
130 return self::encodeText($this->values, $scale['min'], $scale['max']);
131 case GoogleChart::SIMPLE_ENCODING :
132 return self::encodeSimple($this->values, $scale['min'], $scale['max']);
133 case GoogleChart::EXTENDED_ENCODING :
134 return self::encodeExtended($this->values, $scale['min'], $scale['max']);
135 default:
136 throw new InvalidArgumentException('Invalid encoding format');
137 }
138 }
139
140
141 /**
142 * @name Pie Chart Labels @c chl
143 */
144 //@{
145 /**
146 * @since 0.5
147 */
148 public function setLabelsAuto()
149 {
150 return $this->setLabels(array_keys($this->values));
151 }
152
153 /**
154 * @since 0.5
155 */
156 public function setLabels($labels)
157 {
158 $n = sizeof($labels);
159 $v = sizeof($this->values);
160 if ( $n > $v ) {
161 throw new InvalidArgumentException('Invalid labels, to many labels');
162 }
163 elseif ( $n < $v ) {
164 $labels += array_fill(0, $v-$n, '');
165 }
166
167 $this->labels = $labels;
168 return $this;
169 }
170
171 /**
172 * Return labels set by setLabels()
173 * @return array();
174 */
175 public function getLabels()
176 {
177 return $this->labels;
178 }
179
180 /**
181 * Compute @c chl parameter.
182 *
183 * Only for Pie Chart.
184 *
185 * If the chart has no label, this function returns a string containing
186 * an empty label for each value (example "|" for 2 values, "||" for 3, etc.).
187 * This way, labels are always in sync with the values. The case happens
188 * with a concentric chart, if the inner chart (first data serie) doesn't
189 * have label, but the outer chart (second data serie) has.
190 *
191 * @internal
192 * @since 0.5
193 */
194 public function computeChl()
195 {
196 if ( ! $this->values )
197 return '';
198
199 if ( $this->labels === null ) {
200 return str_repeat('|',sizeof($this->values)-1);
201 }
202 return implode('|',$this->labels);
203 }
204 //@}
205
206 /**
207 * Set the index of the data serie in the chart.
208 *
209 * @internal
210 * @note Used by GoogleChart when calling GoogleChart::addData()
211 * @param $index (int)
212 * @return $this
213 */
214 public function setIndex($index)
215 {
216 if ( ! is_int($index) )
217 throw new InvalidArgumentException('Invalid index (must be an integer)');
218
219 $this->index = (int) $index;
220 return $this;
221 }
222
223 /**
224 * Return the index of the data serie in the chart (null if not in a chart).
225 *
226 * @return int or null
227 */
228 public function getIndex()
229 {
230 return $this->index;
231 }
232
233 /**
234 * Returns true if the data serie has an index, false otherwise.
235 *
236 * @return bool
237 */
238 public function hasIndex()
239 {
240 return $this->index !== null;
241 }
242
243 /**
244 * Enable/disabled autoscaling.
245 * @param $autoscale (bool)
246 * @return $this
247 */
248 public function setAutoscale($autoscale)
249 {
250 $this->autoscale = $autoscale;
251 return $this;
252 }
253
254 /**
255 * Set the scale of this data serie.
256 * When using this function, be sure your turned off global autoscaling.
257 * @see http://code.google.com/p/googlechartphplib/wiki/Autoscaling
258 * @param $min (int)
259 * @param $max (int)
260 */
261 public function setScale($min, $max)
262 {
263 $this->setAutoscale(false);
264 $this->scale = array(
265 'min' => $min,
266 'max' => $max
267 );
268 return $this;
269 }
270
271 /**
272 * @since 0.5
273 */
274 public function getScale()
275 {
276 if ( $this->autoscale == true ) {
277 if ( ! empty($this->values) ) {
278 $n = min($this->values);
279 if ( $n > 0 )
280 $n = 0;
281 return array('min' => $n, 'max' => max($this->values));
282 }
283 }
284
285 if ( $this->scale === null ) {
286 return array('min' => 0, 'max' => 100);
287 }
288
289 return $this->scale;
290 }
291
292 /**
293 * @since 0.5
294 */
295 public function computeChds()
296 {
297 $scale = $this->getScale();
298 return $scale['min'].','.$scale['max'];
299 }
300
301 /**
302 * @since 0.5
303 */
304 public function hasCustomScale()
305 {
306 return $this->scale !== null || $this->autoscale;
307 }
308
309 /**
310 * Chart Legend (chdl)
311 *
312 * @param $legend (string)
313 */
314 public function setLegend($legend)
315 {
316 $this->legend = $legend;
317 return $this;
318 }
319
320 /**
321 * Return the legend.
322 * @return string
323 */
324 public function getLegend()
325 {
326 return $this->legend;
327 }
328
329 /**
330 * Return true if a legend has been set
331 * @return bool
332 */
333 public function hasCustomLegend()
334 {
335 return $this->legend !== null;
336 }
337
338 /**
339 * @name Data Serie Color (@c chco).
340 */
341 //@{
342 /**
343 * Set the serie color.
344 * Color can be an array for bar charts and pie charts.
345 *
346 * @param $color (mixed) a RRGGBB string, or an array for Bar Chart and Pie Chart
347 * @see http://code.google.com/apis/chart/docs/chart_params.html#gcharts_series_color
348 */
349 public function setColor($color)
350 {
351 $this->chco = true;
352 $this->color = $color;
353 return $this;
354 }
355
356 /**
357 * Return the serie colors.
358 * @return color
359 */
360 public function getColor()
361 {
362 return $this->color;
363 }
364
365 /**
366 * Compute the @c cho parameter.
367 * @internal
368 * @return string
369 */
370 public function computeChco()
371 {
372 if ( is_array($this->color) )
373 return implode('|',$this->color);
374
375 return $this->color;
376 }
377
378 /**
379 * Return true if parameter @chco is needed
380 * @return true
381 */
382 public function hasChco()
383 {
384 return $this->chco;
385 }
386 //@}
387
388 /**
389 * @name Line fill (chm). Line and radar charts only.
390 */
391 //@{
392 /**
393 * Line fill
394 *
395 * @param $color (string) RRGGBB color. Supports transparency if you uses
396 * RRGGBBAA format.
397 *
398 * @param $end_line (int) On a multi-line chart, if you want to fill only
399 * between two lines, you can specify the index of the line at which to stop
400 * the filling.
401 *
402 * @see http://code.google.com/apis/chart/docs/chart_params.html#gcharts_line_fills
403 */
404 public function setFill($color, $end_line = null)
405 {
406 $this->fill = array(
407 'color' => $color,
408 'end_line' => $end_line
409 );
410 }
411
412 /**
413 * @since 0.5
414 */
415 public function addFillSlice($color, $start = null, $stop = null)
416 {
417 if ( $start !== null && ! is_numeric($start) ) {
418 throw new InvalidArgumentException('Invalid start index (must be NULL or numeric)');
419 }
420 if ( $stop !== null && ! is_numeric($stop) ) {
421 throw new InvalidArgumentException('Invalid stop index (must be NULL or numeric)');
422 }
423
424 $this->fill_slices[] = array(
425 'color' => $color,
426 'start' => $start === null ? null : intval($start),
427 'stop' => $stop === null ? null : intval($stop)
428 );
429 }
430
431 /**
432 * @todo Move to compute*
433 */
434 public function computeChm($index)
435 {
436 if ( $this->fill === null && ! isset($this->fill_slices[0]) )
437 return null;
438
439 $fill = array();
440
441 if ( $this->fill !== null ) {
442 $fill[] = sprintf(
443 '%s,%s,%d,%d,0',
444 $this->fill['end_line'] === null ? 'B' : 'b',
445 $this->fill['color'],
446 $index,
447 $this->fill['end_line']
448 );
449 }
450
451 if ( isset($this->fill_slices[0]) ) {
452 foreach ( $this->fill_slices as $f ) {
453 $fill[] = sprintf(
454 'B,%s,%d,%s:%s,0',
455 $f['color'],
456 $index,
457 $f['start'],
458 $f['stop']
459 );
460 }
461 }
462 return implode('|',$fill);
463 }
464 //@}
465
466
467 /**
468 * @name Line styles (chls).
469 */
470 // @{
471
472 /**
473 * Set the thickness of the line (Line Chart only).
474 *
475 * @see http://code.google.com/apis/chart/docs/chart_params.html#gcharts_line_styles
476 * @since 0.5
477 */
478 public function setThickness($thickness)
479 {
480 $this->chls = true;
481
482 $this->thickness = $thickness;
483 return $this;
484 }
485
486 /**
487 * @since 0.5
488 */
489 public function getThickness()
490 {
491 return $this->thickness;
492 }
493
494 /**
495 * @since 0.5
496 */
497 public function setDash($dash_length, $space_length = null)
498 {
499 $this->chls = true;
500
501 $this->dash_length = $dash_length;
502 $this->space_length = $space_length;
503 return $this;
504 }
505
506 /**
507 * @internal
508 * @since 0.5
509 */
510 public function computeChls()
511 {
512 $str = $this->thickness;
513 if ( $this->dash_length !== null ) {
514 $str .= ','.$this->dash_length;
515 if ( $this->space_length !== null ) {
516 $str .= ','.$this->space_length;
517 }
518 }
519 return $str;
520 }
521
522 /**
523 * @internal
524 * @since 0.5
525 */
526 public function hasChls()
527 {
528 return $this->chls;
529 }
530 //@}
531
532 /**
533 * @internal
534 * @since 0.5
535 */
536 static public function encodeText(array $values)
537 {
538 foreach ( $values as & $v ) {
539 if ( $v === null ) {
540 $v = '_';
541 }
542 else {
543 // We can't rely on PHP's default display for float values, as
544 // Float are actually displayed differently depending on the
545 // Current locale.
546 $v = number_format($v, 2, '.', '');
547 }
548 }
549 return implode(',',$values);
550 }
551
552 /**
553 * @internal
554 * @since 0.5
555 */
556 static public function encodeSimple(array $values, $min = null, $max = null)
557 {
558 if ( $min === null ) {
559 $min = min($values);
560 // By default, we only want a min if there is negative values
561 if ( $min > 0 ) {
562 $min = 0;
563 }
564 }
565 if ( $max === null ) {
566 $max = max($values);
567 }
568 $max = $max + abs($min);
569
570 $map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
571 $str = '';
572
573 foreach ( $values as $v ) {
574 if ( $v === null ) {
575 $str .= '_';
576 continue;
577 }
578
579 $n = round(61 * (($v - $min) / $max));
580 if ( $n > 61 ) {
581 $str .= '9';
582 }
583 elseif ( $n < 0 ) {
584 $str .= '_';
585 }
586 else {
587 $str .= $map[$n];
588 }
589 }
590 return $str;
591 }
592
593 /**
594 * @internal
595 * @since 0.5
596 */
597 static public function encodeExtended(array $values, $min = null, $max = null)
598 {
599 if ( $min === null ) {
600 $min = min($values);
601 // By default, we only want a min if there is negative values
602 if ( $min > 0 ) {
603 $min = 0;
604 }
605 }
606 if ( $max === null ) {
607 $max = max($values);
608 }
609 $max = $max + abs($min);
610 if ( $max == 0 )
611 return '';
612
613 $map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.';
614 $str = '';
615
616 foreach ( $values as $v ) {
617 if ( $v === null ) {
618 $str .= '__';
619 continue;
620 }
621
622 $n = floor(64 * 64 * (($v - $min) / $max));
623 if ( $n > (64*64 - 1) ) {
624 $str .= '..';
625 }
626 elseif ( $n < 0 ) {
627 $str .= '__';
628 }
629 else {
630 $q = floor($n / 64);
631 $r = $n - 64 * $q;
632 $str .= $map[$q].$map[$r];
633 }
634 }
635 return $str;
636 }
637
638 /**
639 * linear regression function
640 *
641 * @param $data array Points to calculate
642 * @returns array() m=>slope, b=>intercept
643 */
644 static public function calculateLinearRegression($data)
645 {
646 // Calculate number points
647 $n = count($data);
648
649 $x = array_keys($data);
650 $y = array_values($data);
651
652 // Calculate sums
653 $x_sum = array_sum($x);
654 $y_sum = array_sum($y);
655
656 $xx_sum = 0;
657 $xy_sum = 0;
658
659 for($i = 0; $i < $n; $i++) {
660
661 $xy_sum+=($x[$i]*$y[$i]);
662 $xx_sum+=($x[$i]*$x[$i]);
663
664 }
665
666 // Calculate slope
667 $m = (($n * $xy_sum) - ($x_sum * $y_sum)) / (($n * $xx_sum) - ($x_sum * $x_sum));
668
669 // Calculate intercept
670 $b = ($y_sum - ($m * $x_sum)) / $n;
671
672 // Return result
673 return array($m, $b);
674 }
675
676 /**
677 * Function that creates a new GoogleChartData element with trend points based
678 * on the current values.
679 *
680 * @return GoogleChartData Trend data
681 */
682 public function createTrendData()
683 {
684 if(!$this->hasValues())
685 return null;
686
687 list($slope, $intercept) = self::calculateLinearRegression(array_values($this->values));
688
689 $n = sizeof($this->values);
690 $array = array();
691 $v = $intercept;
692
693 for ( $i = 1; $i <= $n; $i++ ) {
694 $v += $slope;
695 $array[] = round($v,2);
696 }
697
698 return new self($array);
699 }
700
701 /**
702 * Function that returns a LineMarker that indicates the trend of the contained
703 * data.
704 *
705 * @return GoogleChartLineMarker Trend line
706 */
707 public function createTrendMarker()
708 {
709 if(!$this->hasValues())
710 return null;
711
712 $marker = new GoogleChartLineMarker();
713 $marker->setData($this->createTrendData());
714
715 return $marker;
716 }
717 }
718