Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Chart;
4
 
5
/**
6
 * Created by PhpStorm.
7
 * User: nhw2h8s
8
 * Date: 7/2/14
9
 * Time: 5:45 PM.
10
 */
11
abstract class Properties
12
{
13
    const AXIS_LABELS_LOW = 'low';
14
    const AXIS_LABELS_HIGH = 'high';
15
    const AXIS_LABELS_NEXT_TO = 'nextTo';
16
    const AXIS_LABELS_NONE = 'none';
17
 
18
    const TICK_MARK_NONE = 'none';
19
    const TICK_MARK_INSIDE = 'in';
20
    const TICK_MARK_OUTSIDE = 'out';
21
    const TICK_MARK_CROSS = 'cross';
22
 
23
    const HORIZONTAL_CROSSES_AUTOZERO = 'autoZero';
24
    const HORIZONTAL_CROSSES_MAXIMUM = 'max';
25
 
26
    const FORMAT_CODE_GENERAL = 'General';
27
    const FORMAT_CODE_NUMBER = '#,##0.00';
28
    const FORMAT_CODE_CURRENCY = '$#,##0.00';
29
    const FORMAT_CODE_ACCOUNTING = '_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)';
30
    const FORMAT_CODE_DATE = 'm/d/yyyy';
31
    const FORMAT_CODE_DATE_ISO8601 = 'yyyy-mm-dd';
32
    const FORMAT_CODE_TIME = '[$-F400]h:mm:ss AM/PM';
33
    const FORMAT_CODE_PERCENTAGE = '0.00%';
34
    const FORMAT_CODE_FRACTION = '# ?/?';
35
    const FORMAT_CODE_SCIENTIFIC = '0.00E+00';
36
    const FORMAT_CODE_TEXT = '@';
37
    const FORMAT_CODE_SPECIAL = '00000';
38
 
39
    const ORIENTATION_NORMAL = 'minMax';
40
    const ORIENTATION_REVERSED = 'maxMin';
41
 
42
    const LINE_STYLE_COMPOUND_SIMPLE = 'sng';
43
    const LINE_STYLE_COMPOUND_DOUBLE = 'dbl';
44
    const LINE_STYLE_COMPOUND_THICKTHIN = 'thickThin';
45
    const LINE_STYLE_COMPOUND_THINTHICK = 'thinThick';
46
    const LINE_STYLE_COMPOUND_TRIPLE = 'tri';
47
    const LINE_STYLE_DASH_SOLID = 'solid';
48
    const LINE_STYLE_DASH_ROUND_DOT = 'sysDot';
49
    const LINE_STYLE_DASH_SQUARE_DOT = 'sysDash';
50
    const LINE_STYPE_DASH_DASH = 'dash';
51
    const LINE_STYLE_DASH_DASH_DOT = 'dashDot';
52
    const LINE_STYLE_DASH_LONG_DASH = 'lgDash';
53
    const LINE_STYLE_DASH_LONG_DASH_DOT = 'lgDashDot';
54
    const LINE_STYLE_DASH_LONG_DASH_DOT_DOT = 'lgDashDotDot';
55
    const LINE_STYLE_CAP_SQUARE = 'sq';
56
    const LINE_STYLE_CAP_ROUND = 'rnd';
57
    const LINE_STYLE_CAP_FLAT = 'flat';
58
    const LINE_STYLE_JOIN_ROUND = 'round';
59
    const LINE_STYLE_JOIN_MITER = 'miter';
60
    const LINE_STYLE_JOIN_BEVEL = 'bevel';
61
    const LINE_STYLE_ARROW_TYPE_NOARROW = null;
62
    const LINE_STYLE_ARROW_TYPE_ARROW = 'triangle';
63
    const LINE_STYLE_ARROW_TYPE_OPEN = 'arrow';
64
    const LINE_STYLE_ARROW_TYPE_STEALTH = 'stealth';
65
    const LINE_STYLE_ARROW_TYPE_DIAMOND = 'diamond';
66
    const LINE_STYLE_ARROW_TYPE_OVAL = 'oval';
67
    const LINE_STYLE_ARROW_SIZE_1 = 1;
68
    const LINE_STYLE_ARROW_SIZE_2 = 2;
69
    const LINE_STYLE_ARROW_SIZE_3 = 3;
70
    const LINE_STYLE_ARROW_SIZE_4 = 4;
71
    const LINE_STYLE_ARROW_SIZE_5 = 5;
72
    const LINE_STYLE_ARROW_SIZE_6 = 6;
73
    const LINE_STYLE_ARROW_SIZE_7 = 7;
74
    const LINE_STYLE_ARROW_SIZE_8 = 8;
75
    const LINE_STYLE_ARROW_SIZE_9 = 9;
76
 
77
    const SHADOW_PRESETS_NOSHADOW = null;
78
    const SHADOW_PRESETS_OUTER_BOTTTOM_RIGHT = 1;
79
    const SHADOW_PRESETS_OUTER_BOTTOM = 2;
80
    const SHADOW_PRESETS_OUTER_BOTTOM_LEFT = 3;
81
    const SHADOW_PRESETS_OUTER_RIGHT = 4;
82
    const SHADOW_PRESETS_OUTER_CENTER = 5;
83
    const SHADOW_PRESETS_OUTER_LEFT = 6;
84
    const SHADOW_PRESETS_OUTER_TOP_RIGHT = 7;
85
    const SHADOW_PRESETS_OUTER_TOP = 8;
86
    const SHADOW_PRESETS_OUTER_TOP_LEFT = 9;
87
    const SHADOW_PRESETS_INNER_BOTTTOM_RIGHT = 10;
88
    const SHADOW_PRESETS_INNER_BOTTOM = 11;
89
    const SHADOW_PRESETS_INNER_BOTTOM_LEFT = 12;
90
    const SHADOW_PRESETS_INNER_RIGHT = 13;
91
    const SHADOW_PRESETS_INNER_CENTER = 14;
92
    const SHADOW_PRESETS_INNER_LEFT = 15;
93
    const SHADOW_PRESETS_INNER_TOP_RIGHT = 16;
94
    const SHADOW_PRESETS_INNER_TOP = 17;
95
    const SHADOW_PRESETS_INNER_TOP_LEFT = 18;
96
    const SHADOW_PRESETS_PERSPECTIVE_BELOW = 19;
97
    const SHADOW_PRESETS_PERSPECTIVE_UPPER_RIGHT = 20;
98
    const SHADOW_PRESETS_PERSPECTIVE_UPPER_LEFT = 21;
99
    const SHADOW_PRESETS_PERSPECTIVE_LOWER_RIGHT = 22;
100
    const SHADOW_PRESETS_PERSPECTIVE_LOWER_LEFT = 23;
101
 
102
    const POINTS_WIDTH_MULTIPLIER = 12700;
103
    const ANGLE_MULTIPLIER = 60000; // direction and size-kx size-ky
104
    const PERCENTAGE_MULTIPLIER = 100000; // size sx and sy
105
 
106
    protected bool $objectState = false; // used only for minor gridlines
107
 
108
    protected ?float $glowSize = null;
109
 
110
    protected ChartColor $glowColor;
111
 
112
    protected array $softEdges = [
113
        'size' => null,
114
    ];
115
 
116
    protected array $shadowProperties = self::PRESETS_OPTIONS[0];
117
 
118
    protected ChartColor $shadowColor;
119
 
120
    public function __construct()
121
    {
122
        $this->lineColor = new ChartColor();
123
        $this->glowColor = new ChartColor();
124
        $this->shadowColor = new ChartColor();
125
        $this->shadowColor->setType(ChartColor::EXCEL_COLOR_TYPE_STANDARD);
126
        $this->shadowColor->setValue('black');
127
        $this->shadowColor->setAlpha(40);
128
    }
129
 
130
    /**
131
     * Get Object State.
132
     */
133
    public function getObjectState(): bool
134
    {
135
        return $this->objectState;
136
    }
137
 
138
    /**
139
     * Change Object State to True.
140
     *
141
     * @return $this
142
     */
143
    public function activateObject()
144
    {
145
        $this->objectState = true;
146
 
147
        return $this;
148
    }
149
 
150
    public static function pointsToXml(float $width): string
151
    {
152
        return (string) (int) ($width * self::POINTS_WIDTH_MULTIPLIER);
153
    }
154
 
155
    public static function xmlToPoints(string $width): float
156
    {
157
        return ((float) $width) / self::POINTS_WIDTH_MULTIPLIER;
158
    }
159
 
160
    public static function angleToXml(float $angle): string
161
    {
162
        return (string) (int) ($angle * self::ANGLE_MULTIPLIER);
163
    }
164
 
165
    public static function xmlToAngle(string $angle): float
166
    {
167
        return ((float) $angle) / self::ANGLE_MULTIPLIER;
168
    }
169
 
170
    public static function tenthOfPercentToXml(float $value): string
171
    {
172
        return (string) (int) ($value * self::PERCENTAGE_MULTIPLIER);
173
    }
174
 
175
    public static function xmlToTenthOfPercent(string $value): float
176
    {
177
        return ((float) $value) / self::PERCENTAGE_MULTIPLIER;
178
    }
179
 
180
    protected function setColorProperties(?string $color, null|float|int|string $alpha, ?string $colorType): array
181
    {
182
        return [
183
            'type' => $colorType,
184
            'value' => $color,
185
            'alpha' => ($alpha === null) ? null : (int) $alpha,
186
        ];
187
    }
188
 
189
    protected const PRESETS_OPTIONS = [
190
        //NONE
191
 
192
            'presets' => self::SHADOW_PRESETS_NOSHADOW,
193
            'effect' => null,
194
            //'color' => [
195
            //    'type' => ChartColor::EXCEL_COLOR_TYPE_STANDARD,
196
            //    'value' => 'black',
197
            //    'alpha' => 40,
198
            //],
199
            'size' => [
200
                'sx' => null,
201
                'sy' => null,
202
                'kx' => null,
203
                'ky' => null,
204
            ],
205
            'blur' => null,
206
            'direction' => null,
207
            'distance' => null,
208
            'algn' => null,
209
            'rotWithShape' => null,
210
        ],
211
        //OUTER
212
        1 => [
213
            'effect' => 'outerShdw',
214
            'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
215
            'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
216
            'direction' => 2700000 / self::ANGLE_MULTIPLIER,
217
            'algn' => 'tl',
218
            'rotWithShape' => '0',
219
        ],
220
        2 => [
221
            'effect' => 'outerShdw',
222
            'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
223
            'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
224
            'direction' => 5400000 / self::ANGLE_MULTIPLIER,
225
            'algn' => 't',
226
            'rotWithShape' => '0',
227
        ],
228
        3 => [
229
            'effect' => 'outerShdw',
230
            'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
231
            'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
232
            'direction' => 8100000 / self::ANGLE_MULTIPLIER,
233
            'algn' => 'tr',
234
            'rotWithShape' => '0',
235
        ],
236
        4 => [
237
            'effect' => 'outerShdw',
238
            'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
239
            'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
240
            'algn' => 'l',
241
            'rotWithShape' => '0',
242
        ],
243
        5 => [
244
            'effect' => 'outerShdw',
245
            'size' => [
246
                'sx' => 102000 / self::PERCENTAGE_MULTIPLIER,
247
                'sy' => 102000 / self::PERCENTAGE_MULTIPLIER,
248
            ],
249
            'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
250
            'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
251
            'algn' => 'ctr',
252
            'rotWithShape' => '0',
253
        ],
254
        6 => [
255
            'effect' => 'outerShdw',
256
            'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
257
            'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
258
            'direction' => 10800000 / self::ANGLE_MULTIPLIER,
259
            'algn' => 'r',
260
            'rotWithShape' => '0',
261
        ],
262
        7 => [
263
            'effect' => 'outerShdw',
264
            'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
265
            'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
266
            'direction' => 18900000 / self::ANGLE_MULTIPLIER,
267
            'algn' => 'bl',
268
            'rotWithShape' => '0',
269
        ],
270
        8 => [
271
            'effect' => 'outerShdw',
272
            'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
273
            'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
274
            'direction' => 16200000 / self::ANGLE_MULTIPLIER,
275
            'rotWithShape' => '0',
276
        ],
277
        9 => [
278
            'effect' => 'outerShdw',
279
            'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
280
            'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
281
            'direction' => 13500000 / self::ANGLE_MULTIPLIER,
282
            'algn' => 'br',
283
            'rotWithShape' => '0',
284
        ],
285
        //INNER
286
        10 => [
287
            'effect' => 'innerShdw',
288
            'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
289
            'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
290
            'direction' => 2700000 / self::ANGLE_MULTIPLIER,
291
        ],
292
        11 => [
293
            'effect' => 'innerShdw',
294
            'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
295
            'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
296
            'direction' => 5400000 / self::ANGLE_MULTIPLIER,
297
        ],
298
        12 => [
299
            'effect' => 'innerShdw',
300
            'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
301
            'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
302
            'direction' => 8100000 / self::ANGLE_MULTIPLIER,
303
        ],
304
        13 => [
305
            'effect' => 'innerShdw',
306
            'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
307
            'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
308
        ],
309
        14 => [
310
            'effect' => 'innerShdw',
311
            'blur' => 114300 / self::POINTS_WIDTH_MULTIPLIER,
312
        ],
313
        15 => [
314
            'effect' => 'innerShdw',
315
            'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
316
            'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
317
            'direction' => 10800000 / self::ANGLE_MULTIPLIER,
318
        ],
319
        16 => [
320
            'effect' => 'innerShdw',
321
            'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
322
            'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
323
            'direction' => 18900000 / self::ANGLE_MULTIPLIER,
324
        ],
325
        17 => [
326
            'effect' => 'innerShdw',
327
            'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
328
            'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
329
            'direction' => 16200000 / self::ANGLE_MULTIPLIER,
330
        ],
331
        18 => [
332
            'effect' => 'innerShdw',
333
            'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
334
            'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
335
            'direction' => 13500000 / self::ANGLE_MULTIPLIER,
336
        ],
337
        //perspective
338
        19 => [
339
            'effect' => 'outerShdw',
340
            'blur' => 152400 / self::POINTS_WIDTH_MULTIPLIER,
341
            'distance' => 317500 / self::POINTS_WIDTH_MULTIPLIER,
342
            'size' => [
343
                'sx' => 90000 / self::PERCENTAGE_MULTIPLIER,
344
                'sy' => -19000 / self::PERCENTAGE_MULTIPLIER,
345
            ],
346
            'direction' => 5400000 / self::ANGLE_MULTIPLIER,
347
            'rotWithShape' => '0',
348
        ],
349
        20 => [
350
            'effect' => 'outerShdw',
351
            'blur' => 76200 / self::POINTS_WIDTH_MULTIPLIER,
352
            'direction' => 18900000 / self::ANGLE_MULTIPLIER,
353
            'size' => [
354
                'sy' => 23000 / self::PERCENTAGE_MULTIPLIER,
355
                'kx' => -1200000 / self::ANGLE_MULTIPLIER,
356
            ],
357
            'algn' => 'bl',
358
            'rotWithShape' => '0',
359
        ],
360
        21 => [
361
            'effect' => 'outerShdw',
362
            'blur' => 76200 / self::POINTS_WIDTH_MULTIPLIER,
363
            'direction' => 13500000 / self::ANGLE_MULTIPLIER,
364
            'size' => [
365
                'sy' => 23000 / self::PERCENTAGE_MULTIPLIER,
366
                'kx' => 1200000 / self::ANGLE_MULTIPLIER,
367
            ],
368
            'algn' => 'br',
369
            'rotWithShape' => '0',
370
        ],
371
        22 => [
372
            'effect' => 'outerShdw',
373
            'blur' => 76200 / self::POINTS_WIDTH_MULTIPLIER,
374
            'distance' => 12700 / self::POINTS_WIDTH_MULTIPLIER,
375
            'direction' => 2700000 / self::ANGLE_MULTIPLIER,
376
            'size' => [
377
                'sy' => -23000 / self::PERCENTAGE_MULTIPLIER,
378
                'kx' => -800400 / self::ANGLE_MULTIPLIER,
379
            ],
380
            'algn' => 'bl',
381
            'rotWithShape' => '0',
382
        ],
383
        23 => [
384
            'effect' => 'outerShdw',
385
            'blur' => 76200 / self::POINTS_WIDTH_MULTIPLIER,
386
            'distance' => 12700 / self::POINTS_WIDTH_MULTIPLIER,
387
            'direction' => 8100000 / self::ANGLE_MULTIPLIER,
388
            'size' => [
389
                'sy' => -23000 / self::PERCENTAGE_MULTIPLIER,
390
                'kx' => 800400 / self::ANGLE_MULTIPLIER,
391
            ],
392
            'algn' => 'br',
393
            'rotWithShape' => '0',
394
        ],
395
    ];
396
 
397
    protected function getShadowPresetsMap(int $presetsOption): array
398
    {
399
        return self::PRESETS_OPTIONS[$presetsOption] ?? self::PRESETS_OPTIONS[0];
400
    }
401
 
402
    /**
403
     * Get value of array element.
404
     */
405
    protected function getArrayElementsValue(array $properties, array|int|string $elements): mixed
406
    {
407
        $reference = &$properties;
408
        if (!is_array($elements)) {
409
            return $reference[$elements];
410
        }
411
 
412
        foreach ($elements as $keys) {
413
            $reference = &$reference[$keys];
414
        }
415
 
416
        return $reference;
417
    }
418
 
419
    /**
420
     * Set Glow Properties.
421
     */
422
    public function setGlowProperties(float $size, ?string $colorValue = null, ?int $colorAlpha = null, ?string $colorType = null): void
423
    {
424
        $this
425
            ->activateObject()
426
            ->setGlowSize($size);
427
        $this->glowColor->setColorPropertiesArray(
428
            [
429
                'value' => $colorValue,
430
                'type' => $colorType,
431
                'alpha' => $colorAlpha,
432
            ]
433
        );
434
    }
435
 
436
    /**
437
     * Get Glow Property.
438
     */
439
    public function getGlowProperty(array|string $property): null|array|float|int|string
440
    {
441
        $retVal = null;
442
        if ($property === 'size') {
443
            $retVal = $this->glowSize;
444
        } elseif ($property === 'color') {
445
            $retVal = [
446
                'value' => $this->glowColor->getColorProperty('value'),
447
                'type' => $this->glowColor->getColorProperty('type'),
448
                'alpha' => $this->glowColor->getColorProperty('alpha'),
449
            ];
450
        } elseif (is_array($property) && count($property) >= 2 && $property[0] === 'color') {
451
            $retVal = $this->glowColor->getColorProperty($property[1]);
452
        }
453
 
454
        return $retVal;
455
    }
456
 
457
    /**
458
     * Get Glow Color Property.
459
     */
460
    public function getGlowColor(string $propertyName): null|int|string
461
    {
462
        return $this->glowColor->getColorProperty($propertyName);
463
    }
464
 
465
    public function getGlowColorObject(): ChartColor
466
    {
467
        return $this->glowColor;
468
    }
469
 
470
    /**
471
     * Get Glow Size.
472
     */
473
    public function getGlowSize(): ?float
474
    {
475
        return $this->glowSize;
476
    }
477
 
478
    /**
479
     * Set Glow Size.
480
     *
481
     * @return $this
482
     */
483
    protected function setGlowSize(?float $size)
484
    {
485
        $this->glowSize = $size;
486
 
487
        return $this;
488
    }
489
 
490
    /**
491
     * Set Soft Edges Size.
492
     */
493
    public function setSoftEdges(?float $size): void
494
    {
495
        if ($size !== null) {
496
            $this->activateObject();
497
            $this->softEdges['size'] = $size;
498
        }
499
    }
500
 
501
    /**
502
     * Get Soft Edges Size.
503
     */
504
    public function getSoftEdgesSize(): ?float
505
    {
506
        return $this->softEdges['size'];
507
    }
508
 
509
    public function setShadowProperty(string $propertyName, mixed $value): self
510
    {
511
        $this->activateObject();
512
        if ($propertyName === 'color' && is_array($value)) {
513
            $this->shadowColor->setColorPropertiesArray($value);
514
        } else {
515
            $this->shadowProperties[$propertyName] = $value;
516
        }
517
 
518
        return $this;
519
    }
520
 
521
    /**
522
     * Set Shadow Properties.
523
     */
524
    public function setShadowProperties(int $presets, ?string $colorValue = null, ?string $colorType = null, null|float|int|string $colorAlpha = null, ?float $blur = null, ?int $angle = null, ?float $distance = null): void
525
    {
526
        $this->activateObject()->setShadowPresetsProperties((int) $presets);
527
        if ($presets === 0) {
528
            $this->shadowColor->setType(ChartColor::EXCEL_COLOR_TYPE_STANDARD);
529
            $this->shadowColor->setValue('black');
530
            $this->shadowColor->setAlpha(40);
531
        }
532
        if ($colorValue !== null) {
533
            $this->shadowColor->setValue($colorValue);
534
        }
535
        if ($colorType !== null) {
536
            $this->shadowColor->setType($colorType);
537
        }
538
        if (is_numeric($colorAlpha)) {
539
            $this->shadowColor->setAlpha((int) $colorAlpha);
540
        }
541
        $this
542
            ->setShadowBlur($blur)
543
            ->setShadowAngle($angle)
544
            ->setShadowDistance($distance);
545
    }
546
 
547
    /**
548
     * Set Shadow Presets Properties.
549
     *
550
     * @return $this
551
     */
552
    protected function setShadowPresetsProperties(int $presets)
553
    {
554
        $this->shadowProperties['presets'] = $presets;
555
        $this->setShadowPropertiesMapValues($this->getShadowPresetsMap($presets));
556
 
557
        return $this;
558
    }
559
 
560
    protected const SHADOW_ARRAY_KEYS = ['size', 'color'];
561
 
562
    /**
563
     * Set Shadow Properties Values.
564
     *
565
     * @return $this
566
     */
567
    protected function setShadowPropertiesMapValues(array $propertiesMap, ?array &$reference = null)
568
    {
569
        $base_reference = $reference;
570
        foreach ($propertiesMap as $property_key => $property_val) {
571
            if (is_array($property_val)) {
572
                if (in_array($property_key, self::SHADOW_ARRAY_KEYS, true)) {
573
                    $reference = &$this->shadowProperties[$property_key];
574
                    $this->setShadowPropertiesMapValues($property_val, $reference);
575
                }
576
            } else {
577
                if ($base_reference === null) {
578
                    $this->shadowProperties[$property_key] = $property_val;
579
                } else {
580
                    $reference[$property_key] = $property_val;
581
                }
582
            }
583
        }
584
 
585
        return $this;
586
    }
587
 
588
    /**
589
     * Set Shadow Blur.
590
     *
591
     * @return $this
592
     */
593
    protected function setShadowBlur(?float $blur)
594
    {
595
        if ($blur !== null) {
596
            $this->shadowProperties['blur'] = $blur;
597
        }
598
 
599
        return $this;
600
    }
601
 
602
    /**
603
     * Set Shadow Angle.
604
     *
605
     * @return $this
606
     */
607
    protected function setShadowAngle(null|float|int|string $angle)
608
    {
609
        if (is_numeric($angle)) {
610
            $this->shadowProperties['direction'] = $angle;
611
        }
612
 
613
        return $this;
614
    }
615
 
616
    /**
617
     * Set Shadow Distance.
618
     *
619
     * @return $this
620
     */
621
    protected function setShadowDistance(?float $distance)
622
    {
623
        if ($distance !== null) {
624
            $this->shadowProperties['distance'] = $distance;
625
        }
626
 
627
        return $this;
628
    }
629
 
630
    public function getShadowColorObject(): ChartColor
631
    {
632
        return $this->shadowColor;
633
    }
634
 
635
    /**
636
     * Get Shadow Property.
637
     *
638
     * @param string|string[] $elements
639
     */
640
    public function getShadowProperty($elements): array|string|null
641
    {
642
        if ($elements === 'color') {
643
            return [
644
                'value' => $this->shadowColor->getValue(),
645
                'type' => $this->shadowColor->getType(),
646
                'alpha' => $this->shadowColor->getAlpha(),
647
            ];
648
        }
649
        $retVal = $this->getArrayElementsValue($this->shadowProperties, $elements);
650
        if (is_scalar($retVal)) {
651
            $retVal = (string) $retVal;
652
        } elseif ($retVal !== null && !is_array($retVal)) {
653
            // @codeCoverageIgnoreStart
654
            throw new Exception('Unexpected value for shadowProperty');
655
            // @codeCoverageIgnoreEnd
656
        }
657
 
658
        return $retVal;
659
    }
660
 
661
    public function getShadowArray(): array
662
    {
663
        $array = $this->shadowProperties;
664
        if ($this->getShadowColorObject()->isUsable()) {
665
            $array['color'] = $this->getShadowProperty('color');
666
        }
667
 
668
        return $array;
669
    }
670
 
671
    protected ChartColor $lineColor;
672
 
673
    protected array $lineStyleProperties = [
674
        'width' => null, //'9525',
675
        'compound' => '', //self::LINE_STYLE_COMPOUND_SIMPLE,
676
        'dash' => '', //self::LINE_STYLE_DASH_SOLID,
677
        'cap' => '', //self::LINE_STYLE_CAP_FLAT,
678
        'join' => '', //self::LINE_STYLE_JOIN_BEVEL,
679
        'arrow' => [
680
            'head' => [
681
                'type' => '', //self::LINE_STYLE_ARROW_TYPE_NOARROW,
682
                'size' => '', //self::LINE_STYLE_ARROW_SIZE_5,
683
                'w' => '',
684
                'len' => '',
685
            ],
686
            'end' => [
687
                'type' => '', //self::LINE_STYLE_ARROW_TYPE_NOARROW,
688
                'size' => '', //self::LINE_STYLE_ARROW_SIZE_8,
689
                'w' => '',
690
                'len' => '',
691
            ],
692
        ],
693
    ];
694
 
695
    public function copyLineStyles(self $otherProperties): void
696
    {
697
        $this->lineStyleProperties = $otherProperties->lineStyleProperties;
698
        $this->lineColor = $otherProperties->lineColor;
699
        $this->glowSize = $otherProperties->glowSize;
700
        $this->glowColor = $otherProperties->glowColor;
701
        $this->softEdges = $otherProperties->softEdges;
702
        $this->shadowProperties = $otherProperties->shadowProperties;
703
    }
704
 
705
    public function getLineColor(): ChartColor
706
    {
707
        return $this->lineColor;
708
    }
709
 
710
    /**
711
     * Set Line Color Properties.
712
     */
713
    public function setLineColorProperties(?string $value, ?int $alpha = null, ?string $colorType = null): void
714
    {
715
        $this->activateObject();
716
        $this->lineColor->setColorPropertiesArray(
717
            $this->setColorProperties(
718
                $value,
719
                $alpha,
720
                $colorType
721
            )
722
        );
723
    }
724
 
725
    /**
726
     * Get Line Color Property.
727
     */
728
    public function getLineColorProperty(string $propertyName): null|int|string
729
    {
730
        return $this->lineColor->getColorProperty($propertyName);
731
    }
732
 
733
    /**
734
     * Set Line Style Properties.
735
     */
736
    public function setLineStyleProperties(
737
        null|float|int|string $lineWidth = null,
738
        ?string $compoundType = '',
739
        ?string $dashType = '',
740
        ?string $capType = '',
741
        ?string $joinType = '',
742
        ?string $headArrowType = '',
743
        int $headArrowSize = 0,
744
        ?string $endArrowType = '',
745
        int $endArrowSize = 0,
746
        ?string $headArrowWidth = '',
747
        ?string $headArrowLength = '',
748
        ?string $endArrowWidth = '',
749
        ?string $endArrowLength = ''
750
    ): void {
751
        $this->activateObject();
752
        if (is_numeric($lineWidth)) {
753
            $this->lineStyleProperties['width'] = $lineWidth;
754
        }
755
        if ($compoundType !== '') {
756
            $this->lineStyleProperties['compound'] = $compoundType;
757
        }
758
        if ($dashType !== '') {
759
            $this->lineStyleProperties['dash'] = $dashType;
760
        }
761
        if ($capType !== '') {
762
            $this->lineStyleProperties['cap'] = $capType;
763
        }
764
        if ($joinType !== '') {
765
            $this->lineStyleProperties['join'] = $joinType;
766
        }
767
        if ($headArrowType !== '') {
768
            $this->lineStyleProperties['arrow']['head']['type'] = $headArrowType;
769
        }
770
        if (isset(self::ARROW_SIZES[$headArrowSize])) {
771
            $this->lineStyleProperties['arrow']['head']['size'] = $headArrowSize;
772
            $this->lineStyleProperties['arrow']['head']['w'] = self::ARROW_SIZES[$headArrowSize]['w'];
773
            $this->lineStyleProperties['arrow']['head']['len'] = self::ARROW_SIZES[$headArrowSize]['len'];
774
        }
775
        if ($endArrowType !== '') {
776
            $this->lineStyleProperties['arrow']['end']['type'] = $endArrowType;
777
        }
778
        if (isset(self::ARROW_SIZES[$endArrowSize])) {
779
            $this->lineStyleProperties['arrow']['end']['size'] = $endArrowSize;
780
            $this->lineStyleProperties['arrow']['end']['w'] = self::ARROW_SIZES[$endArrowSize]['w'];
781
            $this->lineStyleProperties['arrow']['end']['len'] = self::ARROW_SIZES[$endArrowSize]['len'];
782
        }
783
        if ($headArrowWidth !== '') {
784
            $this->lineStyleProperties['arrow']['head']['w'] = $headArrowWidth;
785
        }
786
        if ($headArrowLength !== '') {
787
            $this->lineStyleProperties['arrow']['head']['len'] = $headArrowLength;
788
        }
789
        if ($endArrowWidth !== '') {
790
            $this->lineStyleProperties['arrow']['end']['w'] = $endArrowWidth;
791
        }
792
        if ($endArrowLength !== '') {
793
            $this->lineStyleProperties['arrow']['end']['len'] = $endArrowLength;
794
        }
795
    }
796
 
797
    public function getLineStyleArray(): array
798
    {
799
        return $this->lineStyleProperties;
800
    }
801
 
802
    public function setLineStyleArray(array $lineStyleProperties = []): self
803
    {
804
        $this->activateObject();
805
        $this->lineStyleProperties['width'] = $lineStyleProperties['width'] ?? null;
806
        $this->lineStyleProperties['compound'] = $lineStyleProperties['compound'] ?? '';
807
        $this->lineStyleProperties['dash'] = $lineStyleProperties['dash'] ?? '';
808
        $this->lineStyleProperties['cap'] = $lineStyleProperties['cap'] ?? '';
809
        $this->lineStyleProperties['join'] = $lineStyleProperties['join'] ?? '';
810
        $this->lineStyleProperties['arrow']['head']['type'] = $lineStyleProperties['arrow']['head']['type'] ?? '';
811
        $this->lineStyleProperties['arrow']['head']['size'] = $lineStyleProperties['arrow']['head']['size'] ?? '';
812
        $this->lineStyleProperties['arrow']['head']['w'] = $lineStyleProperties['arrow']['head']['w'] ?? '';
813
        $this->lineStyleProperties['arrow']['head']['len'] = $lineStyleProperties['arrow']['head']['len'] ?? '';
814
        $this->lineStyleProperties['arrow']['end']['type'] = $lineStyleProperties['arrow']['end']['type'] ?? '';
815
        $this->lineStyleProperties['arrow']['end']['size'] = $lineStyleProperties['arrow']['end']['size'] ?? '';
816
        $this->lineStyleProperties['arrow']['end']['w'] = $lineStyleProperties['arrow']['end']['w'] ?? '';
817
        $this->lineStyleProperties['arrow']['end']['len'] = $lineStyleProperties['arrow']['end']['len'] ?? '';
818
 
819
        return $this;
820
    }
821
 
822
    public function setLineStyleProperty(string $propertyName, mixed $value): self
823
    {
824
        $this->activateObject();
825
        $this->lineStyleProperties[$propertyName] = $value;
826
 
827
        return $this;
828
    }
829
 
830
    /**
831
     * Get Line Style Property.
832
     */
833
    public function getLineStyleProperty(array|string $elements): ?string
834
    {
835
        $retVal = $this->getArrayElementsValue($this->lineStyleProperties, $elements);
836
        if (is_scalar($retVal)) {
837
            $retVal = (string) $retVal;
838
        } elseif ($retVal !== null) {
839
            // @codeCoverageIgnoreStart
840
            throw new Exception('Unexpected value for lineStyleProperty');
841
            // @codeCoverageIgnoreEnd
842
        }
843
 
844
        return $retVal;
845
    }
846
 
847
    protected const ARROW_SIZES = [
848
        1 => ['w' => 'sm', 'len' => 'sm'],
849
        2 => ['w' => 'sm', 'len' => 'med'],
850
        3 => ['w' => 'sm', 'len' => 'lg'],
851
        4 => ['w' => 'med', 'len' => 'sm'],
852
        5 => ['w' => 'med', 'len' => 'med'],
853
        6 => ['w' => 'med', 'len' => 'lg'],
854
        7 => ['w' => 'lg', 'len' => 'sm'],
855
        8 => ['w' => 'lg', 'len' => 'med'],
856
        9 => ['w' => 'lg', 'len' => 'lg'],
857
    ];
858
 
859
    /**
860
     * Get Line Style Arrow Size.
861
     */
862
    protected function getLineStyleArrowSize(int $arraySelector, string $arrayKaySelector): string
863
    {
864
        return self::ARROW_SIZES[$arraySelector][$arrayKaySelector] ?? '';
865
    }
866
 
867
    /**
868
     * Get Line Style Arrow Parameters.
869
     */
870
    public function getLineStyleArrowParameters(string $arrowSelector, string $propertySelector): string
871
    {
872
        return $this->getLineStyleArrowSize($this->lineStyleProperties['arrow'][$arrowSelector]['size'], $propertySelector);
873
    }
874
 
875
    /**
876
     * Get Line Style Arrow Width.
877
     */
878
    public function getLineStyleArrowWidth(string $arrow): ?string
879
    {
880
        return $this->getLineStyleProperty(['arrow', $arrow, 'w']);
881
    }
882
 
883
    /**
884
     * Get Line Style Arrow Excel Length.
885
     */
886
    public function getLineStyleArrowLength(string $arrow): ?string
887
    {
888
        return $this->getLineStyleProperty(['arrow', $arrow, 'len']);
889
    }
890
 
891
    /**
892
     * Implement PHP __clone to create a deep clone, not just a shallow copy.
893
     */
894
    public function __clone()
895
    {
896
        $this->lineColor = clone $this->lineColor;
897
        $this->glowColor = clone $this->glowColor;
898
        $this->shadowColor = clone $this->shadowColor;
899
    }
900
}