Chart::readChart()   F
last analyzed

Complexity

Conditions 101
Paths 3072

Size

Total Lines 414
Code Lines 313

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 308
CRAP Score 101.0003

Importance

Changes 0
Metric Value
eloc 313
dl 0
loc 414
ccs 308
cts 309
cp 0.9968
rs 0
c 0
b 0
f 0
cc 101
nc 3072
nop 2
crap 101.0003

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
6
use PhpOffice\PhpSpreadsheet\Chart\Axis;
7
use PhpOffice\PhpSpreadsheet\Chart\AxisText;
8
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
9
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
10
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
11
use PhpOffice\PhpSpreadsheet\Chart\GridLines;
12
use PhpOffice\PhpSpreadsheet\Chart\Layout;
13
use PhpOffice\PhpSpreadsheet\Chart\Legend;
14
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
15
use PhpOffice\PhpSpreadsheet\Chart\Properties as ChartProperties;
16
use PhpOffice\PhpSpreadsheet\Chart\Title;
17
use PhpOffice\PhpSpreadsheet\Chart\TrendLine;
18
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
19
use PhpOffice\PhpSpreadsheet\RichText\RichText;
20
use PhpOffice\PhpSpreadsheet\Style\Font;
21
use SimpleXMLElement;
22
23
class Chart
24
{
25
    private string $cNamespace;
26
27
    private string $aNamespace;
28
29 65
    public function __construct(string $cNamespace = Namespaces::CHART, string $aNamespace = Namespaces::DRAWINGML)
30
    {
31 65
        $this->cNamespace = $cNamespace;
32 65
        $this->aNamespace = $aNamespace;
33
    }
34
35 65
    private static function getAttributeString(SimpleXMLElement $component, string $name): string|null
36
    {
37 65
        $attributes = $component->attributes();
38 65
        if (@isset($attributes[$name])) {
39 65
            return (string) $attributes[$name];
40
        }
41
42 65
        return null;
43
    }
44
45 65
    private static function getAttributeInteger(SimpleXMLElement $component, string $name): int|null
46
    {
47 65
        $attributes = $component->attributes();
48 65
        if (@isset($attributes[$name])) {
49 65
            return (int) $attributes[$name];
50
        }
51
52 61
        return null;
53
    }
54
55 63
    private static function getAttributeBoolean(SimpleXMLElement $component, string $name): bool|null
56
    {
57 63
        $attributes = $component->attributes();
58 63
        if (@isset($attributes[$name])) {
59 62
            $value = (string) $attributes[$name];
60
61 62
            return $value === 'true' || $value === '1';
62
        }
63
64 60
        return null;
65
    }
66
67 7
    private static function getAttributeFloat(SimpleXMLElement $component, string $name): float|null
68
    {
69 7
        $attributes = $component->attributes();
70 7
        if (@isset($attributes[$name])) {
71 5
            return (float) $attributes[$name];
72
        }
73
74 6
        return null;
75
    }
76
77 65
    public function readChart(SimpleXMLElement $chartElements, string $chartName): \PhpOffice\PhpSpreadsheet\Chart\Chart
78
    {
79 65
        $chartElementsC = $chartElements->children($this->cNamespace);
80
81 65
        $XaxisLabel = $YaxisLabel = $legend = $title = null;
82 65
        $dispBlanksAs = null;
83 65
        $plotVisOnly = false;
84 65
        $plotArea = null;
85 65
        $rotX = $rotY = $rAngAx = $perspective = null;
86 65
        $xAxis = new Axis();
87 65
        $yAxis = new Axis();
88 65
        $autoTitleDeleted = null;
89 65
        $chartNoFill = false;
90 65
        $chartBorderLines = null;
91 65
        $chartFillColor = null;
92 65
        $gradientArray = [];
93 65
        $gradientLin = null;
94 65
        $roundedCorners = false;
95 65
        $gapWidth = null;
96 65
        $useUpBars = null;
97 65
        $useDownBars = null;
98 65
        foreach ($chartElementsC as $chartElementKey => $chartElement) {
99
            switch ($chartElementKey) {
100 65
                case 'spPr':
101 47
                    $children = $chartElementsC->spPr->children($this->aNamespace);
102 47
                    if (isset($children->noFill)) {
103 3
                        $chartNoFill = true;
104
                    }
105 47
                    if (isset($children->solidFill)) {
106 11
                        $chartFillColor = $this->readColor($children->solidFill);
107
                    }
108 47
                    if (isset($children->ln)) {
109 47
                        $chartBorderLines = new GridLines();
110 47
                        $this->readLineStyle($chartElementsC, $chartBorderLines);
111
                    }
112
113 47
                    break;
114 65
                case 'roundedCorners':
115
                    /** @var bool $roundedCorners */
116 61
                    $roundedCorners = self::getAttributeBoolean($chartElementsC->roundedCorners, 'val');
117
118 61
                    break;
119 65
                case 'chart':
120 65
                    foreach ($chartElement as $chartDetailsKey => $chartDetails) {
121 65
                        $chartDetails = Xlsx::testSimpleXml($chartDetails);
122
                        switch ($chartDetailsKey) {
123 65
                            case 'autoTitleDeleted':
124
                                /** @var bool $autoTitleDeleted */
125 61
                                $autoTitleDeleted = self::getAttributeBoolean($chartElementsC->chart->autoTitleDeleted, 'val');
126
127 61
                                break;
128 65
                            case 'view3D':
129 45
                                $rotX = self::getAttributeInteger($chartDetails->rotX, 'val');
130 45
                                $rotY = self::getAttributeInteger($chartDetails->rotY, 'val');
131 45
                                $rAngAx = self::getAttributeInteger($chartDetails->rAngAx, 'val');
132 45
                                $perspective = self::getAttributeInteger($chartDetails->perspective, 'val');
133
134 45
                                break;
135 65
                            case 'plotArea':
136 65
                                $plotAreaLayout = $XaxisLabel = $YaxisLabel = null;
137 65
                                $plotSeries = $plotAttributes = [];
138 65
                                $catAxRead = false;
139 65
                                $plotNoFill = false;
140 65
                                foreach ($chartDetails as $chartDetailKey => $chartDetail) {
141 65
                                    $chartDetail = Xlsx::testSimpleXml($chartDetail);
142
                                    switch ($chartDetailKey) {
143 65
                                        case 'spPr':
144 19
                                            $possibleNoFill = $chartDetails->spPr->children($this->aNamespace);
145 19
                                            if (isset($possibleNoFill->noFill)) {
146 18
                                                $plotNoFill = true;
147
                                            }
148 19
                                            if (isset($possibleNoFill->gradFill->gsLst)) {
149 3
                                                foreach ($possibleNoFill->gradFill->gsLst->gs as $gradient) {
150 3
                                                    $gradient = Xlsx::testSimpleXml($gradient);
151
                                                    /** @var float $pos */
152 3
                                                    $pos = self::getAttributeFloat($gradient, 'pos');
153 3
                                                    $gradientArray[] = [
154 3
                                                        $pos / ChartProperties::PERCENTAGE_MULTIPLIER,
155 3
                                                        new ChartColor($this->readColor($gradient)),
156 3
                                                    ];
157
                                                }
158
                                            }
159 19
                                            if (isset($possibleNoFill->gradFill->lin)) {
160 3
                                                $gradientLin = ChartProperties::XmlToAngle((string) self::getAttributeString($possibleNoFill->gradFill->lin, 'ang'));
161
                                            }
162
163 19
                                            break;
164 65
                                        case 'layout':
165 62
                                            $plotAreaLayout = $this->chartLayoutDetails($chartDetail);
166
167 62
                                            break;
168 5
                                        case Axis::AXIS_TYPE_CATEGORY:
169 5
                                        case Axis::AXIS_TYPE_DATE:
170 57
                                            $catAxRead = true;
171 57
                                            if (isset($chartDetail->title)) {
172 10
                                                $XaxisLabel = $this->chartTitle($chartDetail->title->children($this->cNamespace));
173
                                            }
174 57
                                            $xAxis->setAxisType($chartDetailKey);
175 57
                                            $this->readEffects($chartDetail, $xAxis);
176 57
                                            $this->readLineStyle($chartDetail, $xAxis);
177 57
                                            if (isset($chartDetail->spPr)) {
178 41
                                                $sppr = $chartDetail->spPr->children($this->aNamespace);
179 41
                                                if (isset($sppr->solidFill)) {
180 4
                                                    $axisColorArray = $this->readColor($sppr->solidFill);
181 4
                                                    $xAxis->setFillParameters($axisColorArray['value'], $axisColorArray['alpha'], $axisColorArray['type']);
182
                                                }
183 41
                                                if (isset($chartDetail->spPr->ln->noFill)) {
184
                                                    $xAxis->setNoFill(true);
185
                                                }
186
                                            }
187 57
                                            if (isset($chartDetail->majorGridlines)) {
188 5
                                                $majorGridlines = new GridLines();
189 5
                                                if (isset($chartDetail->majorGridlines->spPr)) {
190 5
                                                    $this->readEffects($chartDetail->majorGridlines, $majorGridlines);
191 5
                                                    $this->readLineStyle($chartDetail->majorGridlines, $majorGridlines);
192
                                                }
193 5
                                                $xAxis->setMajorGridlines($majorGridlines);
194
                                            }
195 57
                                            if (isset($chartDetail->minorGridlines)) {
196 4
                                                $minorGridlines = new GridLines();
197 4
                                                $minorGridlines->activateObject();
198 4
                                                if (isset($chartDetail->minorGridlines->spPr)) {
199 4
                                                    $this->readEffects($chartDetail->minorGridlines, $minorGridlines);
200 4
                                                    $this->readLineStyle($chartDetail->minorGridlines, $minorGridlines);
201
                                                }
202 4
                                                $xAxis->setMinorGridlines($minorGridlines);
203
                                            }
204 57
                                            $this->setAxisProperties($chartDetail, $xAxis);
205
206 57
                                            break;
207 5
                                        case Axis::AXIS_TYPE_VALUE:
208 63
                                            $whichAxis = null;
209 63
                                            $axPos = null;
210 63
                                            if (isset($chartDetail->axPos)) {
211 63
                                                $axPos = self::getAttributeString($chartDetail->axPos, 'val');
212
                                            }
213 63
                                            if ($catAxRead) {
214 57
                                                $whichAxis = $yAxis;
215 57
                                                $yAxis->setAxisType($chartDetailKey);
216 24
                                            } elseif (!empty($axPos)) {
217
                                                switch ($axPos) {
218 24
                                                    case 't':
219 24
                                                    case 'b':
220 22
                                                        $whichAxis = $xAxis;
221 22
                                                        $xAxis->setAxisType($chartDetailKey);
222
223 22
                                                        break;
224 24
                                                    case 'r':
225 24
                                                    case 'l':
226 24
                                                        $whichAxis = $yAxis;
227 24
                                                        $yAxis->setAxisType($chartDetailKey);
228
229 24
                                                        break;
230
                                                }
231
                                            }
232 63
                                            if (isset($chartDetail->title)) {
233 27
                                                $axisLabel = $this->chartTitle($chartDetail->title->children($this->cNamespace));
234
235
                                                switch ($axPos) {
236 27
                                                    case 't':
237 27
                                                    case 'b':
238 4
                                                        $XaxisLabel = $axisLabel;
239
240 4
                                                        break;
241 27
                                                    case 'r':
242 27
                                                    case 'l':
243 27
                                                        $YaxisLabel = $axisLabel;
244
245 27
                                                        break;
246
                                                }
247
                                            }
248 63
                                            $this->readEffects($chartDetail, $whichAxis);
249 63
                                            $this->readLineStyle($chartDetail, $whichAxis);
250 63
                                            if ($whichAxis !== null && isset($chartDetail->spPr)) {
251 48
                                                $sppr = $chartDetail->spPr->children($this->aNamespace);
252 48
                                                if (isset($sppr->solidFill)) {
253 4
                                                    $axisColorArray = $this->readColor($sppr->solidFill);
254 4
                                                    $whichAxis->setFillParameters($axisColorArray['value'], $axisColorArray['alpha'], $axisColorArray['type']);
255
                                                }
256 48
                                                if (isset($sppr->ln->noFill)) {
257 8
                                                    $whichAxis->setNoFill(true);
258
                                                }
259
                                            }
260 63
                                            if ($whichAxis !== null && isset($chartDetail->majorGridlines)) {
261 49
                                                $majorGridlines = new GridLines();
262 49
                                                if (isset($chartDetail->majorGridlines->spPr)) {
263 33
                                                    $this->readEffects($chartDetail->majorGridlines, $majorGridlines);
264 33
                                                    $this->readLineStyle($chartDetail->majorGridlines, $majorGridlines);
265
                                                }
266 49
                                                $whichAxis->setMajorGridlines($majorGridlines);
267
                                            }
268 63
                                            if ($whichAxis !== null && isset($chartDetail->minorGridlines)) {
269 7
                                                $minorGridlines = new GridLines();
270 7
                                                $minorGridlines->activateObject();
271 7
                                                if (isset($chartDetail->minorGridlines->spPr)) {
272 7
                                                    $this->readEffects($chartDetail->minorGridlines, $minorGridlines);
273 7
                                                    $this->readLineStyle($chartDetail->minorGridlines, $minorGridlines);
274
                                                }
275 7
                                                $whichAxis->setMinorGridlines($minorGridlines);
276
                                            }
277 63
                                            $this->setAxisProperties($chartDetail, $whichAxis);
278
279 63
                                            break;
280 65
                                        case 'barChart':
281 58
                                        case 'bar3DChart':
282 27
                                            $barDirection = self::getAttributeString($chartDetail->barDir, 'val');
283 27
                                            $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey);
284 27
                                            $plotSer->setPlotDirection("$barDirection");
285 27
                                            $plotSeries[] = $plotSer;
286 27
                                            $plotAttributes = $this->readChartAttributes($chartDetail);
287
288 27
                                            break;
289 54
                                        case 'lineChart':
290 41
                                        case 'line3DChart':
291 20
                                            $plotSeries[] = $this->chartDataSeries($chartDetail, $chartDetailKey);
292 20
                                            $plotAttributes = $this->readChartAttributes($chartDetail);
293
294 20
                                            break;
295 41
                                        case 'areaChart':
296 31
                                        case 'area3DChart':
297 12
                                            $plotSeries[] = $this->chartDataSeries($chartDetail, $chartDetailKey);
298 12
                                            $plotAttributes = $this->readChartAttributes($chartDetail);
299
300 12
                                            break;
301 31
                                        case 'doughnutChart':
302 31
                                        case 'pieChart':
303 28
                                        case 'pie3DChart':
304 7
                                            $explosion = self::getAttributeString($chartDetail->ser->explosion, 'val');
305 7
                                            $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey);
306 7
                                            $plotSer->setPlotStyle("$explosion");
307 7
                                            $plotSeries[] = $plotSer;
308 7
                                            $plotAttributes = $this->readChartAttributes($chartDetail);
309
310 7
                                            break;
311 26
                                        case 'scatterChart':
312
                                            /** @var string $scatterStyle */
313 22
                                            $scatterStyle = self::getAttributeString($chartDetail->scatterStyle, 'val');
314 22
                                            $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey);
315 22
                                            $plotSer->setPlotStyle($scatterStyle);
316 22
                                            $plotSeries[] = $plotSer;
317 22
                                            $plotAttributes = $this->readChartAttributes($chartDetail);
318
319 22
                                            break;
320 6
                                        case 'bubbleChart':
321 4
                                            $bubbleScale = self::getAttributeInteger($chartDetail->bubbleScale, 'val');
322 4
                                            $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey);
323 4
                                            $plotSer->setPlotStyle("$bubbleScale");
324 4
                                            $plotSeries[] = $plotSer;
325 4
                                            $plotAttributes = $this->readChartAttributes($chartDetail);
326
327 4
                                            break;
328 4
                                        case 'radarChart':
329
                                            /** @var string $radarStyle */
330 2
                                            $radarStyle = self::getAttributeString($chartDetail->radarStyle, 'val');
331 2
                                            $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey);
332 2
                                            $plotSer->setPlotStyle($radarStyle);
333 2
                                            $plotSeries[] = $plotSer;
334 2
                                            $plotAttributes = $this->readChartAttributes($chartDetail);
335
336 2
                                            break;
337 4
                                        case 'surfaceChart':
338 4
                                        case 'surface3DChart':
339 2
                                            $wireFrame = self::getAttributeBoolean($chartDetail->wireframe, 'val');
340 2
                                            $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey);
341 2
                                            $plotSer->setPlotStyle("$wireFrame");
342 2
                                            $plotSeries[] = $plotSer;
343 2
                                            $plotAttributes = $this->readChartAttributes($chartDetail);
344
345 2
                                            break;
346 4
                                        case 'stockChart':
347 4
                                            $plotSeries[] = $this->chartDataSeries($chartDetail, $chartDetailKey);
348 4
                                            if (isset($chartDetail->upDownBars->gapWidth)) {
349 2
                                                $gapWidth = self::getAttributeInteger($chartDetail->upDownBars->gapWidth, 'val');
350
                                            }
351 4
                                            if (isset($chartDetail->upDownBars->upBars)) {
352 2
                                                $useUpBars = true;
353
                                            }
354 4
                                            if (isset($chartDetail->upDownBars->downBars)) {
355 2
                                                $useDownBars = true;
356
                                            }
357 4
                                            $plotAttributes = $this->readChartAttributes($chartDetail);
358
359 4
                                            break;
360
                                    }
361
                                }
362 65
                                if ($plotAreaLayout == null) {
363 54
                                    $plotAreaLayout = new Layout();
364
                                }
365 65
                                $plotArea = new PlotArea($plotAreaLayout, $plotSeries);
366 65
                                $this->setChartAttributes($plotAreaLayout, $plotAttributes);
367 65
                                if ($plotNoFill) {
368 18
                                    $plotArea->setNoFill(true);
369
                                }
370 65
                                if (!empty($gradientArray)) {
371 3
                                    $plotArea->setGradientFillProperties($gradientArray, $gradientLin);
372
                                }
373 65
                                if (is_int($gapWidth)) {
374 2
                                    $plotArea->setGapWidth($gapWidth);
375
                                }
376 65
                                if ($useUpBars === true) {
377 2
                                    $plotArea->setUseUpBars(true);
378
                                }
379 65
                                if ($useDownBars === true) {
380 2
                                    $plotArea->setUseDownBars(true);
381
                                }
382
383 65
                                break;
384 65
                            case 'plotVisOnly':
385 65
                                $plotVisOnly = (bool) self::getAttributeString($chartDetails, 'val');
386
387 65
                                break;
388 65
                            case 'dispBlanksAs':
389 63
                                $dispBlanksAs = self::getAttributeString($chartDetails, 'val');
390
391 63
                                break;
392 64
                            case 'title':
393 60
                                $title = $this->chartTitle($chartDetails);
394
395 60
                                break;
396 64
                            case 'legend':
397 56
                                $legendPos = 'r';
398 56
                                $legendLayout = null;
399 56
                                $legendOverlay = false;
400 56
                                $legendBorderLines = null;
401 56
                                $legendFillColor = null;
402 56
                                $legendText = null;
403 56
                                $addLegendText = false;
404 56
                                foreach ($chartDetails as $chartDetailKey => $chartDetail) {
405 56
                                    $chartDetail = Xlsx::testSimpleXml($chartDetail);
406
                                    switch ($chartDetailKey) {
407 56
                                        case 'legendPos':
408 56
                                            $legendPos = self::getAttributeString($chartDetail, 'val');
409
410 56
                                            break;
411 54
                                        case 'overlay':
412 53
                                            $legendOverlay = self::getAttributeBoolean($chartDetail, 'val');
413
414 53
                                            break;
415 54
                                        case 'layout':
416 50
                                            $legendLayout = $this->chartLayoutDetails($chartDetail);
417
418 50
                                            break;
419 52
                                        case 'spPr':
420 49
                                            $children = $chartDetails->spPr->children($this->aNamespace);
421 49
                                            if (isset($children->solidFill)) {
422 1
                                                $legendFillColor = $this->readColor($children->solidFill);
423
                                            }
424 49
                                            if (isset($children->ln)) {
425 49
                                                $legendBorderLines = new GridLines();
426 49
                                                $this->readLineStyle($chartDetails, $legendBorderLines);
427
                                            }
428
429 49
                                            break;
430 44
                                        case 'txPr':
431 44
                                            $children = $chartDetails->txPr->children($this->aNamespace);
432 44
                                            $addLegendText = false;
433 44
                                            $legendText = new AxisText();
434 44
                                            if (isset($children->p->pPr->defRPr->solidFill)) {
435 6
                                                $colorArray = $this->readColor($children->p->pPr->defRPr->solidFill);
436 6
                                                $legendText->getFillColorObject()->setColorPropertiesArray($colorArray);
437 6
                                                $addLegendText = true;
438
                                            }
439 44
                                            if (isset($children->p->pPr->defRPr->effectLst)) {
440 1
                                                $this->readEffects($children->p->pPr->defRPr, $legendText, false);
441 1
                                                $addLegendText = true;
442
                                            }
443
444 44
                                            break;
445
                                    }
446
                                }
447 56
                                $legend = new Legend("$legendPos", $legendLayout, (bool) $legendOverlay);
448 56
                                if ($legendFillColor !== null) {
449 1
                                    $legend->getFillColor()->setColorPropertiesArray($legendFillColor);
450
                                }
451 56
                                if ($legendBorderLines !== null) {
452 49
                                    $legend->setBorderLines($legendBorderLines);
453
                                }
454 56
                                if ($addLegendText) {
455 6
                                    $legend->setLegendText($legendText);
456
                                }
457
458 56
                                break;
459
                        }
460
                    }
461
            }
462
        }
463 65
        $chart = new \PhpOffice\PhpSpreadsheet\Chart\Chart($chartName, $title, $legend, $plotArea, $plotVisOnly, (string) $dispBlanksAs, $XaxisLabel, $YaxisLabel, $xAxis, $yAxis);
464 65
        if ($chartNoFill) {
465 3
            $chart->setNoFill(true);
466
        }
467 65
        if ($chartFillColor !== null) {
468 11
            $chart->getFillColor()->setColorPropertiesArray($chartFillColor);
469
        }
470 65
        if ($chartBorderLines !== null) {
471 47
            $chart->setBorderLines($chartBorderLines);
472
        }
473 65
        $chart->setRoundedCorners($roundedCorners);
474 65
        if (is_bool($autoTitleDeleted)) {
475 61
            $chart->setAutoTitleDeleted($autoTitleDeleted);
476
        }
477 65
        if (is_int($rotX)) {
478 8
            $chart->setRotX($rotX);
479
        }
480 65
        if (is_int($rotY)) {
481 8
            $chart->setRotY($rotY);
482
        }
483 65
        if (is_int($rAngAx)) {
484 8
            $chart->setRAngAx($rAngAx);
485
        }
486 65
        if (is_int($perspective)) {
487 2
            $chart->setPerspective($perspective);
488
        }
489
490 65
        return $chart;
491
    }
492
493 60
    private function chartTitle(SimpleXMLElement $titleDetails): Title
494
    {
495 60
        $caption = '';
496 60
        $titleLayout = null;
497 60
        $titleOverlay = false;
498 60
        $titleFormula = null;
499 60
        $titleFont = null;
500 60
        foreach ($titleDetails as $titleDetailKey => $chartDetail) {
501 60
            $chartDetail = Xlsx::testSimpleXml($chartDetail);
502
            switch ($titleDetailKey) {
503 60
                case 'tx':
504 60
                    $caption = [];
505 60
                    if (isset($chartDetail->rich)) {
506 57
                        $titleDetails = $chartDetail->rich->children($this->aNamespace);
507 57
                        foreach ($titleDetails as $titleKey => $titleDetail) {
508 57
                            $titleDetail = Xlsx::testSimpleXml($titleDetail);
509
                            switch ($titleKey) {
510 57
                                case 'p':
511 57
                                    $titleDetailPart = $titleDetail->children($this->aNamespace);
512 57
                                    $caption[] = $this->parseRichText($titleDetailPart);
513
                            }
514
                        }
515 3
                    } elseif (isset($chartDetail->strRef->strCache)) {
516 3
                        foreach ($chartDetail->strRef->strCache->pt as $pt) {
517 3
                            if (isset($pt->v)) {
518 3
                                $caption[] = (string) $pt->v;
519
                            }
520
                        }
521 3
                        if (isset($chartDetail->strRef->f)) {
522 3
                            $titleFormula = (string) $chartDetail->strRef->f;
523
                        }
524
                    }
525
526 60
                    break;
527 60
                case 'overlay':
528 59
                    $titleOverlay = self::getAttributeBoolean($chartDetail, 'val');
529
530 59
                    break;
531 58
                case 'layout':
532 56
                    $titleLayout = $this->chartLayoutDetails($chartDetail);
533
534 56
                    break;
535 33
                case 'txPr':
536 8
                    if (isset($chartDetail->children($this->aNamespace)->p)) {
537 8
                        $titleFont = $this->parseFont($chartDetail->children($this->aNamespace)->p);
538
                    }
539
540 8
                    break;
541
            }
542
        }
543 60
        $title = new Title($caption, $titleLayout, (bool) $titleOverlay);
544 60
        if (!empty($titleFormula)) {
545 3
            $title->setCellReference($titleFormula);
546
        }
547 60
        if ($titleFont !== null) {
548 8
            $title->setFont($titleFont);
549
        }
550
551 60
        return $title;
552
    }
553
554 62
    private function chartLayoutDetails(SimpleXMLElement $chartDetail): ?Layout
555
    {
556 62
        if (!isset($chartDetail->manualLayout)) {
557 52
            return null;
558
        }
559 40
        $details = $chartDetail->manualLayout->children($this->cNamespace);
560 40
        if ($details === null) {
561
            return null;
562
        }
563 40
        $layout = [];
564 40
        foreach ($details as $detailKey => $detail) {
565 23
            $detail = Xlsx::testSimpleXml($detail);
566 23
            $layout[$detailKey] = self::getAttributeString($detail, 'val');
567
        }
568
569 40
        return new Layout($layout);
570
    }
571
572 65
    private function chartDataSeries(SimpleXMLElement $chartDetail, string $plotType): DataSeries
573
    {
574 65
        $multiSeriesType = null;
575 65
        $smoothLine = false;
576 65
        $seriesLabel = $seriesCategory = $seriesValues = $plotOrder = $seriesBubbles = [];
577 65
        $plotDirection = null;
578
579 65
        $seriesDetailSet = $chartDetail->children($this->cNamespace);
580 65
        foreach ($seriesDetailSet as $seriesDetailKey => $seriesDetails) {
581
            switch ($seriesDetailKey) {
582 65
                case 'grouping':
583 54
                    $multiSeriesType = self::getAttributeString($chartDetail->grouping, 'val');
584
585 54
                    break;
586 65
                case 'ser':
587 65
                    $marker = null;
588 65
                    $seriesIndex = '';
589 65
                    $fillColor = null;
590 65
                    $pointSize = null;
591 65
                    $noFill = false;
592 65
                    $bubble3D = false;
593 65
                    $dptColors = [];
594 65
                    $markerFillColor = null;
595 65
                    $markerBorderColor = null;
596 65
                    $lineStyle = null;
597 65
                    $labelLayout = null;
598 65
                    $trendLines = [];
599 65
                    foreach ($seriesDetails as $seriesKey => $seriesDetail) {
600 65
                        $seriesDetail = Xlsx::testSimpleXml($seriesDetail);
601
                        switch ($seriesKey) {
602 65
                            case 'idx':
603 65
                                $seriesIndex = self::getAttributeInteger($seriesDetail, 'val');
604
605 65
                                break;
606 65
                            case 'order':
607 65
                                $seriesOrder = self::getAttributeInteger($seriesDetail, 'val');
608 65
                                if ($seriesOrder !== null) {
609 65
                                    $plotOrder[$seriesIndex] = $seriesOrder;
610
                                }
611
612 65
                                break;
613 65
                            case 'tx':
614 64
                                $temp = $this->chartDataSeriesValueSet($seriesDetail);
615 64
                                if ($temp !== null) {
616 64
                                    $seriesLabel[$seriesIndex] = $temp;
617
                                }
618
619 64
                                break;
620 65
                            case 'spPr':
621 62
                                $children = $seriesDetail->children($this->aNamespace);
622 62
                                if (isset($children->ln)) {
623 62
                                    $ln = $children->ln;
624 62
                                    if (is_countable($ln->noFill) && count($ln->noFill) === 1) {
625 23
                                        $noFill = true;
626
                                    }
627 62
                                    $lineStyle = new GridLines();
628 62
                                    $this->readLineStyle($seriesDetails, $lineStyle);
629
                                }
630 62
                                if (isset($children->effectLst)) {
631 6
                                    if ($lineStyle === null) {
632 3
                                        $lineStyle = new GridLines();
633
                                    }
634 6
                                    $this->readEffects($seriesDetails, $lineStyle);
635
                                }
636 62
                                if (isset($children->solidFill)) {
637 21
                                    $fillColor = new ChartColor($this->readColor($children->solidFill));
638
                                }
639
640 62
                                break;
641 65
                            case 'dPt':
642 8
                                $dptIdx = (int) self::getAttributeString($seriesDetail->idx, 'val');
643 8
                                if (isset($seriesDetail->spPr)) {
644 8
                                    $children = $seriesDetail->spPr->children($this->aNamespace);
645 8
                                    if (isset($children->solidFill)) {
646 8
                                        $arrayColors = $this->readColor($children->solidFill);
647 8
                                        $dptColors[$dptIdx] = new ChartColor($arrayColors);
648
                                    }
649
                                }
650
651 8
                                break;
652 65
                            case 'trendline':
653 6
                                $trendLine = new TrendLine();
654 6
                                $this->readLineStyle($seriesDetail, $trendLine);
655 6
                                $trendLineType = self::getAttributeString($seriesDetail->trendlineType, 'val');
656 6
                                $dispRSqr = self::getAttributeBoolean($seriesDetail->dispRSqr, 'val');
657 6
                                $dispEq = self::getAttributeBoolean($seriesDetail->dispEq, 'val');
658 6
                                $order = self::getAttributeInteger($seriesDetail->order, 'val');
659 6
                                $period = self::getAttributeInteger($seriesDetail->period, 'val');
660 6
                                $forward = self::getAttributeFloat($seriesDetail->forward, 'val');
661 6
                                $backward = self::getAttributeFloat($seriesDetail->backward, 'val');
662 6
                                $intercept = self::getAttributeFloat($seriesDetail->intercept, 'val');
663 6
                                $name = (string) $seriesDetail->name;
664 6
                                $trendLine->setTrendLineProperties(
665 6
                                    $trendLineType,
666 6
                                    $order,
667 6
                                    $period,
668 6
                                    $dispRSqr,
669 6
                                    $dispEq,
670 6
                                    $backward,
671 6
                                    $forward,
672 6
                                    $intercept,
673 6
                                    $name
674 6
                                );
675 6
                                $trendLines[] = $trendLine;
676
677 6
                                break;
678 65
                            case 'marker':
679 29
                                $marker = self::getAttributeString($seriesDetail->symbol, 'val');
680 29
                                $pointSize = self::getAttributeString($seriesDetail->size, 'val');
681 29
                                $pointSize = is_numeric($pointSize) ? ((int) $pointSize) : null;
682 29
                                if (isset($seriesDetail->spPr)) {
683 26
                                    $children = $seriesDetail->spPr->children($this->aNamespace);
684 26
                                    if (isset($children->solidFill)) {
685 24
                                        $markerFillColor = $this->readColor($children->solidFill);
686
                                    }
687 26
                                    if (isset($children->ln->solidFill)) {
688 16
                                        $markerBorderColor = $this->readColor($children->ln->solidFill);
689
                                    }
690
                                }
691
692 29
                                break;
693 65
                            case 'smooth':
694 34
                                $smoothLine = self::getAttributeBoolean($seriesDetail, 'val') ?? false;
695
696 34
                                break;
697 65
                            case 'cat':
698 47
                                $temp = $this->chartDataSeriesValueSet($seriesDetail);
699 47
                                if ($temp !== null) {
700 47
                                    $seriesCategory[$seriesIndex] = $temp;
701
                                }
702
703 47
                                break;
704 65
                            case 'val':
705 57
                                $temp = $this->chartDataSeriesValueSet($seriesDetail, "$marker", $fillColor, "$pointSize");
706 57
                                if ($temp !== null) {
707 57
                                    $seriesValues[$seriesIndex] = $temp;
708
                                }
709
710 57
                                break;
711 49
                            case 'xVal':
712 24
                                $temp = $this->chartDataSeriesValueSet($seriesDetail, "$marker", $fillColor, "$pointSize");
713 24
                                if ($temp !== null) {
714 24
                                    $seriesCategory[$seriesIndex] = $temp;
715
                                }
716
717 24
                                break;
718 49
                            case 'yVal':
719 24
                                $temp = $this->chartDataSeriesValueSet($seriesDetail, "$marker", $fillColor, "$pointSize");
720 24
                                if ($temp !== null) {
721 24
                                    $seriesValues[$seriesIndex] = $temp;
722
                                }
723
724 24
                                break;
725 46
                            case 'bubbleSize':
726 4
                                $seriesBubble = $this->chartDataSeriesValueSet($seriesDetail, "$marker", $fillColor, "$pointSize");
727 4
                                if ($seriesBubble !== null) {
728 3
                                    $seriesBubbles[$seriesIndex] = $seriesBubble;
729
                                }
730
731 4
                                break;
732 44
                            case 'bubble3D':
733 2
                                $bubble3D = self::getAttributeBoolean($seriesDetail, 'val');
734
735 2
                                break;
736 44
                            case 'dLbls':
737 8
                                $labelLayout = new Layout($this->readChartAttributes($seriesDetails));
738
739 8
                                break;
740
                        }
741
                    }
742 65
                    if ($labelLayout) {
743 8
                        if (isset($seriesLabel[$seriesIndex])) {
744 8
                            $seriesLabel[$seriesIndex]->setLabelLayout($labelLayout);
745
                        }
746 8
                        if (isset($seriesCategory[$seriesIndex])) {
747 5
                            $seriesCategory[$seriesIndex]->setLabelLayout($labelLayout);
748
                        }
749 8
                        if (isset($seriesValues[$seriesIndex])) {
750 8
                            $seriesValues[$seriesIndex]->setLabelLayout($labelLayout);
751
                        }
752
                    }
753 65
                    if ($noFill) {
754 23
                        if (isset($seriesLabel[$seriesIndex])) {
755 23
                            $seriesLabel[$seriesIndex]->setScatterLines(false);
756
                        }
757 23
                        if (isset($seriesCategory[$seriesIndex])) {
758 23
                            $seriesCategory[$seriesIndex]->setScatterLines(false);
759
                        }
760 23
                        if (isset($seriesValues[$seriesIndex])) {
761 23
                            $seriesValues[$seriesIndex]->setScatterLines(false);
762
                        }
763
                    }
764 65
                    if ($lineStyle !== null) {
765 62
                        if (isset($seriesLabel[$seriesIndex])) {
766 62
                            $seriesLabel[$seriesIndex]->copyLineStyles($lineStyle);
767
                        }
768 62
                        if (isset($seriesCategory[$seriesIndex])) {
769 52
                            $seriesCategory[$seriesIndex]->copyLineStyles($lineStyle);
770
                        }
771 62
                        if (isset($seriesValues[$seriesIndex])) {
772 62
                            $seriesValues[$seriesIndex]->copyLineStyles($lineStyle);
773
                        }
774
                    }
775 65
                    if ($bubble3D) {
776 2
                        if (isset($seriesLabel[$seriesIndex])) {
777 2
                            $seriesLabel[$seriesIndex]->setBubble3D($bubble3D);
778
                        }
779 2
                        if (isset($seriesCategory[$seriesIndex])) {
780 2
                            $seriesCategory[$seriesIndex]->setBubble3D($bubble3D);
781
                        }
782 2
                        if (isset($seriesValues[$seriesIndex])) {
783 2
                            $seriesValues[$seriesIndex]->setBubble3D($bubble3D);
784
                        }
785
                    }
786 65
                    if (!empty($dptColors)) {
787 8
                        if (isset($seriesLabel[$seriesIndex])) {
788 6
                            $seriesLabel[$seriesIndex]->setFillColor($dptColors);
789
                        }
790 8
                        if (isset($seriesCategory[$seriesIndex])) {
791 8
                            $seriesCategory[$seriesIndex]->setFillColor($dptColors);
792
                        }
793 8
                        if (isset($seriesValues[$seriesIndex])) {
794 8
                            $seriesValues[$seriesIndex]->setFillColor($dptColors);
795
                        }
796
                    }
797 65
                    if ($markerFillColor !== null) {
798 24
                        if (isset($seriesLabel[$seriesIndex])) {
799 24
                            $seriesLabel[$seriesIndex]->getMarkerFillColor()->setColorPropertiesArray($markerFillColor);
800
                        }
801 24
                        if (isset($seriesCategory[$seriesIndex])) {
802 24
                            $seriesCategory[$seriesIndex]->getMarkerFillColor()->setColorPropertiesArray($markerFillColor);
803
                        }
804 24
                        if (isset($seriesValues[$seriesIndex])) {
805 24
                            $seriesValues[$seriesIndex]->getMarkerFillColor()->setColorPropertiesArray($markerFillColor);
806
                        }
807
                    }
808 65
                    if ($markerBorderColor !== null) {
809 16
                        if (isset($seriesLabel[$seriesIndex])) {
810 16
                            $seriesLabel[$seriesIndex]->getMarkerBorderColor()->setColorPropertiesArray($markerBorderColor);
811
                        }
812 16
                        if (isset($seriesCategory[$seriesIndex])) {
813 16
                            $seriesCategory[$seriesIndex]->getMarkerBorderColor()->setColorPropertiesArray($markerBorderColor);
814
                        }
815 16
                        if (isset($seriesValues[$seriesIndex])) {
816 16
                            $seriesValues[$seriesIndex]->getMarkerBorderColor()->setColorPropertiesArray($markerBorderColor);
817
                        }
818
                    }
819 65
                    if ($smoothLine) {
820 11
                        if (isset($seriesLabel[$seriesIndex])) {
821 11
                            $seriesLabel[$seriesIndex]->setSmoothLine(true);
822
                        }
823 11
                        if (isset($seriesCategory[$seriesIndex])) {
824 11
                            $seriesCategory[$seriesIndex]->setSmoothLine(true);
825
                        }
826 11
                        if (isset($seriesValues[$seriesIndex])) {
827 11
                            $seriesValues[$seriesIndex]->setSmoothLine(true);
828
                        }
829
                    }
830 65
                    if (!empty($trendLines)) {
831 6
                        if (isset($seriesLabel[$seriesIndex])) {
832 6
                            $seriesLabel[$seriesIndex]->setTrendLines($trendLines);
833
                        }
834 6
                        if (isset($seriesCategory[$seriesIndex])) {
835 6
                            $seriesCategory[$seriesIndex]->setTrendLines($trendLines);
836
                        }
837 6
                        if (isset($seriesValues[$seriesIndex])) {
838 6
                            $seriesValues[$seriesIndex]->setTrendLines($trendLines);
839
                        }
840
                    }
841
            }
842
        }
843 65
        $series = new DataSeries($plotType, $multiSeriesType, $plotOrder, $seriesLabel, $seriesCategory, $seriesValues, $plotDirection, $smoothLine);
844 65
        $series->setPlotBubbleSizes($seriesBubbles);
845
846 65
        return $series;
847
    }
848
849 65
    private function chartDataSeriesValueSet(SimpleXMLElement $seriesDetail, ?string $marker = null, ?ChartColor $fillColor = null, ?string $pointSize = null): ?DataSeriesValues
850
    {
851 65
        if (isset($seriesDetail->strRef)) {
852 63
            $seriesSource = (string) $seriesDetail->strRef->f;
853 63
            $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize");
854
855 63
            if (isset($seriesDetail->strRef->strCache)) {
856 62
                $seriesData = $this->chartDataSeriesValues($seriesDetail->strRef->strCache->children($this->cNamespace), 's');
857 62
                $seriesValues
858 62
                    ->setFormatCode($seriesData['formatCode'])
859 62
                    ->setDataValues($seriesData['dataValues']);
860
            }
861
862 63
            return $seriesValues;
863 65
        } elseif (isset($seriesDetail->numRef)) {
864 65
            $seriesSource = (string) $seriesDetail->numRef->f;
865 65
            $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize");
866 65
            if (isset($seriesDetail->numRef->numCache)) {
867 63
                $seriesData = $this->chartDataSeriesValues($seriesDetail->numRef->numCache->children($this->cNamespace));
868 63
                $seriesValues
869 63
                    ->setFormatCode($seriesData['formatCode'])
870 63
                    ->setDataValues($seriesData['dataValues']);
871
            }
872
873 65
            return $seriesValues;
874 27
        } elseif (isset($seriesDetail->multiLvlStrRef)) {
875 21
            $seriesSource = (string) $seriesDetail->multiLvlStrRef->f;
876 21
            $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize");
877
878 21
            if (isset($seriesDetail->multiLvlStrRef->multiLvlStrCache)) {
879 21
                $seriesData = $this->chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($this->cNamespace), 's');
880 21
                $seriesValues
881 21
                    ->setFormatCode($seriesData['formatCode'])
882 21
                    ->setDataValues($seriesData['dataValues']);
883
            }
884
885 21
            return $seriesValues;
886 8
        } elseif (isset($seriesDetail->multiLvlNumRef)) {
887
            $seriesSource = (string) $seriesDetail->multiLvlNumRef->f;
888
            $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize");
889
890
            if (isset($seriesDetail->multiLvlNumRef->multiLvlNumCache)) {
891
                $seriesData = $this->chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($this->cNamespace), 's');
892
                $seriesValues
893
                    ->setFormatCode($seriesData['formatCode'])
894
                    ->setDataValues($seriesData['dataValues']);
895
            }
896
897
            return $seriesValues;
898
        }
899
900 8
        if (isset($seriesDetail->v)) {
901 7
            return new DataSeriesValues(
902 7
                DataSeriesValues::DATASERIES_TYPE_STRING,
903 7
                null,
904 7
                null,
905 7
                1,
906 7
                [(string) $seriesDetail->v]
907 7
            );
908
        }
909
910 2
        return null;
911
    }
912
913 63
    private function chartDataSeriesValues(SimpleXMLElement $seriesValueSet, string $dataType = 'n'): array
914
    {
915 63
        $seriesVal = [];
916 63
        $formatCode = '';
917 63
        $pointCount = 0;
918
919 63
        foreach ($seriesValueSet as $seriesValueIdx => $seriesValue) {
920 62
            $seriesValue = Xlsx::testSimpleXml($seriesValue);
921
            switch ($seriesValueIdx) {
922 62
                case 'ptCount':
923 62
                    $pointCount = self::getAttributeInteger($seriesValue, 'val');
924
925 62
                    break;
926 62
                case 'formatCode':
927 48
                    $formatCode = (string) $seriesValue;
928
929 48
                    break;
930 62
                case 'pt':
931 62
                    $pointVal = self::getAttributeInteger($seriesValue, 'idx');
932 62
                    if ($dataType == 's') {
933 62
                        $seriesVal[$pointVal] = (string) $seriesValue->v;
934 62
                    } elseif ((string) $seriesValue->v === ExcelError::NA()) {
935
                        $seriesVal[$pointVal] = null;
936
                    } else {
937 62
                        $seriesVal[$pointVal] = (float) $seriesValue->v;
938
                    }
939
940 62
                    break;
941
            }
942
        }
943
944 63
        return [
945 63
            'formatCode' => $formatCode,
946 63
            'pointCount' => $pointCount,
947 63
            'dataValues' => $seriesVal,
948 63
        ];
949
    }
950
951 21
    private function chartDataSeriesValuesMultiLevel(SimpleXMLElement $seriesValueSet, string $dataType = 'n'): array
952
    {
953 21
        $seriesVal = [];
954 21
        $formatCode = '';
955 21
        $pointCount = 0;
956
957 21
        foreach ($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) {
958 21
            foreach ($seriesLevel as $seriesValueIdx => $seriesValue) {
959 21
                $seriesValue = Xlsx::testSimpleXml($seriesValue);
960
                switch ($seriesValueIdx) {
961 21
                    case 'ptCount':
962
                        $pointCount = self::getAttributeInteger($seriesValue, 'val');
963
964
                        break;
965 21
                    case 'formatCode':
966
                        $formatCode = (string) $seriesValue;
967
968
                        break;
969 21
                    case 'pt':
970 21
                        $pointVal = self::getAttributeInteger($seriesValue, 'idx');
971 21
                        if ($dataType == 's') {
972 21
                            $seriesVal[$pointVal][] = (string) $seriesValue->v;
973
                        } elseif ((string) $seriesValue->v === ExcelError::NA()) {
974
                            $seriesVal[$pointVal] = null;
975
                        } else {
976
                            $seriesVal[$pointVal][] = (float) $seriesValue->v;
977
                        }
978
979 21
                        break;
980
                }
981
            }
982
        }
983
984 21
        return [
985 21
            'formatCode' => $formatCode,
986 21
            'pointCount' => $pointCount,
987 21
            'dataValues' => $seriesVal,
988 21
        ];
989
    }
990
991 57
    private function parseRichText(SimpleXMLElement $titleDetailPart): RichText
992
    {
993 57
        $value = new RichText();
994 57
        $defaultFontSize = null;
995 57
        $defaultBold = null;
996 57
        $defaultItalic = null;
997 57
        $defaultUnderscore = null;
998 57
        $defaultStrikethrough = null;
999 57
        $defaultBaseline = null;
1000 57
        $defaultFontName = null;
1001 57
        $defaultLatin = null;
1002 57
        $defaultEastAsian = null;
1003 57
        $defaultComplexScript = null;
1004 57
        $defaultFontColor = null;
1005 57
        if (isset($titleDetailPart->pPr->defRPr)) {
1006 57
            $defaultFontSize = self::getAttributeInteger($titleDetailPart->pPr->defRPr, 'sz');
1007 57
            $defaultBold = self::getAttributeBoolean($titleDetailPart->pPr->defRPr, 'b');
1008 57
            $defaultItalic = self::getAttributeBoolean($titleDetailPart->pPr->defRPr, 'i');
1009 57
            $defaultUnderscore = self::getAttributeString($titleDetailPart->pPr->defRPr, 'u');
1010 57
            $defaultStrikethrough = self::getAttributeString($titleDetailPart->pPr->defRPr, 'strike');
1011 57
            $defaultBaseline = self::getAttributeInteger($titleDetailPart->pPr->defRPr, 'baseline');
1012 57
            if (isset($titleDetailPart->defRPr->rFont['val'])) {
1013
                $defaultFontName = (string) $titleDetailPart->defRPr->rFont['val'];
1014
            }
1015 57
            if (isset($titleDetailPart->pPr->defRPr->latin)) {
1016 30
                $defaultLatin = self::getAttributeString($titleDetailPart->pPr->defRPr->latin, 'typeface');
1017
            }
1018 57
            if (isset($titleDetailPart->pPr->defRPr->ea)) {
1019 28
                $defaultEastAsian = self::getAttributeString($titleDetailPart->pPr->defRPr->ea, 'typeface');
1020
            }
1021 57
            if (isset($titleDetailPart->pPr->defRPr->cs)) {
1022 28
                $defaultComplexScript = self::getAttributeString($titleDetailPart->pPr->defRPr->cs, 'typeface');
1023
            }
1024 57
            if (isset($titleDetailPart->pPr->defRPr->solidFill)) {
1025 30
                $defaultFontColor = $this->readColor($titleDetailPart->pPr->defRPr->solidFill);
1026
            }
1027
        }
1028 57
        foreach ($titleDetailPart as $titleDetailElementKey => $titleDetailElement) {
1029
            if (
1030 57
                (string) $titleDetailElementKey !== 'r'
1031 57
                || !isset($titleDetailElement->t)
1032
            ) {
1033 57
                continue;
1034
            }
1035 57
            $objText = $value->createTextRun((string) $titleDetailElement->t);
1036 57
            if ($objText->getFont() === null) {
1037
                // @codeCoverageIgnoreStart
1038
                continue;
1039
                // @codeCoverageIgnoreEnd
1040
            }
1041 57
            $fontSize = null;
1042 57
            $bold = null;
1043 57
            $italic = null;
1044 57
            $underscore = null;
1045 57
            $strikethrough = null;
1046 57
            $baseline = null;
1047 57
            $fontName = null;
1048 57
            $latinName = null;
1049 57
            $eastAsian = null;
1050 57
            $complexScript = null;
1051 57
            $fontColor = null;
1052 57
            $underlineColor = null;
1053 57
            if (isset($titleDetailElement->rPr)) {
1054
                // not used now, not sure it ever was, grandfathering
1055 41
                if (isset($titleDetailElement->rPr->rFont['val'])) {
1056
                    // @codeCoverageIgnoreStart
1057
                    $fontName = (string) $titleDetailElement->rPr->rFont['val'];
1058
                    // @codeCoverageIgnoreEnd
1059
                }
1060 41
                if (isset($titleDetailElement->rPr->latin)) {
1061 22
                    $latinName = self::getAttributeString($titleDetailElement->rPr->latin, 'typeface');
1062
                }
1063 41
                if (isset($titleDetailElement->rPr->ea)) {
1064 11
                    $eastAsian = self::getAttributeString($titleDetailElement->rPr->ea, 'typeface');
1065
                }
1066 41
                if (isset($titleDetailElement->rPr->cs)) {
1067 13
                    $complexScript = self::getAttributeString($titleDetailElement->rPr->cs, 'typeface');
1068
                }
1069 41
                $fontSize = self::getAttributeInteger($titleDetailElement->rPr, 'sz');
1070
1071
                // not used now, not sure it ever was, grandfathering
1072 41
                if (isset($titleDetailElement->rPr->solidFill)) {
1073 21
                    $fontColor = $this->readColor($titleDetailElement->rPr->solidFill);
1074
                }
1075
1076 41
                $bold = self::getAttributeBoolean($titleDetailElement->rPr, 'b');
1077 41
                $italic = self::getAttributeBoolean($titleDetailElement->rPr, 'i');
1078 41
                $baseline = self::getAttributeInteger($titleDetailElement->rPr, 'baseline');
1079 41
                $underscore = self::getAttributeString($titleDetailElement->rPr, 'u');
1080 41
                if (isset($titleDetailElement->rPr->uFill->solidFill)) {
1081 7
                    $underlineColor = $this->readColor($titleDetailElement->rPr->uFill->solidFill);
1082
                }
1083
1084 41
                $strikethrough = self::getAttributeString($titleDetailElement->rPr, 'strike');
1085
            }
1086
1087 57
            $fontFound = false;
1088 57
            $latinName = $latinName ?? $defaultLatin;
1089 57
            if ($latinName !== null) {
1090 31
                $objText->getFont()->setLatin($latinName);
1091 31
                $fontFound = true;
1092
            }
1093 57
            $eastAsian = $eastAsian ?? $defaultEastAsian;
1094 57
            if ($eastAsian !== null) {
1095 28
                $objText->getFont()->setEastAsian($eastAsian);
1096 28
                $fontFound = true;
1097
            }
1098 57
            $complexScript = $complexScript ?? $defaultComplexScript;
1099 57
            if ($complexScript !== null) {
1100 28
                $objText->getFont()->setComplexScript($complexScript);
1101 28
                $fontFound = true;
1102
            }
1103 57
            $fontName = $fontName ?? $defaultFontName;
1104 57
            if ($fontName !== null) {
1105
                // @codeCoverageIgnoreStart
1106
                $objText->getFont()->setName($fontName);
1107
                $fontFound = true;
1108
                // @codeCoverageIgnoreEnd
1109
            }
1110
1111 57
            $fontSize = $fontSize ?? $defaultFontSize;
1112 57
            if (is_int($fontSize)) {
1113 29
                $objText->getFont()->setSize(floor($fontSize / 100));
1114 29
                $fontFound = true;
1115
            } else {
1116 30
                $objText->getFont()->setSize(null, true);
1117
            }
1118
1119 57
            $fontColor = $fontColor ?? $defaultFontColor;
1120 57
            if (!empty($fontColor)) {
1121 30
                $objText->getFont()->setChartColor($fontColor);
1122 30
                $fontFound = true;
1123
            }
1124
1125 57
            $bold = $bold ?? $defaultBold;
1126 57
            if ($bold !== null) {
1127 36
                $objText->getFont()->setBold($bold);
1128 36
                $fontFound = true;
1129
            }
1130
1131 57
            $italic = $italic ?? $defaultItalic;
1132 57
            if ($italic !== null) {
1133 35
                $objText->getFont()->setItalic($italic);
1134 35
                $fontFound = true;
1135
            }
1136
1137 57
            $baseline = $baseline ?? $defaultBaseline;
1138 57
            if ($baseline !== null) {
1139 32
                $objText->getFont()->setBaseLine($baseline);
1140 32
                if ($baseline > 0) {
1141 7
                    $objText->getFont()->setSuperscript(true);
1142 32
                } elseif ($baseline < 0) {
1143 7
                    $objText->getFont()->setSubscript(true);
1144
                }
1145 32
                $fontFound = true;
1146
            }
1147
1148 57
            $underscore = $underscore ?? $defaultUnderscore;
1149 57
            if ($underscore !== null) {
1150 35
                if ($underscore == 'sng') {
1151 8
                    $objText->getFont()->setUnderline(Font::UNDERLINE_SINGLE);
1152 35
                } elseif ($underscore == 'dbl') {
1153 7
                    $objText->getFont()->setUnderline(Font::UNDERLINE_DOUBLE);
1154 35
                } elseif ($underscore !== '') {
1155 35
                    $objText->getFont()->setUnderline($underscore);
1156
                } else {
1157
                    $objText->getFont()->setUnderline(Font::UNDERLINE_NONE);
1158
                }
1159 35
                $fontFound = true;
1160 35
                if ($underlineColor) {
1161 7
                    $objText->getFont()->setUnderlineColor($underlineColor);
1162
                }
1163
            }
1164
1165 57
            $strikethrough = $strikethrough ?? $defaultStrikethrough;
1166 57
            if ($strikethrough !== null) {
1167 35
                $objText->getFont()->setStrikeType($strikethrough);
1168 35
                if ($strikethrough == 'noStrike') {
1169 35
                    $objText->getFont()->setStrikethrough(false);
1170
                } else {
1171 7
                    $objText->getFont()->setStrikethrough(true);
1172
                }
1173 35
                $fontFound = true;
1174
            }
1175 57
            if ($fontFound === false) {
1176 29
                $objText->setFont(null);
1177
            }
1178
        }
1179
1180 57
        return $value;
1181
    }
1182
1183 20
    private function parseFont(SimpleXMLElement $titleDetailPart): ?Font
1184
    {
1185 20
        if (!isset($titleDetailPart->pPr->defRPr)) {
1186
            return null;
1187
        }
1188 20
        $fontArray = [];
1189 20
        $fontArray['size'] = self::getAttributeInteger($titleDetailPart->pPr->defRPr, 'sz');
1190 20
        $fontArray['bold'] = self::getAttributeBoolean($titleDetailPart->pPr->defRPr, 'b');
1191 20
        $fontArray['italic'] = self::getAttributeBoolean($titleDetailPart->pPr->defRPr, 'i');
1192 20
        $fontArray['underscore'] = self::getAttributeString($titleDetailPart->pPr->defRPr, 'u');
1193 20
        $fontArray['strikethrough'] = self::getAttributeString($titleDetailPart->pPr->defRPr, 'strike');
1194 20
        $fontArray['cap'] = self::getAttributeString($titleDetailPart->pPr->defRPr, 'cap');
1195
1196 20
        if (isset($titleDetailPart->pPr->defRPr->latin)) {
1197 12
            $fontArray['latin'] = self::getAttributeString($titleDetailPart->pPr->defRPr->latin, 'typeface');
1198
        }
1199 20
        if (isset($titleDetailPart->pPr->defRPr->ea)) {
1200 5
            $fontArray['eastAsian'] = self::getAttributeString($titleDetailPart->pPr->defRPr->ea, 'typeface');
1201
        }
1202 20
        if (isset($titleDetailPart->pPr->defRPr->cs)) {
1203 5
            $fontArray['complexScript'] = self::getAttributeString($titleDetailPart->pPr->defRPr->cs, 'typeface');
1204
        }
1205 20
        if (isset($titleDetailPart->pPr->defRPr->solidFill)) {
1206 13
            $fontArray['chartColor'] = new ChartColor($this->readColor($titleDetailPart->pPr->defRPr->solidFill));
1207
        }
1208 20
        $font = new Font();
1209 20
        $font->setSize(null, true);
1210 20
        $font->applyFromArray($fontArray);
1211
1212 20
        return $font;
1213
    }
1214
1215 65
    private function readChartAttributes(?SimpleXMLElement $chartDetail): array
1216
    {
1217 65
        $plotAttributes = [];
1218 65
        if (isset($chartDetail->dLbls)) {
1219 48
            if (isset($chartDetail->dLbls->dLblPos)) {
1220 6
                $plotAttributes['dLblPos'] = self::getAttributeString($chartDetail->dLbls->dLblPos, 'val');
1221
            }
1222 48
            if (isset($chartDetail->dLbls->numFmt)) {
1223 4
                $plotAttributes['numFmtCode'] = self::getAttributeString($chartDetail->dLbls->numFmt, 'formatCode');
1224 4
                $plotAttributes['numFmtLinked'] = self::getAttributeBoolean($chartDetail->dLbls->numFmt, 'sourceLinked');
1225
            }
1226 48
            if (isset($chartDetail->dLbls->showLegendKey)) {
1227 46
                $plotAttributes['showLegendKey'] = self::getAttributeString($chartDetail->dLbls->showLegendKey, 'val');
1228
            }
1229 48
            if (isset($chartDetail->dLbls->showVal)) {
1230 48
                $plotAttributes['showVal'] = self::getAttributeString($chartDetail->dLbls->showVal, 'val');
1231
            }
1232 48
            if (isset($chartDetail->dLbls->showCatName)) {
1233 46
                $plotAttributes['showCatName'] = self::getAttributeString($chartDetail->dLbls->showCatName, 'val');
1234
            }
1235 48
            if (isset($chartDetail->dLbls->showSerName)) {
1236 46
                $plotAttributes['showSerName'] = self::getAttributeString($chartDetail->dLbls->showSerName, 'val');
1237
            }
1238 48
            if (isset($chartDetail->dLbls->showPercent)) {
1239 48
                $plotAttributes['showPercent'] = self::getAttributeString($chartDetail->dLbls->showPercent, 'val');
1240
            }
1241 48
            if (isset($chartDetail->dLbls->showBubbleSize)) {
1242 43
                $plotAttributes['showBubbleSize'] = self::getAttributeString($chartDetail->dLbls->showBubbleSize, 'val');
1243
            }
1244 48
            if (isset($chartDetail->dLbls->showLeaderLines)) {
1245 10
                $plotAttributes['showLeaderLines'] = self::getAttributeString($chartDetail->dLbls->showLeaderLines, 'val');
1246
            }
1247 48
            if (isset($chartDetail->dLbls->spPr)) {
1248 5
                $sppr = $chartDetail->dLbls->spPr->children($this->aNamespace);
1249 5
                if (isset($sppr->solidFill)) {
1250 3
                    $plotAttributes['labelFillColor'] = new ChartColor($this->readColor($sppr->solidFill));
1251
                }
1252 5
                if (isset($sppr->ln->solidFill)) {
1253 3
                    $plotAttributes['labelBorderColor'] = new ChartColor($this->readColor($sppr->ln->solidFill));
1254
                }
1255
            }
1256 48
            if (isset($chartDetail->dLbls->txPr)) {
1257 8
                $txpr = $chartDetail->dLbls->txPr->children($this->aNamespace);
1258 8
                if (isset($txpr->p)) {
1259 8
                    $plotAttributes['labelFont'] = $this->parseFont($txpr->p);
1260 8
                    if (isset($txpr->p->pPr->defRPr->effectLst)) {
1261 3
                        $labelEffects = new GridLines();
1262 3
                        $this->readEffects($txpr->p->pPr->defRPr, $labelEffects, false);
1263 3
                        $plotAttributes['labelEffects'] = $labelEffects;
1264
                    }
1265
                }
1266
            }
1267
        }
1268
1269 65
        return $plotAttributes;
1270
    }
1271
1272 65
    private function setChartAttributes(Layout $plotArea, array $plotAttributes): void
1273
    {
1274 65
        foreach ($plotAttributes as $plotAttributeKey => $plotAttributeValue) {
1275
            switch ($plotAttributeKey) {
1276 45
                case 'showLegendKey':
1277 43
                    $plotArea->setShowLegendKey($plotAttributeValue);
1278
1279 43
                    break;
1280 45
                case 'showVal':
1281 45
                    $plotArea->setShowVal($plotAttributeValue);
1282
1283 45
                    break;
1284 45
                case 'showCatName':
1285 43
                    $plotArea->setShowCatName($plotAttributeValue);
1286
1287 43
                    break;
1288 45
                case 'showSerName':
1289 43
                    $plotArea->setShowSerName($plotAttributeValue);
1290
1291 43
                    break;
1292 45
                case 'showPercent':
1293 45
                    $plotArea->setShowPercent($plotAttributeValue);
1294
1295 45
                    break;
1296 43
                case 'showBubbleSize':
1297 43
                    $plotArea->setShowBubbleSize($plotAttributeValue);
1298
1299 43
                    break;
1300 4
                case 'showLeaderLines':
1301 4
                    $plotArea->setShowLeaderLines($plotAttributeValue);
1302
1303 4
                    break;
1304
            }
1305
        }
1306
    }
1307
1308 63
    private function readEffects(SimpleXMLElement $chartDetail, ?ChartProperties $chartObject, bool $getSppr = true): void
1309
    {
1310 63
        if (!isset($chartObject)) {
1311
            return;
1312
        }
1313 63
        if ($getSppr) {
1314 63
            if (!isset($chartDetail->spPr)) {
1315 35
                return;
1316
            }
1317 48
            $sppr = $chartDetail->spPr->children($this->aNamespace);
1318
        } else {
1319 5
            $sppr = $chartDetail;
1320
        }
1321 48
        if (isset($sppr->effectLst->glow)) {
1322 8
            $axisGlowSize = (float) self::getAttributeInteger($sppr->effectLst->glow, 'rad') / ChartProperties::POINTS_WIDTH_MULTIPLIER;
1323 8
            if ($axisGlowSize != 0.0) {
1324 8
                $colorArray = $this->readColor($sppr->effectLst->glow);
1325 8
                $chartObject->setGlowProperties($axisGlowSize, $colorArray['value'], $colorArray['alpha'], $colorArray['type']);
1326
            }
1327
        }
1328
1329 48
        if (isset($sppr->effectLst->softEdge)) {
1330 2
            $softEdgeSize = self::getAttributeString($sppr->effectLst->softEdge, 'rad');
1331 2
            if (is_numeric($softEdgeSize)) {
1332 2
                $chartObject->setSoftEdges((float) ChartProperties::xmlToPoints($softEdgeSize));
1333
            }
1334
        }
1335
1336 48
        $type = '';
1337 48
        foreach (self::SHADOW_TYPES as $shadowType) {
1338 48
            if (isset($sppr->effectLst->$shadowType)) {
1339 6
                $type = $shadowType;
1340
1341 6
                break;
1342
            }
1343
        }
1344 48
        if ($type !== '') {
1345 6
            $blur = self::getAttributeString($sppr->effectLst->$type, 'blurRad');
1346 6
            $blur = is_numeric($blur) ? ChartProperties::xmlToPoints($blur) : null;
1347 6
            $dist = self::getAttributeString($sppr->effectLst->$type, 'dist');
1348 6
            $dist = is_numeric($dist) ? ChartProperties::xmlToPoints($dist) : null;
1349 6
            $direction = self::getAttributeString($sppr->effectLst->$type, 'dir');
1350 6
            $direction = is_numeric($direction) ? ChartProperties::xmlToAngle($direction) : null;
1351 6
            $algn = self::getAttributeString($sppr->effectLst->$type, 'algn');
1352 6
            $rot = self::getAttributeString($sppr->effectLst->$type, 'rotWithShape');
1353 6
            $size = [];
1354 6
            foreach (['sx', 'sy'] as $sizeType) {
1355 6
                $sizeValue = self::getAttributeString($sppr->effectLst->$type, $sizeType);
1356 6
                if (is_numeric($sizeValue)) {
1357 1
                    $size[$sizeType] = ChartProperties::xmlToTenthOfPercent((string) $sizeValue);
1358
                } else {
1359 6
                    $size[$sizeType] = null;
1360
                }
1361
            }
1362 6
            foreach (['kx', 'ky'] as $sizeType) {
1363 6
                $sizeValue = self::getAttributeString($sppr->effectLst->$type, $sizeType);
1364 6
                if (is_numeric($sizeValue)) {
1365 1
                    $size[$sizeType] = ChartProperties::xmlToAngle((string) $sizeValue);
1366
                } else {
1367 6
                    $size[$sizeType] = null;
1368
                }
1369
            }
1370 6
            $colorArray = $this->readColor($sppr->effectLst->$type);
1371 6
            $chartObject
1372 6
                ->setShadowProperty('effect', $type)
1373 6
                ->setShadowProperty('blur', $blur)
1374 6
                ->setShadowProperty('direction', $direction)
1375 6
                ->setShadowProperty('distance', $dist)
1376 6
                ->setShadowProperty('algn', $algn)
1377 6
                ->setShadowProperty('rotWithShape', $rot)
1378 6
                ->setShadowProperty('size', $size)
1379 6
                ->setShadowProperty('color', $colorArray);
1380
        }
1381
    }
1382
1383
    private const SHADOW_TYPES = [
1384
        'outerShdw',
1385
        'innerShdw',
1386
    ];
1387
1388 65
    private function readColor(SimpleXMLElement $colorXml): array
1389
    {
1390 65
        $result = [
1391 65
            'type' => null,
1392 65
            'value' => null,
1393 65
            'alpha' => null,
1394 65
            'brightness' => null,
1395 65
        ];
1396 65
        foreach (ChartColor::EXCEL_COLOR_TYPES as $type) {
1397 65
            if (isset($colorXml->$type)) {
1398 59
                $result['type'] = $type;
1399 59
                $result['value'] = self::getAttributeString($colorXml->$type, 'val');
1400 59
                if (isset($colorXml->$type->alpha)) {
1401 20
                    $alpha = self::getAttributeString($colorXml->$type->alpha, 'val');
1402 20
                    if (is_numeric($alpha)) {
1403 20
                        $result['alpha'] = ChartColor::alphaFromXml($alpha);
1404
                    }
1405
                }
1406 59
                if (isset($colorXml->$type->lumMod)) {
1407 14
                    $brightness = self::getAttributeString($colorXml->$type->lumMod, 'val');
1408 14
                    if (is_numeric($brightness)) {
1409 14
                        $result['brightness'] = ChartColor::alphaFromXml($brightness);
1410
                    }
1411
                }
1412
1413 59
                break;
1414
            }
1415
        }
1416
1417 65
        return $result;
1418
    }
1419
1420 65
    private function readLineStyle(SimpleXMLElement $chartDetail, ?ChartProperties $chartObject): void
1421
    {
1422 65
        if (!isset($chartObject, $chartDetail->spPr)) {
1423 35
            return;
1424
        }
1425 65
        $sppr = $chartDetail->spPr->children($this->aNamespace);
1426
1427 65
        if (!isset($sppr->ln)) {
1428 7
            return;
1429
        }
1430 65
        $lineWidth = null;
1431 65
        $lineWidthTemp = self::getAttributeString($sppr->ln, 'w');
1432 65
        if (is_numeric($lineWidthTemp)) {
1433 46
            $lineWidth = ChartProperties::xmlToPoints($lineWidthTemp);
1434
        }
1435
        /** @var string $compoundType */
1436 65
        $compoundType = self::getAttributeString($sppr->ln, 'cmpd');
1437
        /** @var string $dashType */
1438 65
        $dashType = self::getAttributeString($sppr->ln->prstDash, 'val');
1439
        /** @var string $capType */
1440 65
        $capType = self::getAttributeString($sppr->ln, 'cap');
1441 65
        if (isset($sppr->ln->miter)) {
1442 12
            $joinType = ChartProperties::LINE_STYLE_JOIN_MITER;
1443 65
        } elseif (isset($sppr->ln->bevel)) {
1444 5
            $joinType = ChartProperties::LINE_STYLE_JOIN_BEVEL;
1445
        } else {
1446 65
            $joinType = '';
1447
        }
1448 65
        $headArrowSize = 0;
1449 65
        $endArrowSize = 0;
1450 65
        $headArrowType = self::getAttributeString($sppr->ln->headEnd, 'type');
1451 65
        $headArrowWidth = self::getAttributeString($sppr->ln->headEnd, 'w');
1452 65
        $headArrowLength = self::getAttributeString($sppr->ln->headEnd, 'len');
1453 65
        $endArrowType = self::getAttributeString($sppr->ln->tailEnd, 'type');
1454 65
        $endArrowWidth = self::getAttributeString($sppr->ln->tailEnd, 'w');
1455 65
        $endArrowLength = self::getAttributeString($sppr->ln->tailEnd, 'len');
1456 65
        $chartObject->setLineStyleProperties(
1457 65
            $lineWidth,
1458 65
            $compoundType,
1459 65
            $dashType,
1460 65
            $capType,
1461 65
            $joinType,
1462 65
            $headArrowType,
1463 65
            $headArrowSize,
1464 65
            $endArrowType,
1465 65
            $endArrowSize,
1466 65
            $headArrowWidth,
1467 65
            $headArrowLength,
1468 65
            $endArrowWidth,
1469 65
            $endArrowLength
1470 65
        );
1471 65
        $colorArray = $this->readColor($sppr->ln->solidFill);
1472 65
        $chartObject->getLineColor()->setColorPropertiesArray($colorArray);
1473
    }
1474
1475 63
    private function setAxisProperties(SimpleXMLElement $chartDetail, ?Axis $whichAxis): void
1476
    {
1477 63
        if (!isset($whichAxis)) {
1478
            return;
1479
        }
1480 63
        if (isset($chartDetail->delete)) {
1481 60
            $whichAxis->setAxisOption('hidden', (string) self::getAttributeString($chartDetail->delete, 'val'));
1482
        }
1483 63
        if (isset($chartDetail->numFmt)) {
1484 61
            $whichAxis->setAxisNumberProperties(
1485 61
                (string) self::getAttributeString($chartDetail->numFmt, 'formatCode'),
1486 61
                null,
1487 61
                (int) self::getAttributeInteger($chartDetail->numFmt, 'sourceLinked')
1488 61
            );
1489
        }
1490 63
        if (isset($chartDetail->crossBetween)) {
1491 46
            $whichAxis->setCrossBetween((string) self::getAttributeString($chartDetail->crossBetween, 'val'));
1492
        }
1493 63
        if (isset($chartDetail->dispUnits, $chartDetail->dispUnits->builtInUnit)) {
1494 3
            $whichAxis->setAxisOption('dispUnitsBuiltIn', (string) self::getAttributeString($chartDetail->dispUnits->builtInUnit, 'val'));
1495 3
            if (isset($chartDetail->dispUnits->dispUnitsLbl)) {
1496 3
                $whichAxis->setDispUnitsTitle(new Title());
1497
                // TODO parse title elements
1498
            }
1499
        }
1500 63
        if (isset($chartDetail->majorTickMark)) {
1501 63
            $whichAxis->setAxisOption('major_tick_mark', (string) self::getAttributeString($chartDetail->majorTickMark, 'val'));
1502
        }
1503 63
        if (isset($chartDetail->minorTickMark)) {
1504 62
            $whichAxis->setAxisOption('minor_tick_mark', (string) self::getAttributeString($chartDetail->minorTickMark, 'val'));
1505
        }
1506 63
        if (isset($chartDetail->tickLblPos)) {
1507 61
            $whichAxis->setAxisOption('axis_labels', (string) self::getAttributeString($chartDetail->tickLblPos, 'val'));
1508
        }
1509 63
        if (isset($chartDetail->crosses)) {
1510 60
            $whichAxis->setAxisOption('horizontal_crosses', (string) self::getAttributeString($chartDetail->crosses, 'val'));
1511
        }
1512 63
        if (isset($chartDetail->crossesAt)) {
1513
            $whichAxis->setAxisOption('horizontal_crosses_value', (string) self::getAttributeString($chartDetail->crossesAt, 'val'));
1514
        }
1515 63
        if (isset($chartDetail->scaling->logBase)) {
1516 1
            $whichAxis->setAxisOption('logBase', (string) self::getAttributeString($chartDetail->scaling->logBase, 'val'));
1517
        }
1518 63
        if (isset($chartDetail->scaling->orientation)) {
1519 63
            $whichAxis->setAxisOption('orientation', (string) self::getAttributeString($chartDetail->scaling->orientation, 'val'));
1520
        }
1521 63
        if (isset($chartDetail->scaling->max)) {
1522 8
            $whichAxis->setAxisOption('maximum', (string) self::getAttributeString($chartDetail->scaling->max, 'val'));
1523
        }
1524 63
        if (isset($chartDetail->scaling->min)) {
1525 8
            $whichAxis->setAxisOption('minimum', (string) self::getAttributeString($chartDetail->scaling->min, 'val'));
1526
        }
1527 63
        if (isset($chartDetail->scaling->min)) {
1528 8
            $whichAxis->setAxisOption('minimum', (string) self::getAttributeString($chartDetail->scaling->min, 'val'));
1529
        }
1530 63
        if (isset($chartDetail->majorUnit)) {
1531 4
            $whichAxis->setAxisOption('major_unit', (string) self::getAttributeString($chartDetail->majorUnit, 'val'));
1532
        }
1533 63
        if (isset($chartDetail->minorUnit)) {
1534 1
            $whichAxis->setAxisOption('minor_unit', (string) self::getAttributeString($chartDetail->minorUnit, 'val'));
1535
        }
1536 63
        if (isset($chartDetail->baseTimeUnit)) {
1537 3
            $whichAxis->setAxisOption('baseTimeUnit', (string) self::getAttributeString($chartDetail->baseTimeUnit, 'val'));
1538
        }
1539 63
        if (isset($chartDetail->majorTimeUnit)) {
1540 3
            $whichAxis->setAxisOption('majorTimeUnit', (string) self::getAttributeString($chartDetail->majorTimeUnit, 'val'));
1541
        }
1542 63
        if (isset($chartDetail->minorTimeUnit)) {
1543 3
            $whichAxis->setAxisOption('minorTimeUnit', (string) self::getAttributeString($chartDetail->minorTimeUnit, 'val'));
1544
        }
1545 63
        if (isset($chartDetail->txPr)) {
1546 14
            $children = $chartDetail->txPr->children($this->aNamespace);
1547 14
            $addAxisText = false;
1548 14
            $axisText = new AxisText();
1549 14
            if (isset($children->bodyPr)) {
1550 14
                $textRotation = self::getAttributeString($children->bodyPr, 'rot');
1551 14
                if (is_numeric($textRotation)) {
1552 9
                    $axisText->setRotation((int) ChartProperties::xmlToAngle($textRotation));
1553 9
                    $addAxisText = true;
1554
                }
1555
            }
1556 14
            if (isset($children->p->pPr->defRPr)) {
1557 14
                $font = $this->parseFont($children->p);
1558 14
                if ($font !== null) {
1559 14
                    $axisText->setFont($font);
1560 14
                    $addAxisText = true;
1561
                }
1562
            }
1563 14
            if (isset($children->p->pPr->defRPr->effectLst)) {
1564 4
                $this->readEffects($children->p->pPr->defRPr, $axisText, false);
1565 4
                $addAxisText = true;
1566
            }
1567 14
            if ($addAxisText) {
1568 14
                $whichAxis->setAxisText($axisText);
1569
            }
1570
        }
1571
    }
1572
}
1573