PluginProbe
wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin / 6.5.1.7
wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin v6.5.1.7
6.5.1.7 6.5.1.6 6.5.1.5 6.5.1.4 6.5.1.3 6.5.1.2 6.5.1.1 6.5.0.9 6.5.0.8 6.5.0.7 6.5.0.6 trunk 3.4.2.40 3.4.2.41 3.4.2.42 3.4.2.43 3.4.2.44 3.4.2.45 3.4.2.46 3.4.2.47 3.4.2.48 3.4.2.49 3.4.2.50 6.3.2 6.3.3.1 All 47 releases
wpdatatables / lib / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Chart / DataSeriesValues.php

DataSeriesValues.php in wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin 6.5.1.7, at lib/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeriesValues.php

596 lines 13.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace PhpOffice\PhpSpreadsheet\Chart;
4
5 use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6 use PhpOffice\PhpSpreadsheet\Calculation\Functions;
7 use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
8 use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
9
10 class DataSeriesValues extends Properties
11 {
12 const DATASERIES_TYPE_STRING = 'String';
13 const DATASERIES_TYPE_NUMBER = 'Number';
14
15 private const DATA_TYPE_VALUES = [
16 self::DATASERIES_TYPE_STRING,
17 self::DATASERIES_TYPE_NUMBER,
18 ];
19
20 /**
21 * Series Data Type.
22 *
23 * @var string
24 */
25 private $dataType;
26
27 /**
28 * Series Data Source.
29 *
30 * @var ?string
31 */
32 private $dataSource;
33
34 /**
35 * Format Code.
36 *
37 * @var string
38 */
39 private $formatCode;
40
41 /**
42 * Series Point Marker.
43 *
44 * @var string
45 */
46 private $pointMarker;
47
48 /** @var ChartColor */
49 private $markerFillColor;
50
51 /** @var ChartColor */
52 private $markerBorderColor;
53
54 /**
55 * Series Point Size.
56 *
57 * @var int
58 */
59 private $pointSize = 3;
60
61 /**
62 * Point Count (The number of datapoints in the dataseries).
63 *
64 * @var int
65 */
66 private $pointCount = 0;
67
68 /**
69 * Data Values.
70 *
71 * @var mixed[]
72 */
73 private $dataValues = [];
74
75 /**
76 * Fill color (can be array with colors if dataseries have custom colors).
77 *
78 * @var null|ChartColor|ChartColor[]
79 */
80 private $fillColor;
81
82 /** @var bool */
83 private $scatterLines = true;
84
85 /** @var bool */
86 private $bubble3D = false;
87
88 /** @var ?Layout */
89 private $labelLayout;
90
91 /** @var TrendLine[] */
92 private $trendLines = [];
93
94 /**
95 * Create a new DataSeriesValues object.
96 *
97 * @param string $dataType
98 * @param string $dataSource
99 * @param null|mixed $formatCode
100 * @param int $pointCount
101 * @param mixed $dataValues
102 * @param null|mixed $marker
103 * @param null|ChartColor|ChartColor[]|string|string[] $fillColor
104 * @param string $pointSize
105 */
106 public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSource = null, $formatCode = null, $pointCount = 0, $dataValues = [], $marker = null, $fillColor = null, $pointSize = '3')
107 {
108 parent::__construct();
109 $this->markerFillColor = new ChartColor();
110 $this->markerBorderColor = new ChartColor();
111 $this->setDataType($dataType);
112 $this->dataSource = $dataSource;
113 $this->formatCode = $formatCode;
114 $this->pointCount = $pointCount;
115 $this->dataValues = $dataValues;
116 $this->pointMarker = $marker;
117 if ($fillColor !== null) {
118 $this->setFillColor($fillColor);
119 }
120 if (is_numeric($pointSize)) {
121 $this->pointSize = (int) $pointSize;
122 }
123 }
124
125 /**
126 * Get Series Data Type.
127 *
128 * @return string
129 */
130 public function getDataType()
131 {
132 return $this->dataType;
133 }
134
135 /**
136 * Set Series Data Type.
137 *
138 * @param string $dataType Datatype of this data series
139 * Typical values are:
140 * DataSeriesValues::DATASERIES_TYPE_STRING
141 * Normally used for axis point values
142 * DataSeriesValues::DATASERIES_TYPE_NUMBER
143 * Normally used for chart data values
144 *
145 * @return $this
146 */
147 public function setDataType($dataType)
148 {
149 if (!in_array($dataType, self::DATA_TYPE_VALUES)) {
150 throw new Exception('Invalid datatype for chart data series values');
151 }
152 $this->dataType = $dataType;
153
154 return $this;
155 }
156
157 /**
158 * Get Series Data Source (formula).
159 *
160 * @return ?string
161 */
162 public function getDataSource()
163 {
164 return $this->dataSource;
165 }
166
167 /**
168 * Set Series Data Source (formula).
169 *
170 * @param ?string $dataSource
171 *
172 * @return $this
173 */
174 public function setDataSource($dataSource)
175 {
176 $this->dataSource = $dataSource;
177
178 return $this;
179 }
180
181 /**
182 * Get Point Marker.
183 *
184 * @return string
185 */
186 public function getPointMarker()
187 {
188 return $this->pointMarker;
189 }
190
191 /**
192 * Set Point Marker.
193 *
194 * @param string $marker
195 *
196 * @return $this
197 */
198 public function setPointMarker($marker)
199 {
200 $this->pointMarker = $marker;
201
202 return $this;
203 }
204
205 public function getMarkerFillColor(): ChartColor
206 {
207 return $this->markerFillColor;
208 }
209
210 public function getMarkerBorderColor(): ChartColor
211 {
212 return $this->markerBorderColor;
213 }
214
215 /**
216 * Get Point Size.
217 */
218 public function getPointSize(): int
219 {
220 return $this->pointSize;
221 }
222
223 /**
224 * Set Point Size.
225 *
226 * @return $this
227 */
228 public function setPointSize(int $size = 3)
229 {
230 $this->pointSize = $size;
231
232 return $this;
233 }
234
235 /**
236 * Get Series Format Code.
237 *
238 * @return string
239 */
240 public function getFormatCode()
241 {
242 return $this->formatCode;
243 }
244
245 /**
246 * Set Series Format Code.
247 *
248 * @param string $formatCode
249 *
250 * @return $this
251 */
252 public function setFormatCode($formatCode)
253 {
254 $this->formatCode = $formatCode;
255
256 return $this;
257 }
258
259 /**
260 * Get Series Point Count.
261 *
262 * @return int
263 */
264 public function getPointCount()
265 {
266 return $this->pointCount;
267 }
268
269 /**
270 * Get fill color object.
271 *
272 * @return null|ChartColor|ChartColor[]
273 */
274 public function getFillColorObject()
275 {
276 return $this->fillColor;
277 }
278
279 private function stringToChartColor(string $fillString): ChartColor
280 {
281 $value = $type = '';
282 if (substr($fillString, 0, 1) === '*') {
283 $type = 'schemeClr';
284 $value = substr($fillString, 1);
285 } elseif (substr($fillString, 0, 1) === '/') {
286 $type = 'prstClr';
287 $value = substr($fillString, 1);
288 } elseif ($fillString !== '') {
289 $type = 'srgbClr';
290 $value = $fillString;
291 $this->validateColor($value);
292 }
293
294 return new ChartColor($value, null, $type);
295 }
296
297 private function chartColorToString(ChartColor $chartColor): string
298 {
299 $type = (string) $chartColor->getColorProperty('type');
300 $value = (string) $chartColor->getColorProperty('value');
301 if ($type === '' || $value === '') {
302 return '';
303 }
304 if ($type === 'schemeClr') {
305 return "*$value";
306 }
307 if ($type === 'prstClr') {
308 return "/$value";
309 }
310
311 return $value;
312 }
313
314 /**
315 * Get fill color.
316 *
317 * @return string|string[] HEX color or array with HEX colors
318 */
319 public function getFillColor()
320 {
321 if ($this->fillColor === null) {
322 return '';
323 }
324 if (is_array($this->fillColor)) {
325 $array = [];
326 foreach ($this->fillColor as $chartColor) {
327 $array[] = $this->chartColorToString($chartColor);
328 }
329
330 return $array;
331 }
332
333 return $this->chartColorToString($this->fillColor);
334 }
335
336 /**
337 * Set fill color for series.
338 *
339 * @param ChartColor|ChartColor[]|string|string[] $color HEX color or array with HEX colors
340 *
341 * @return DataSeriesValues
342 */
343 public function setFillColor($color)
344 {
345 if (is_array($color)) {
346 $this->fillColor = [];
347 foreach ($color as $fillString) {
348 if ($fillString instanceof ChartColor) {
349 $this->fillColor[] = $fillString;
350 } else {
351 $this->fillColor[] = $this->stringToChartColor($fillString);
352 }
353 }
354 } elseif ($color instanceof ChartColor) {
355 $this->fillColor = $color;
356 } else {
357 $this->fillColor = $this->stringToChartColor($color);
358 }
359
360 return $this;
361 }
362
363 /**
364 * Method for validating hex color.
365 *
366 * @param string $color value for color
367 *
368 * @return bool true if validation was successful
369 */
370 private function validateColor($color)
371 {
372 if (!preg_match('/^[a-f0-9]{6}$/i', $color)) {
373 throw new Exception(sprintf('Invalid hex color for chart series (color: "%s")', $color));
374 }
375
376 return true;
377 }
378
379 /**
380 * Get line width for series.
381 *
382 * @return null|float|int
383 */
384 public function getLineWidth()
385 {
386 return $this->lineStyleProperties['width'];
387 }
388
389 /**
390 * Set line width for the series.
391 *
392 * @param null|float|int $width
393 *
394 * @return $this
395 */
396 public function setLineWidth($width)
397 {
398 $this->lineStyleProperties['width'] = $width;
399
400 return $this;
401 }
402
403 /**
404 * Identify if the Data Series is a multi-level or a simple series.
405 *
406 * @return null|bool
407 */
408 public function isMultiLevelSeries()
409 {
410 if (!empty($this->dataValues)) {
411 return is_array(array_values($this->dataValues)[0]);
412 }
413
414 return null;
415 }
416
417 /**
418 * Return the level count of a multi-level Data Series.
419 *
420 * @return int
421 */
422 public function multiLevelCount()
423 {
424 $levelCount = 0;
425 foreach ($this->dataValues as $dataValueSet) {
426 $levelCount = max($levelCount, count($dataValueSet));
427 }
428
429 return $levelCount;
430 }
431
432 /**
433 * Get Series Data Values.
434 *
435 * @return mixed[]
436 */
437 public function getDataValues()
438 {
439 return $this->dataValues;
440 }
441
442 /**
443 * Get the first Series Data value.
444 *
445 * @return mixed
446 */
447 public function getDataValue()
448 {
449 $count = count($this->dataValues);
450 if ($count == 0) {
451 return null;
452 } elseif ($count == 1) {
453 return $this->dataValues[0];
454 }
455
456 return $this->dataValues;
457 }
458
459 /**
460 * Set Series Data Values.
461 *
462 * @param array $dataValues
463 *
464 * @return $this
465 */
466 public function setDataValues($dataValues)
467 {
468 $this->dataValues = Functions::flattenArray($dataValues);
469 $this->pointCount = count($dataValues);
470
471 return $this;
472 }
473
474 public function refresh(Worksheet $worksheet, bool $flatten = true): void
475 {
476 if ($this->dataSource !== null) {
477 $calcEngine = Calculation::getInstance($worksheet->getParent());
478 $newDataValues = Calculation::unwrapResult(
479 $calcEngine->_calculateFormulaValue(
480 '=' . $this->dataSource,
481 null,
482 $worksheet->getCell('A1')
483 )
484 );
485 if ($flatten) {
486 $this->dataValues = Functions::flattenArray($newDataValues);
487 foreach ($this->dataValues as &$dataValue) {
488 if (is_string($dataValue) && !empty($dataValue) && $dataValue[0] == '#') {
489 $dataValue = 0.0;
490 }
491 }
492 unset($dataValue);
493 } else {
494 [$worksheet, $cellRange] = Worksheet::extractSheetTitle($this->dataSource, true);
495 $dimensions = Coordinate::rangeDimension(str_replace('$', '', $cellRange));
496 if (($dimensions[0] == 1) || ($dimensions[1] == 1)) {
497 $this->dataValues = Functions::flattenArray($newDataValues);
498 } else {
499 $newArray = array_values(array_shift(/** @scrutinizer ignore-type */ $newDataValues));
500 foreach ($newArray as $i => $newDataSet) {
501 $newArray[$i] = [$newDataSet];
502 }
503
504 foreach ($newDataValues as $newDataSet) {
505 $i = 0;
506 foreach ($newDataSet as $newDataVal) {
507 array_unshift($newArray[$i++], $newDataVal);
508 }
509 }
510 $this->dataValues = $newArray;
511 }
512 }
513 $this->pointCount = count($this->dataValues);
514 }
515 }
516
517 public function getScatterLines(): bool
518 {
519 return $this->scatterLines;
520 }
521
522 public function setScatterLines(bool $scatterLines): self
523 {
524 $this->scatterLines = $scatterLines;
525
526 return $this;
527 }
528
529 public function getBubble3D(): bool
530 {
531 return $this->bubble3D;
532 }
533
534 public function setBubble3D(bool $bubble3D): self
535 {
536 $this->bubble3D = $bubble3D;
537
538 return $this;
539 }
540
541 /**
542 * Smooth Line. Must be specified for both DataSeries and DataSeriesValues.
543 *
544 * @var bool
545 */
546 private $smoothLine;
547
548 /**
549 * Get Smooth Line.
550 *
551 * @return bool
552 */
553 public function getSmoothLine()
554 {
555 return $this->smoothLine;
556 }
557
558 /**
559 * Set Smooth Line.
560 *
561 * @param bool $smoothLine
562 *
563 * @return $this
564 */
565 public function setSmoothLine($smoothLine)
566 {
567 $this->smoothLine = $smoothLine;
568
569 return $this;
570 }
571
572 public function getLabelLayout(): ?Layout
573 {
574 return $this->labelLayout;
575 }
576
577 public function setLabelLayout(?Layout $labelLayout): self
578 {
579 $this->labelLayout = $labelLayout;
580
581 return $this;
582 }
583
584 public function setTrendLines(array $trendLines): self
585 {
586 $this->trendLines = $trendLines;
587
588 return $this;
589 }
590
591 public function getTrendLines(): array
592 {
593 return $this->trendLines;
594 }
595 }
596