PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.0.3
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.0.3
5.13.0 5.12.1 5.12.0 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 2 years ago
Sparkline.php
202 lines
1 <?php
2
3 /**
4 * Matomo - free/libre analytics platform
5 *
6 * @link https://matomo.org
7 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8 *
9 */
10 namespace Piwik\Visualization;
11
12 use Piwik\Common;
13 use Piwik\Piwik;
14 use Piwik\View\ViewInterface;
15 /**
16 * Renders a sparkline image given a PHP data array.
17 * Using the Sparkline PHP Graphing Library sparkline.org
18 */
19 class Sparkline implements ViewInterface
20 {
21 const DEFAULT_WIDTH = 200;
22 const DEFAULT_HEIGHT = 50;
23 const MAX_WIDTH = 1000;
24 const MAX_HEIGHT = 1000;
25 /**
26 * Width of the sparkline
27 * @var int
28 */
29 protected $_width = self::DEFAULT_WIDTH;
30 /**
31 * Height of sparkline
32 * @var int
33 */
34 protected $_height = self::DEFAULT_HEIGHT;
35 private $serieses = [];
36 /**
37 * @var \Davaxi\Sparkline
38 */
39 private $sparkline;
40 /**
41 * Array with format: array( x, y, z, ... )
42 * @param array ...$data
43 */
44 public function setValues(...$data)
45 {
46 $this->serieses = $data;
47 }
48 public function addSeries(array $values)
49 {
50 $this->serieses[] = $values;
51 }
52 public function main()
53 {
54 try {
55 $sparkline = new \Davaxi\Sparkline();
56 } catch (\Exception $exception) {
57 // Ignore GD not installed exception
58 return;
59 }
60 $thousandSeparator = Piwik::translate('Intl_NumberSymbolGroup');
61 $decimalSeparator = Piwik::translate('Intl_NumberSymbolDecimal');
62 $sparkline->setData();
63 // remove default series
64 foreach ($this->serieses as $seriesIndex => $series) {
65 $values = [];
66 $hasFloat = false;
67 foreach ($series as $value) {
68 // replace localized decimal separator
69 $value = str_replace($thousandSeparator, '', $value);
70 $value = str_replace($decimalSeparator, '.', $value);
71 // sanitize value
72 $value = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_SCIENTIFIC);
73 if (empty($value) || !is_numeric($value)) {
74 $value = 0;
75 }
76 $values[] = $value;
77 if (is_float($value + 0)) {
78 // coerce to int/float type before checking
79 $hasFloat = true;
80 }
81 }
82 // the sparkline lib used converts everything to integers (see the FormatTrait.php file) which means float
83 // numbers that are close to 1.0 or 0.0 will get floored. this can happen in the average page generation time
84 // report, and cause some values which are, eg, around ~.9 to appear as 0 in the sparkline. to workaround this, we
85 // scale the values.
86 if ($hasFloat) {
87 $values = array_map(function ($x) {
88 return $x * 1000.0;
89 }, $values);
90 }
91 $sparkline->addSeries($values);
92 $this->setSparklineColors($sparkline, $seriesIndex);
93 }
94 $sparkline->setWidth($this->getWidth());
95 $sparkline->setHeight($this->getHeight());
96 $sparkline->setLineThickness(1);
97 $sparkline->setPadding('5');
98 $this->sparkline = $sparkline;
99 }
100 /**
101 * Returns the width of the sparkline
102 * @return int
103 */
104 public function getWidth()
105 {
106 return $this->_width;
107 }
108 /**
109 * Sets the width of the sparkline
110 * @param int $width
111 */
112 public function setWidth($width)
113 {
114 if (!is_numeric($width) || $width <= 0) {
115 return;
116 }
117 if ($width > self::MAX_WIDTH) {
118 $this->_width = self::MAX_WIDTH;
119 } else {
120 $this->_width = (int) $width;
121 }
122 }
123 /**
124 * Returns the height of the sparkline
125 * @return int
126 */
127 public function getHeight()
128 {
129 return $this->_height;
130 }
131 /**
132 * Sets the height of the sparkline
133 * @param int $height
134 */
135 public function setHeight($height)
136 {
137 if (!is_numeric($height) || $height <= 0) {
138 return;
139 }
140 if ($height > self::MAX_HEIGHT) {
141 $this->_height = self::MAX_HEIGHT;
142 } else {
143 $this->_height = (int) $height;
144 }
145 }
146 /**
147 * Sets the sparkline colors
148 *
149 * @param \Davaxi\Sparkline $sparkline
150 */
151 private function setSparklineColors($sparkline, $seriesIndex)
152 {
153 $colors = Common::getRequestVar('colors', false, 'json');
154 $defaultColors = array('backgroundColor' => '#ffffff', 'lineColor' => '#162C4A', 'minPointColor' => '#ff7f7f', 'maxPointColor' => '#75BF7C', 'lastPointColor' => '#55AAFF', 'fillColor' => '#ffffff');
155 if (empty($colors)) {
156 $colors = $defaultColors;
157 //set default color, if no color passed
158 } else {
159 $colors = array_merge($defaultColors, $colors);
160 //set default color key, if no key set.
161 }
162 if (strtolower($colors['backgroundColor']) !== '#ffffff') {
163 $sparkline->setBackgroundColorHex($colors['backgroundColor']);
164 } else {
165 $sparkline->deactivateBackgroundColor();
166 }
167 if (is_array($colors['lineColor'])) {
168 $sparkline->setLineColorHex($colors['lineColor'][$seriesIndex] ?? $defaultColors['lineColor'], $seriesIndex);
169 // set point colors to same as line colors so they can be better differentiated
170 $colors['minPointColor'] = $colors['maxPointColor'] = $colors['lastPointColor'] = $colors['lineColor'][$seriesIndex] ?? $defaultColors['lineColor'];
171 } else {
172 $sparkline->setLineColorHex($colors['lineColor']);
173 }
174 if (strtolower($colors['fillColor'] !== "#ffffff")) {
175 $sparkline->setFillColorHex($colors['fillColor']);
176 } else {
177 $sparkline->deactivateFillColor();
178 }
179 if (strtolower($colors['minPointColor'] !== "#ffffff")) {
180 $sparkline->addPoint("minimum", 5, $colors['minPointColor'], $seriesIndex);
181 }
182 if (strtolower($colors['maxPointColor'] !== "#ffffff")) {
183 $sparkline->addPoint("maximum", 5, $colors['maxPointColor'], $seriesIndex);
184 }
185 if (strtolower($colors['lastPointColor'] !== "#ffffff")) {
186 $sparkline->addPoint("last", 5, $colors['lastPointColor'], $seriesIndex);
187 }
188 }
189 public function render()
190 {
191 if (empty($this->sparkline->getSeriesCount())) {
192 // ensure to have at least one series & point in sparkline to avoid possible php notices/errors
193 // a sparkline will then be displayed with a zero line
194 $this->sparkline->addSeries([0]);
195 }
196 if ($this->sparkline instanceof \Davaxi\Sparkline) {
197 $this->sparkline->display();
198 $this->sparkline->destroy();
199 }
200 }
201 }
202