PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 4.0.2
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v4.0.2
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Visualization / Sparkline.php
matomo / app / core / Visualization Last commit date
Sparkline.php 5 years ago
Sparkline.php
220 lines
1 <?php
2 /**
3 * Matomo - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 *
8 */
9
10 namespace Piwik\Visualization;
11
12 use Piwik\Common;
13 use Piwik\Piwik;
14 use Piwik\View\ViewInterface;
15
16 /**
17 * Renders a sparkline image given a PHP data array.
18 * Using the Sparkline PHP Graphing Library sparkline.org
19 */
20 class Sparkline implements ViewInterface
21 {
22 const DEFAULT_WIDTH = 200;
23 const DEFAULT_HEIGHT = 50;
24 const MAX_WIDTH = 1000;
25 const MAX_HEIGHT = 1000;
26
27
28 /**
29 * Width of the sparkline
30 * @var int
31 */
32 protected $_width = self::DEFAULT_WIDTH;
33 /**
34 * Height of sparkline
35 * @var int
36 */
37 protected $_height = self::DEFAULT_HEIGHT;
38 private $serieses = array();
39 /**
40 * @var \Davaxi\Sparkline
41 */
42 private $sparkline;
43
44 /**
45 * Array with format: array( x, y, z, ... )
46 * @param array $data,...
47 */
48 public function setValues()
49 {
50 $this->serieses = func_get_args();
51 }
52
53 public function addSeries(array $values)
54 {
55 $this->serieses[] = $values;
56 }
57
58 public function main()
59 {
60 try {
61 $sparkline = new \Davaxi\Sparkline();
62 } catch (\Exception $exception) {
63 // Ignore GD not installed exception
64 return;
65 }
66
67
68 $thousandSeparator = Piwik::translate('Intl_NumberSymbolGroup');
69 $decimalSeparator = Piwik::translate('Intl_NumberSymbolDecimal');
70
71 $sparkline->setData(); // remove default series
72 foreach ($this->serieses as $seriesIndex => $series) {
73 $values = [];
74 $hasFloat = false;
75
76 foreach ($series as $value) {
77 // replace localized decimal separator
78 $value = str_replace($thousandSeparator, '', $value);
79 $value = str_replace($decimalSeparator, '.', $value);
80
81 // sanitize value
82 $value = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_SCIENTIFIC);
83
84 if (empty($value) || !is_numeric($value)) {
85 $value = 0;
86 }
87
88 $values[] = $value;
89
90 if (is_float($value + 0)) { // coerce to int/float type before checking
91 $hasFloat = true;
92 }
93 }
94
95 // the sparkline lib used converts everything to integers (see the FormatTrait.php file) which means float
96 // numbers that are close to 1.0 or 0.0 will get floored. this can happen in the average page generation time
97 // report, and cause some values which are, eg, around ~.9 to appear as 0 in the sparkline. to workaround this, we
98 // scale the values.
99 if ($hasFloat) {
100 $values = array_map(function ($x) {
101 return $x * 1000.0;
102 }, $values);
103 }
104
105 $sparkline->addSeries($values);
106 $this->setSparklineColors($sparkline, $seriesIndex);
107 }
108
109 $sparkline->setWidth($this->getWidth());
110 $sparkline->setHeight($this->getHeight());
111 $sparkline->setLineThickness(1);
112 $sparkline->setPadding('5');
113
114 $this->sparkline = $sparkline;
115 }
116
117 /**
118 * Returns the width of the sparkline
119 * @return int
120 */
121 public function getWidth() {
122 return $this->_width;
123 }
124
125 /**
126 * Sets the width of the sparkline
127 * @param int $width
128 */
129 public function setWidth($width) {
130 if (!is_numeric($width) || $width <= 0) {
131 return;
132 }
133 if ($width > self::MAX_WIDTH) {
134 $this->_width = self::MAX_WIDTH;
135 } else {
136 $this->_width = (int)$width;
137 }
138 }
139
140 /**
141 * Returns the height of the sparkline
142 * @return int
143 */
144 public function getHeight() {
145 return $this->_height;
146 }
147
148 /**
149 * Sets the height of the sparkline
150 * @param int $height
151 */
152 public function setHeight($height) {
153 if (!is_numeric($height) || $height <= 0) {
154 return;
155 }
156 if ($height > self::MAX_HEIGHT) {
157 $this->_height = self::MAX_HEIGHT;
158 } else {
159 $this->_height = (int)$height;
160 }
161 }
162
163 /**
164 * Sets the sparkline colors
165 *
166 * @param \Davaxi\Sparkline $sparkline
167 */
168 private function setSparklineColors($sparkline, $seriesIndex) {
169 $colors = Common::getRequestVar('colors', false, 'json');
170
171 if (empty($colors)) { // quick fix so row evolution sparklines will have color in widgetize's iframes
172 $colors = array(
173 'backgroundColor' => '#ffffff',
174 'lineColor' => '#162C4A',
175 'minPointColor' => '#ff7f7f',
176 'maxPointColor' => '#75BF7C',
177 'lastPointColor' => '#55AAFF',
178 'fillColor' => '#ffffff'
179 );
180 }
181
182 if (strtolower($colors['backgroundColor']) !== '#ffffff') {
183 $sparkline->setBackgroundColorHex($colors['backgroundColor']);
184 } else {
185 $sparkline->deactivateBackgroundColor();
186 }
187
188 if (is_array($colors['lineColor'])) {
189 $sparkline->setLineColorHex($colors['lineColor'][$seriesIndex], $seriesIndex);
190
191 // set point colors to same as line colors so they can be better differentiated
192 $colors['minPointColor'] = $colors['maxPointColor'] = $colors['lastPointColor'] = $colors['lineColor'][$seriesIndex];
193 } else {
194 $sparkline->setLineColorHex($colors['lineColor']);
195 }
196
197 if (strtolower($colors['fillColor'] !== "#ffffff")) {
198 $sparkline->setFillColorHex($colors['fillColor']);
199 } else {
200 $sparkline->deactivateFillColor();
201 }
202 if (strtolower($colors['minPointColor'] !== "#ffffff")) {
203 $sparkline->addPoint("minimum", 5, $colors['minPointColor'], $seriesIndex);
204 }
205 if (strtolower($colors['maxPointColor'] !== "#ffffff")) {
206 $sparkline->addPoint("maximum", 5, $colors['maxPointColor'], $seriesIndex);
207 }
208 if (strtolower($colors['lastPointColor'] !== "#ffffff")) {
209 $sparkline->addPoint("last", 5, $colors['lastPointColor'], $seriesIndex);
210 }
211 }
212
213 public function render() {
214 if ($this->sparkline instanceof \Davaxi\Sparkline) {
215 $this->sparkline->display();
216 $this->sparkline->destroy();
217 }
218 }
219 }
220