From 6fae406aca4e355af88758a5f0150d63ab45bbd0 Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Sun, 19 Jun 2022 19:11:40 -0700 Subject: [PATCH] New Class ChartColor and Refactoring (#2898) * New Class ChartColor and Refactoring Chart colors are written to Xml in a different manner than font colors, and there are several variations. It will simplify things to create a new class for them. This PR will make use of the new class in Property/Axis/Gridline glow, shadow, and line colors; in Axis fill color; and in Font underline color (used only in charts). It will be used elsewhere in future; in particular, DataSeriesValues, which I will tackle next, will use it for at least one existing and two new properties. This PR is a refactoring; no functionality is added. Some public functions are moved from Properties to ChartColor, but all of these have been introduced after the last release 1.23, so there isn't really any compatibility break. No tests needed to be revised as a result of the source changes. * Simplify Logic in Xlsx/Writer/Chart Minor change. --- src/PhpSpreadsheet/Chart/Axis.php | 30 +- src/PhpSpreadsheet/Chart/ChartColor.php | 133 ++++++++ src/PhpSpreadsheet/Chart/Properties.php | 284 +++++++++--------- src/PhpSpreadsheet/Reader/Xlsx/Chart.php | 24 +- src/PhpSpreadsheet/Style/Font.php | 62 ++-- src/PhpSpreadsheet/Writer/Xlsx/Chart.php | 97 +++--- .../Writer/Xlsx/StringTable.php | 21 +- 7 files changed, 388 insertions(+), 263 deletions(-) create mode 100644 src/PhpSpreadsheet/Chart/ChartColor.php diff --git a/src/PhpSpreadsheet/Chart/Axis.php b/src/PhpSpreadsheet/Chart/Axis.php index 09a4febc..69a25d92 100644 --- a/src/PhpSpreadsheet/Chart/Axis.php +++ b/src/PhpSpreadsheet/Chart/Axis.php @@ -10,6 +10,12 @@ namespace PhpOffice\PhpSpreadsheet\Chart; */ class Axis extends Properties { + public function __construct() + { + parent::__construct(); + $this->fillColor = new ChartColor(); + } + /** * Axis Number. * @@ -42,13 +48,9 @@ class Axis extends Properties /** * Fill Properties. * - * @var mixed[] + * @var ChartColor */ - private $fillProperties = [ - 'type' => self::EXCEL_COLOR_TYPE_ARGB, - 'value' => null, - 'alpha' => 0, - ]; + private $fillColor; private const NUMERIC_FORMAT = [ Properties::FORMAT_CODE_NUMBER, @@ -163,7 +165,7 @@ class Axis extends Properties */ public function setFillParameters($color, $alpha = null, $AlphaType = self::EXCEL_COLOR_TYPE_ARGB): void { - $this->fillProperties = $this->setColorProperties($color, $alpha, $AlphaType); + $this->fillColor->setColorProperties($color, $alpha, $AlphaType); } /** @@ -175,19 +177,29 @@ class Axis extends Properties */ public function getFillProperty($property) { - return (string) $this->fillProperties[$property]; + return (string) $this->fillColor->getColorProperty($property); + } + + public function getFillColorObject(): ChartColor + { + return $this->fillColor; } /** * Get Line Color Property. * + * @Deprecated 1.24.0 + * + * @See Properties::getLineColorProperty() + * Use the getLineColor property in the Properties class instead + * * @param string $propertyName * * @return null|int|string */ public function getLineProperty($propertyName) { - return $this->lineProperties['color'][$propertyName]; + return $this->getLineColorProperty($propertyName); } /** @var string */ diff --git a/src/PhpSpreadsheet/Chart/ChartColor.php b/src/PhpSpreadsheet/Chart/ChartColor.php new file mode 100644 index 00000000..05c1bb9a --- /dev/null +++ b/src/PhpSpreadsheet/Chart/ChartColor.php @@ -0,0 +1,133 @@ +value; + } + + public function setValue(string $value): self + { + $this->value = $value; + + return $this; + } + + public function getType(): string + { + return $this->type; + } + + public function setType(string $type): self + { + $this->type = $type; + + return $this; + } + + public function getAlpha(): ?int + { + return $this->alpha; + } + + public function setAlpha(?int $alpha): self + { + $this->alpha = $alpha; + + return $this; + } + + /** + * @param null|float|int|string $alpha + */ + public function setColorProperties(?string $color, $alpha, ?string $type): self + { + if ($color !== null) { + $this->setValue($color); + } + if ($type !== null) { + $this->setType($type); + } + if ($alpha === null) { + $this->setAlpha(null); + } elseif (is_numeric($alpha)) { + $this->setAlpha((int) $alpha); + } + + return $this; + } + + public function setColorPropertiesArray(array $color): self + { + if (array_key_exists('value', $color) && is_string($color['value'])) { + $this->setValue($color['value']); + } + if (array_key_exists('type', $color) && is_string($color['type'])) { + $this->setType($color['type']); + } + if (array_key_exists('alpha', $color)) { + if ($color['alpha'] === null) { + $this->setAlpha(null); + } elseif (is_numeric($color['alpha'])) { + $this->setAlpha((int) $color['alpha']); + } + } + + return $this; + } + + /** + * Get Color Property. + * + * @param string $propertyName + * + * @return null|int|string + */ + public function getColorProperty($propertyName) + { + $retVal = null; + if ($propertyName === 'value') { + $retVal = $this->value; + } elseif ($propertyName === 'type') { + $retVal = $this->type; + } elseif ($propertyName === 'alpha') { + $retVal = $this->alpha; + } + + return $retVal; + } + + public static function alphaToXml(int $alpha): string + { + return (string) (100 - $alpha) . '000'; + } + + /** + * @param float|int|string $alpha + */ + public static function alphaFromXml($alpha): int + { + return 100 - ((int) $alpha / 1000); + } +} diff --git a/src/PhpSpreadsheet/Chart/Properties.php b/src/PhpSpreadsheet/Chart/Properties.php index c6b2d15b..a64a826f 100644 --- a/src/PhpSpreadsheet/Chart/Properties.php +++ b/src/PhpSpreadsheet/Chart/Properties.php @@ -10,15 +10,12 @@ namespace PhpOffice\PhpSpreadsheet\Chart; */ abstract class Properties { - const - EXCEL_COLOR_TYPE_STANDARD = 'prstClr'; - const EXCEL_COLOR_TYPE_SCHEME = 'schemeClr'; - const EXCEL_COLOR_TYPE_ARGB = 'srgbClr'; - const EXCEL_COLOR_TYPES = [ - self::EXCEL_COLOR_TYPE_ARGB, - self::EXCEL_COLOR_TYPE_SCHEME, - self::EXCEL_COLOR_TYPE_STANDARD, - ]; + /** @deprecated 1.24 use constant from ChartColor instead */ + const EXCEL_COLOR_TYPE_STANDARD = ChartColor::EXCEL_COLOR_TYPE_STANDARD; + /** @deprecated 1.24 use constant from ChartColor instead */ + const EXCEL_COLOR_TYPE_SCHEME = ChartColor::EXCEL_COLOR_TYPE_SCHEME; + /** @deprecated 1.24 use constant from ChartColor instead */ + const EXCEL_COLOR_TYPE_ARGB = ChartColor::EXCEL_COLOR_TYPE_ARGB; const AXIS_LABELS_LOW = 'low'; @@ -123,15 +120,11 @@ abstract class Properties /** @var bool */ protected $objectState = false; // used only for minor gridlines - /** @var array */ - protected $glowProperties = [ - 'size' => null, - 'color' => [ - 'type' => self::EXCEL_COLOR_TYPE_STANDARD, - 'value' => 'black', - 'alpha' => 40, - ], - ]; + /** @var ?float */ + protected $glowSize; + + /** @var ChartColor */ + protected $glowColor; /** @var array */ protected $softEdges = [ @@ -141,6 +134,19 @@ abstract class Properties /** @var array */ protected $shadowProperties = self::PRESETS_OPTIONS[0]; + /** @var ChartColor */ + protected $shadowColor; + + public function __construct() + { + $this->lineColor = new ChartColor(); + $this->glowColor = new ChartColor(); + $this->shadowColor = new ChartColor(); + $this->shadowColor->setType(ChartColor::EXCEL_COLOR_TYPE_STANDARD); + $this->shadowColor->setValue('black'); + $this->shadowColor->setAlpha(40); + } + /** * Get Object State. * @@ -193,19 +199,6 @@ abstract class Properties return ((float) $value) / self::PERCENTAGE_MULTIPLIER; } - public static function alphaToXml(int $alpha): string - { - return (string) (100 - $alpha) . '000'; - } - - /** - * @param float|int|string $alpha - */ - public static function alphaFromXml($alpha): int - { - return 100 - ((int) $alpha / 1000); - } - /** * @param null|float|int|string $alpha */ @@ -223,11 +216,11 @@ abstract class Properties 0 => [ 'presets' => self::SHADOW_PRESETS_NOSHADOW, 'effect' => null, - 'color' => [ - 'type' => self::EXCEL_COLOR_TYPE_STANDARD, - 'value' => 'black', - 'alpha' => 40, - ], + //'color' => [ + // 'type' => ChartColor::EXCEL_COLOR_TYPE_STANDARD, + // 'value' => 'black', + // 'alpha' => 40, + //], 'size' => [ 'sx' => null, 'sy' => null, @@ -457,8 +450,14 @@ abstract class Properties { $this ->activateObject() - ->setGlowSize($size) - ->setGlowColor($colorValue, $colorAlpha, $colorType); + ->setGlowSize($size); + $this->glowColor->setColorPropertiesArray( + [ + 'value' => $colorValue, + 'type' => $colorType, + 'alpha' => $colorAlpha, + ] + ); } /** @@ -466,11 +465,24 @@ abstract class Properties * * @param array|string $property * - * @return null|string + * @return null|array|float|int|string */ public function getGlowProperty($property) { - return $this->getArrayElementsValue($this->glowProperties, $property); + $retVal = null; + if ($property === 'size') { + $retVal = $this->glowSize; + } elseif ($property === 'color') { + $retVal = [ + 'value' => $this->glowColor->getColorProperty('value'), + 'type' => $this->glowColor->getColorProperty('type'), + 'alpha' => $this->glowColor->getColorProperty('alpha'), + ]; + } elseif (is_array($property) && count($property) >= 2 && $property[0] === 'color') { + $retVal = $this->glowColor->getColorProperty($property[1]); + } + + return $retVal; } /** @@ -478,57 +490,38 @@ abstract class Properties * * @param string $propertyName * - * @return string + * @return null|int|string */ public function getGlowColor($propertyName) { - return $this->glowProperties['color'][$propertyName]; + return $this->glowColor->getColorProperty($propertyName); + } + + public function getGlowColorObject(): ChartColor + { + return $this->glowColor; } /** * Get Glow Size. * - * @return string + * @return ?float */ public function getGlowSize() { - return $this->glowProperties['size']; + return $this->glowSize; } /** * Set Glow Size. * - * @param float $size + * @param ?float $size * * @return $this */ protected function setGlowSize($size) { - $this->glowProperties['size'] = $size; - - return $this; - } - - /** - * Set Glow Color. - * - * @param ?string $color - * @param ?int $alpha - * @param ?string $colorType - * - * @return $this - */ - protected function setGlowColor($color, $alpha, $colorType) - { - if ($color !== null) { - $this->glowProperties['color']['value'] = (string) $color; - } - if ($alpha !== null) { - $this->glowProperties['color']['alpha'] = (int) $alpha; - } - if ($colorType !== null) { - $this->glowProperties['color']['type'] = (string) $colorType; - } + $this->glowSize = $size; return $this; } @@ -562,7 +555,11 @@ abstract class Properties public function setShadowProperty(string $propertyName, $value): self { $this->activateObject(); - $this->shadowProperties[$propertyName] = $value; + if ($propertyName === 'color' && is_array($value)) { + $this->shadowColor->setColorPropertiesArray($value); + } else { + $this->shadowProperties[$propertyName] = $value; + } return $this; } @@ -580,13 +577,22 @@ abstract class Properties */ public function setShadowProperties($presets, $colorValue = null, $colorType = null, $colorAlpha = null, $blur = null, $angle = null, $distance = null): void { - $this->activateObject() - ->setShadowPresetsProperties((int) $presets) - ->setShadowColor( - $colorValue ?? $this->shadowProperties['color']['value'], - $colorAlpha === null ? (int) $this->shadowProperties['color']['alpha'] : (int) $colorAlpha, - $colorType ?? $this->shadowProperties['color']['type'] - ) + $this->activateObject()->setShadowPresetsProperties((int) $presets); + if ($presets === 0) { + $this->shadowColor->setType(ChartColor::EXCEL_COLOR_TYPE_STANDARD); + $this->shadowColor->setValue('black'); + $this->shadowColor->setAlpha(40); + } + if ($colorValue !== null) { + $this->shadowColor->setValue($colorValue); + } + if ($colorType !== null) { + $this->shadowColor->setType($colorType); + } + if (is_numeric($colorAlpha)) { + $this->shadowColor->setAlpha((int) $colorAlpha); + } + $this ->setShadowBlur($blur) ->setShadowAngle($angle) ->setShadowDistance($distance); @@ -709,48 +715,62 @@ abstract class Properties return $this; } + public function getShadowColorObject(): ChartColor + { + return $this->shadowColor; + } + /** * Get Shadow Property. * * @param string|string[] $elements * - * @return string + * @return array|string */ public function getShadowProperty($elements) { + if ($elements === 'color') { + return [ + 'value' => $this->shadowColor->getValue(), + 'type' => $this->shadowColor->getType(), + 'alpha' => $this->shadowColor->getAlpha(), + ]; + } + return $this->getArrayElementsValue($this->shadowProperties, $elements); } + /** @var ChartColor */ + protected $lineColor; + /** @var array */ - protected $lineProperties = [ - 'color' => [ - 'type' => '', //self::EXCEL_COLOR_TYPE_STANDARD, - 'value' => '', //null, - 'alpha' => null, - ], - 'style' => [ - 'width' => null, //'9525', - 'compound' => '', //self::LINE_STYLE_COMPOUND_SIMPLE, - 'dash' => '', //self::LINE_STYLE_DASH_SOLID, - 'cap' => '', //self::LINE_STYLE_CAP_FLAT, - 'join' => '', //self::LINE_STYLE_JOIN_BEVEL, - 'arrow' => [ - 'head' => [ - 'type' => '', //self::LINE_STYLE_ARROW_TYPE_NOARROW, - 'size' => '', //self::LINE_STYLE_ARROW_SIZE_5, - 'w' => '', - 'len' => '', - ], - 'end' => [ - 'type' => '', //self::LINE_STYLE_ARROW_TYPE_NOARROW, - 'size' => '', //self::LINE_STYLE_ARROW_SIZE_8, - 'w' => '', - 'len' => '', - ], + protected $lineStyleProperties = [ + 'width' => null, //'9525', + 'compound' => '', //self::LINE_STYLE_COMPOUND_SIMPLE, + 'dash' => '', //self::LINE_STYLE_DASH_SOLID, + 'cap' => '', //self::LINE_STYLE_CAP_FLAT, + 'join' => '', //self::LINE_STYLE_JOIN_BEVEL, + 'arrow' => [ + 'head' => [ + 'type' => '', //self::LINE_STYLE_ARROW_TYPE_NOARROW, + 'size' => '', //self::LINE_STYLE_ARROW_SIZE_5, + 'w' => '', + 'len' => '', + ], + 'end' => [ + 'type' => '', //self::LINE_STYLE_ARROW_TYPE_NOARROW, + 'size' => '', //self::LINE_STYLE_ARROW_SIZE_8, + 'w' => '', + 'len' => '', ], ], ]; + public function getLineColor(): ChartColor + { + return $this->lineColor; + } + /** * Set Line Color Properties. * @@ -758,20 +778,16 @@ abstract class Properties * @param ?int $alpha * @param string $colorType */ - public function setLineColorProperties($value, $alpha = null, $colorType = self::EXCEL_COLOR_TYPE_STANDARD): void + public function setLineColorProperties($value, $alpha = null, $colorType = ChartColor::EXCEL_COLOR_TYPE_STANDARD): void { - $this->activateObject() - ->lineProperties['color'] = $this->setColorProperties( + $this->activateObject(); + $this->lineColor->setColorPropertiesArray( + $this->setColorProperties( $value, $alpha, $colorType - ); - } - - public function setColorPropertiesArray(array $color): void - { - $this->activateObject() - ->lineProperties['color'] = $color; + ) + ); } /** @@ -783,7 +799,7 @@ abstract class Properties */ public function getLineColorProperty($propertyName) { - return $this->lineProperties['color'][$propertyName]; + return $this->lineColor->getColorProperty($propertyName); } /** @@ -807,47 +823,47 @@ abstract class Properties { $this->activateObject(); if (is_numeric($lineWidth)) { - $this->lineProperties['style']['width'] = $lineWidth; + $this->lineStyleProperties['width'] = $lineWidth; } if ($compoundType !== '') { - $this->lineProperties['style']['compound'] = $compoundType; + $this->lineStyleProperties['compound'] = $compoundType; } if ($dashType !== '') { - $this->lineProperties['style']['dash'] = $dashType; + $this->lineStyleProperties['dash'] = $dashType; } if ($capType !== '') { - $this->lineProperties['style']['cap'] = $capType; + $this->lineStyleProperties['cap'] = $capType; } if ($joinType !== '') { - $this->lineProperties['style']['join'] = $joinType; + $this->lineStyleProperties['join'] = $joinType; } if ($headArrowType !== '') { - $this->lineProperties['style']['arrow']['head']['type'] = $headArrowType; + $this->lineStyleProperties['arrow']['head']['type'] = $headArrowType; } if (array_key_exists($headArrowSize, self::ARROW_SIZES)) { - $this->lineProperties['style']['arrow']['head']['size'] = $headArrowSize; - $this->lineProperties['style']['arrow']['head']['w'] = self::ARROW_SIZES[$headArrowSize]['w']; - $this->lineProperties['style']['arrow']['head']['len'] = self::ARROW_SIZES[$headArrowSize]['len']; + $this->lineStyleProperties['arrow']['head']['size'] = $headArrowSize; + $this->lineStyleProperties['arrow']['head']['w'] = self::ARROW_SIZES[$headArrowSize]['w']; + $this->lineStyleProperties['arrow']['head']['len'] = self::ARROW_SIZES[$headArrowSize]['len']; } if ($endArrowType !== '') { - $this->lineProperties['style']['arrow']['end']['type'] = $endArrowType; + $this->lineStyleProperties['arrow']['end']['type'] = $endArrowType; } if (array_key_exists($endArrowSize, self::ARROW_SIZES)) { - $this->lineProperties['style']['arrow']['end']['size'] = $endArrowSize; - $this->lineProperties['style']['arrow']['end']['w'] = self::ARROW_SIZES[$endArrowSize]['w']; - $this->lineProperties['style']['arrow']['end']['len'] = self::ARROW_SIZES[$endArrowSize]['len']; + $this->lineStyleProperties['arrow']['end']['size'] = $endArrowSize; + $this->lineStyleProperties['arrow']['end']['w'] = self::ARROW_SIZES[$endArrowSize]['w']; + $this->lineStyleProperties['arrow']['end']['len'] = self::ARROW_SIZES[$endArrowSize]['len']; } if ($headArrowWidth !== '') { - $this->lineProperties['style']['arrow']['head']['w'] = $headArrowWidth; + $this->lineStyleProperties['arrow']['head']['w'] = $headArrowWidth; } if ($headArrowLength !== '') { - $this->lineProperties['style']['arrow']['head']['len'] = $headArrowLength; + $this->lineStyleProperties['arrow']['head']['len'] = $headArrowLength; } if ($endArrowWidth !== '') { - $this->lineProperties['style']['arrow']['end']['w'] = $endArrowWidth; + $this->lineStyleProperties['arrow']['end']['w'] = $endArrowWidth; } if ($endArrowLength !== '') { - $this->lineProperties['style']['arrow']['end']['len'] = $endArrowLength; + $this->lineStyleProperties['arrow']['end']['len'] = $endArrowLength; } } @@ -860,7 +876,7 @@ abstract class Properties */ public function getLineStyleProperty($elements) { - return $this->getArrayElementsValue($this->lineProperties['style'], $elements); + return $this->getArrayElementsValue($this->lineStyleProperties, $elements); } protected const ARROW_SIZES = [ @@ -890,7 +906,7 @@ abstract class Properties */ public function getLineStyleArrowParameters($arrowSelector, $propertySelector) { - return $this->getLineStyleArrowSize($this->lineProperties['style']['arrow'][$arrowSelector]['size'], $propertySelector); + return $this->getLineStyleArrowSize($this->lineStyleProperties['arrow'][$arrowSelector]['size'], $propertySelector); } /** diff --git a/src/PhpSpreadsheet/Reader/Xlsx/Chart.php b/src/PhpSpreadsheet/Reader/Xlsx/Chart.php index b046bc24..2c060d07 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/Chart.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/Chart.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Chart\Axis; +use PhpOffice\PhpSpreadsheet\Chart\ChartColor; use PhpOffice\PhpSpreadsheet\Chart\DataSeries; use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues; use PhpOffice\PhpSpreadsheet\Chart\GridLines; @@ -756,7 +757,7 @@ class Chart $complexScript = null; $fontSrgbClr = ''; $fontSchemeClr = ''; - $uSchemeClr = null; + $underlineColor = null; if (isset($titleDetailElement->rPr)) { // not used now, not sure it ever was, grandfathering if (isset($titleDetailElement->rPr->rFont['val'])) { @@ -797,9 +798,8 @@ class Chart /** @var ?string */ $underscore = self::getAttribute($titleDetailElement->rPr, 'u', 'string'); - if (isset($titleDetailElement->rPr->uFill->solidFill->schemeClr)) { - /** @var ?string */ - $uSchemeClr = self::getAttribute($titleDetailElement->rPr->uFill->solidFill->schemeClr, 'val', 'string'); + if (isset($titleDetailElement->rPr->uFill->solidFill)) { + $underlineColor = $this->readColor($titleDetailElement->rPr->uFill->solidFill); } /** @var ?string */ @@ -883,8 +883,8 @@ class Chart $objText->getFont()->setUnderline(Font::UNDERLINE_NONE); } $fontFound = true; - if ($uSchemeClr) { - $objText->getFont()->setUSchemeClr($uSchemeClr); + if ($underlineColor) { + $objText->getFont()->setUnderlineColor($underlineColor); } } @@ -1066,7 +1066,7 @@ class Chart 'value' => null, 'alpha' => null, ]; - foreach (Properties::EXCEL_COLOR_TYPES as $type) { + foreach (ChartColor::EXCEL_COLOR_TYPES as $type) { if (isset($colorXml->$type)) { $result['type'] = $type; $result['value'] = self::getAttribute($colorXml->$type, 'val', 'string'); @@ -1078,9 +1078,11 @@ class Chart $prstClr = $result['value']; } if (isset($colorXml->$type->alpha)) { - $alpha = (int) self::getAttribute($colorXml->$type->alpha, 'val', 'string'); - $alpha = 100 - (int) ($alpha / 1000); - $result['alpha'] = $alpha; + /** @var string */ + $alpha = self::getAttribute($colorXml->$type->alpha, 'val', 'string'); + if (is_numeric($alpha)) { + $result['alpha'] = ChartColor::alphaFromXml($alpha); + } } break; @@ -1154,7 +1156,7 @@ class Chart $endArrowLength ); $colorArray = $this->readColor($sppr->ln->solidFill); - $chartObject->setColorPropertiesArray($colorArray); + $chartObject->getLineColor()->setColorPropertiesArray($colorArray); } private function setAxisProperties(SimpleXMLElement $chartDetail, ?Axis $whichAxis): void diff --git a/src/PhpSpreadsheet/Style/Font.php b/src/PhpSpreadsheet/Style/Font.php index 7b1ced63..4dbe7272 100644 --- a/src/PhpSpreadsheet/Style/Font.php +++ b/src/PhpSpreadsheet/Style/Font.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheet\Style; +use PhpOffice\PhpSpreadsheet\Chart\ChartColor; + class Font extends Supervisor { // Underline types @@ -19,7 +21,7 @@ class Font extends Supervisor protected $name = 'Calibri'; /** - * The following 7 are used only for chart titles, I think. + * The following 6 are used only for chart titles, I think. * *@var string */ @@ -37,11 +39,8 @@ class Font extends Supervisor /** @var string */ private $strikeType = ''; - /** @var string */ - private $uSchemeClr = ''; - - /** @var string */ - private $uSrgbClr = ''; + /** @var ?ChartColor */ + private $underlineColor; // end of chart title items /** @@ -582,47 +581,24 @@ class Font extends Supervisor return $this; } - public function getUSchemeClr(): string + public function getUnderlineColor(): ?ChartColor { if ($this->isSupervisor) { - return $this->getSharedComponent()->getUSchemeClr(); + return $this->getSharedComponent()->getUnderlineColor(); } - return $this->uSchemeClr; + return $this->underlineColor; } - public function setUSchemeClr(string $uSchemeClr): self + public function setUnderlineColor(array $colorArray): self { if (!$this->isSupervisor) { - $this->uSchemeClr = $uSchemeClr; + $this->underlineColor = new ChartColor(); + $this->underlineColor->setColorPropertiesArray($colorArray); } else { // should never be true // @codeCoverageIgnoreStart - $styleArray = $this->getStyleArray(['uSchemeClr' => $uSchemeClr]); - $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); - // @codeCoverageIgnoreEnd - } - - return $this; - } - - public function getUSrgbClr(): string - { - if ($this->isSupervisor) { - return $this->getSharedComponent()->getUSrgbClr(); - } - - return $this->uSrgbClr; - } - - public function setUSrgbClr(string $uSrgbClr): self - { - if (!$this->isSupervisor) { - $this->uSrgbClr = $uSrgbClr; - } else { - // should never be true - // @codeCoverageIgnoreStart - $styleArray = $this->getStyleArray(['uSrgbClr' => $uSrgbClr]); + $styleArray = $this->getStyleArray(['underlineColor' => $colorArray]); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } @@ -747,6 +723,14 @@ class Font extends Supervisor if ($this->isSupervisor) { return $this->getSharedComponent()->getHashCode(); } + if ($this->underlineColor === null) { + $underlineColor = ''; + } else { + $underlineColor = + $this->underlineColor->getValue() + . $this->underlineColor->getType() + . (string) $this->underlineColor->getAlpha(); + } return md5( $this->name . @@ -765,8 +749,7 @@ class Font extends Supervisor $this->eastAsian, $this->complexScript, $this->strikeType, - $this->uSchemeClr, - $this->uSrgbClr, + $underlineColor, (string) $this->baseLine, ] ) . @@ -791,8 +774,7 @@ class Font extends Supervisor $this->exportArray2($exportedArray, 'subscript', $this->getSubscript()); $this->exportArray2($exportedArray, 'superscript', $this->getSuperscript()); $this->exportArray2($exportedArray, 'underline', $this->getUnderline()); - $this->exportArray2($exportedArray, 'uSchemeClr', $this->getUSchemeClr()); - $this->exportArray2($exportedArray, 'uSrgbClr', $this->getUSrgbClr()); + $this->exportArray2($exportedArray, 'underlineColor', $this->getUnderlineColor()); return $exportedArray; } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Chart.php b/src/PhpSpreadsheet/Writer/Xlsx/Chart.php index 1bdf4fe1..acc6f3af 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Chart.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Chart.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Chart\Axis; +use PhpOffice\PhpSpreadsheet\Chart\ChartColor; use PhpOffice\PhpSpreadsheet\Chart\DataSeries; use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues; use PhpOffice\PhpSpreadsheet\Chart\GridLines; @@ -517,19 +518,8 @@ class Chart extends WriterPart } $objWriter->startElement('c:spPr'); - if (!empty($yAxis->getFillProperty('value'))) { - $objWriter->startElement('a:solidFill'); - $objWriter->startElement('a:' . $yAxis->getFillProperty('type')); - $objWriter->writeAttribute('val', $yAxis->getFillProperty('value')); - $alpha = $yAxis->getFillProperty('alpha'); - if (is_numeric($alpha)) { - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', Properties::alphaToXml((int) $alpha)); - $objWriter->endElement(); - } - $objWriter->endElement(); - $objWriter->endElement(); - } + $this->writeColor($objWriter, $yAxis->getFillColorObject()); + $objWriter->startElement('a:effectLst'); $this->writeGlow($objWriter, $yAxis); $this->writeShadow($objWriter, $yAxis); @@ -723,19 +713,7 @@ class Chart extends WriterPart $objWriter->startElement('c:spPr'); - if (!empty($xAxis->getFillProperty('value'))) { - $objWriter->startElement('a:solidFill'); - $objWriter->startElement('a:' . $xAxis->getFillProperty('type')); - $objWriter->writeAttribute('val', $xAxis->getFillProperty('value')); - $alpha = $xAxis->getFillProperty('alpha'); - if (is_numeric($alpha)) { - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', Properties::alphaToXml((int) $alpha)); - $objWriter->endElement(); - } - $objWriter->endElement(); - $objWriter->endElement(); - } + $this->writeColor($objWriter, $xAxis->getFillColorObject()); $this->writeGridlinesLn($objWriter, $xAxis); @@ -1472,8 +1450,9 @@ class Chart extends WriterPart if (is_numeric($xAxis->getShadowProperty('direction'))) { $objWriter->writeAttribute('dir', Properties::angleToXml((float) $xAxis->getShadowProperty('direction'))); } - if ($xAxis->getShadowProperty('algn') !== null) { - $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn')); + $algn = $xAxis->getShadowProperty('algn'); + if (is_string($algn) && $algn !== '') { + $objWriter->writeAttribute('algn', $algn); } foreach (['sx', 'sy'] as $sizeType) { $sizeValue = $xAxis->getShadowProperty(['size', $sizeType]); @@ -1487,19 +1466,12 @@ class Chart extends WriterPart $objWriter->writeAttribute($sizeType, Properties::angleToXml((float) $sizeValue)); } } - if ($xAxis->getShadowProperty('rotWithShape') !== null) { - $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape')); + $rotWithShape = $xAxis->getShadowProperty('rotWithShape'); + if (is_numeric($rotWithShape)) { + $objWriter->writeAttribute('rotWithShape', (string) (int) $rotWithShape); } - $objWriter->startElement("a:{$xAxis->getShadowProperty(['color', 'type'])}"); - $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color', 'value'])); - $alpha = $xAxis->getShadowProperty(['color', 'alpha']); - if (is_numeric($alpha)) { - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', Properties::alphaToXml((int) $alpha)); - $objWriter->endElement(); - } - $objWriter->endElement(); + $this->writeColor($objWriter, $xAxis->getShadowColorObject(), false); $objWriter->endElement(); } @@ -1517,15 +1489,7 @@ class Chart extends WriterPart } $objWriter->startElement('a:glow'); $objWriter->writeAttribute('rad', Properties::pointsToXml((float) $size)); - $objWriter->startElement("a:{$yAxis->getGlowProperty(['color', 'type'])}"); - $objWriter->writeAttribute('val', (string) $yAxis->getGlowProperty(['color', 'value'])); - $alpha = $yAxis->getGlowProperty(['color', 'alpha']); - if (is_numeric($alpha)) { - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', Properties::alphaToXml((int) $alpha)); - $objWriter->endElement(); // alpha - } - $objWriter->endElement(); // color + $this->writeColor($objWriter, $yAxis->getGlowColorObject(), false); $objWriter->endElement(); // glow } @@ -1559,19 +1523,7 @@ class Chart extends WriterPart } $this->writeNotEmpty($objWriter, 'cap', $gridlines->getLineStyleProperty('cap')); $this->writeNotEmpty($objWriter, 'cmpd', $gridlines->getLineStyleProperty('compound')); - if (!empty($gridlines->getLineColorProperty('value'))) { - $objWriter->startElement('a:solidFill'); - $objWriter->startElement("a:{$gridlines->getLineColorProperty('type')}"); - $objWriter->writeAttribute('val', (string) $gridlines->getLineColorProperty('value')); - $alpha = $gridlines->getLineColorProperty('alpha'); - if (is_numeric($alpha)) { - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', Properties::alphaToXml((int) $alpha)); - $objWriter->endElement(); // alpha - } - $objWriter->endElement(); //end srgbClr - $objWriter->endElement(); //end solidFill - } + $this->writeColor($objWriter, $gridlines->getLineColor()); $dash = $gridlines->getLineStyleProperty('dash'); if (!empty($dash)) { @@ -1613,4 +1565,27 @@ class Chart extends WriterPart $objWriter->writeAttribute($name, $value); } } + + private function writeColor(XMLWriter $objWriter, ChartColor $chartColor, bool $solidFill = true): void + { + $type = $chartColor->getType(); + $value = $chartColor->getValue(); + if (!empty($type) && !empty($value)) { + if ($solidFill) { + $objWriter->startElement('a:solidFill'); + } + $objWriter->startElement("a:$type"); + $objWriter->writeAttribute('val', $value); + $alpha = $chartColor->getAlpha(); + if (is_numeric($alpha)) { + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', ChartColor::alphaToXml((int) $alpha)); + $objWriter->endElement(); + } + $objWriter->endElement(); //a:srgbClr/schemeClr/prstClr + if ($solidFill) { + $objWriter->endElement(); //a:solidFill + } + } + } } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php b/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php index da7d825b..8a376df4 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php @@ -256,14 +256,19 @@ class StringTable extends WriterPart $objWriter->endElement(); // solidFill // Underscore Color - if ($element->getFont()->getUSchemeClr()) { - $objWriter->startElement($prefix . 'uFill'); - $objWriter->startElement($prefix . 'solidFill'); - $objWriter->startElement($prefix . 'schemeClr'); - $objWriter->writeAttribute('val', $element->getFont()->getUSchemeClr()); - $objWriter->endElement(); // schemeClr - $objWriter->endElement(); // solidFill - $objWriter->endElement(); // uFill + $underlineColor = $element->getFont()->getUnderlineColor(); + if ($underlineColor !== null) { + $type = $underlineColor->getType(); + $value = $underlineColor->getValue(); + if (!empty($type) && !empty($value)) { + $objWriter->startElement($prefix . 'uFill'); + $objWriter->startElement($prefix . 'solidFill'); + $objWriter->startElement($prefix . $type); + $objWriter->writeAttribute('val', $value); + $objWriter->endElement(); // schemeClr + $objWriter->endElement(); // solidFill + $objWriter->endElement(); // uFill + } } // fontName