Chart::parseFont()   C
last analyzed

Complexity

Conditions 11
Paths 193

Size

Total Lines 43
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 11.0397

Importance

Changes 0
Metric Value
eloc 29
c 0
b 0
f 0
dl 0
loc 43
ccs 27
cts 29
cp 0.931
rs 6.5416
cc 11
nc 193
nop 1
crap 11.0397

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