From b9111c73548d40b06d6d8531a127b8221ae47816 Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Fri, 17 Jun 2022 00:05:24 -0700 Subject: [PATCH 1/2] 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. --- src/PhpSpreadsheet/Chart/Axis.php | 25 +- 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 | 113 ++++--- .../Writer/Xlsx/StringTable.php | 21 +- 7 files changed, 399 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 09a4febc11..7343af46aa 100644 --- a/src/PhpSpreadsheet/Chart/Axis.php +++ b/src/PhpSpreadsheet/Chart/Axis.php @@ -10,6 +10,12 @@ */ 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 @@ public function setAxisOrientation($orientation): void */ 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,24 @@ public function setFillParameters($color, $alpha = null, $AlphaType = self::EXCE */ public function getFillProperty($property) { - return (string) $this->fillProperties[$property]; + return (string) $this->fillColor->getColorProperty($property); } /** * 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 0000000000..05c1bb9af0 --- /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 c6b2d15bef..a64a826fa7 100644 --- a/src/PhpSpreadsheet/Chart/Properties.php +++ b/src/PhpSpreadsheet/Chart/Properties.php @@ -10,15 +10,12 @@ */ 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 @@ public static function xmlToTenthOfPercent(string $value): float 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 @@ protected function setColorProperties(?string $color, $alpha, ?string $colorType 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 @@ public function setGlowProperties($size, $colorValue = null, $colorAlpha = null, { $this ->activateObject() - ->setGlowSize($size) - ->setGlowColor($colorValue, $colorAlpha, $colorType); + ->setGlowSize($size); + $this->glowColor->setColorPropertiesArray( + [ + 'value' => $colorValue, + 'type' => $colorType, + 'alpha' => $colorAlpha, + ] + ); } /** @@ -466,11 +465,24 @@ public function setGlowProperties($size, $colorValue = null, $colorAlpha = null, * * @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 @@ public function getGlowProperty($property) * * @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 @@ public function getSoftEdgesSize() 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 @@ public function setShadowProperty(string $propertyName, $value): self */ 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 @@ protected function setShadowDistance($distance) 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 @@ public function getShadowProperty($elements) * @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 @@ public function setColorPropertiesArray(array $color): void */ public function getLineColorProperty($propertyName) { - return $this->lineProperties['color'][$propertyName]; + return $this->lineColor->getColorProperty($propertyName); } /** @@ -807,47 +823,47 @@ public function setLineStyleProperties($lineWidth = null, $compoundType = '', $d { $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 @@ public function setLineStyleProperties($lineWidth = null, $compoundType = '', $d */ 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 @@ protected function getLineStyleArrowSize($arraySelector, $arrayKaySelector) */ 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 b046bc2484..2c060d0727 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/Chart.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/Chart.php @@ -4,6 +4,7 @@ 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 @@ private function parseRichText(SimpleXMLElement $titleDetailPart): RichText $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 @@ private function parseRichText(SimpleXMLElement $titleDetailPart): RichText /** @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 @@ private function parseRichText(SimpleXMLElement $titleDetailPart): RichText $objText->getFont()->setUnderline(Font::UNDERLINE_NONE); } $fontFound = true; - if ($uSchemeClr) { - $objText->getFont()->setUSchemeClr($uSchemeClr); + if ($underlineColor) { + $objText->getFont()->setUnderlineColor($underlineColor); } } @@ -1066,7 +1066,7 @@ private function readColor(SimpleXMLElement $colorXml, ?string &$srgbClr = null, '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 @@ private function readColor(SimpleXMLElement $colorXml, ?string &$srgbClr = null, $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 @@ private function readLineStyle(SimpleXMLElement $chartDetail, $chartObject): voi $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 7b1ced63e6..4dbe7272f1 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 @@ public function setStrikeType(string $strikeType): self return $this; } - public function getUSchemeClr(): string - { - if ($this->isSupervisor) { - return $this->getSharedComponent()->getUSchemeClr(); - } - - return $this->uSchemeClr; - } - - public function setUSchemeClr(string $uSchemeClr): self - { - if (!$this->isSupervisor) { - $this->uSchemeClr = $uSchemeClr; - } 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 + public function getUnderlineColor(): ?ChartColor { if ($this->isSupervisor) { - return $this->getSharedComponent()->getUSrgbClr(); + return $this->getSharedComponent()->getUnderlineColor(); } - return $this->uSrgbClr; + return $this->underlineColor; } - public function setUSrgbClr(string $uSrgbClr): self + public function setUnderlineColor(array $colorArray): self { if (!$this->isSupervisor) { - $this->uSrgbClr = $uSrgbClr; + $this->underlineColor = new ChartColor(); + $this->underlineColor->setColorPropertiesArray($colorArray); } 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 @@ public function getHashCode() 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 @@ public function getHashCode() $this->eastAsian, $this->complexScript, $this->strikeType, - $this->uSchemeClr, - $this->uSrgbClr, + $underlineColor, (string) $this->baseLine, ] ) . @@ -791,8 +774,7 @@ protected function exportArray1(): array $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 1bdf4fe1a3..9766aca370 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,11 @@ private function writeCategoryAxis(XMLWriter $objWriter, ?Title $xAxisLabel, $id } $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(); - } + $type = $yAxis->getFillProperty('type'); + $value = $yAxis->getFillProperty('value'); + $alpha = $yAxis->getFillProperty('alpha'); + $this->writeColor($objWriter, $type, $value, $alpha); + $objWriter->startElement('a:effectLst'); $this->writeGlow($objWriter, $yAxis); $this->writeShadow($objWriter, $yAxis); @@ -723,19 +716,10 @@ private function writeValueAxis(XMLWriter $objWriter, ?Title $yAxisLabel, $group $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(); - } + $type = $xAxis->getFillProperty('type'); + $value = $xAxis->getFillProperty('value'); + $alpha = $xAxis->getFillProperty('alpha'); + $this->writeColor($objWriter, $type, $value, $alpha); $this->writeGridlinesLn($objWriter, $xAxis); @@ -1472,8 +1456,9 @@ private function writeShadow(XMLWriter $objWriter, $xAxis): void 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 +1472,16 @@ private function writeShadow(XMLWriter $objWriter, $xAxis): void $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(); + $colorObject = $xAxis->getShadowColorObject(); + $colorType = $colorObject->getType(); + $colorValue = $colorObject->getValue(); + $alpha = $colorObject->getAlpha(); + $this->writeColor($objWriter, $colorType, $colorValue, $alpha, false); $objWriter->endElement(); } @@ -1517,15 +1499,10 @@ private function writeGlow(XMLWriter $objWriter, $yAxis): void } $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 + $type = $yAxis->getGlowColorObject()->getType(); + $color = $yAxis->getGlowColorObject()->getValue(); + $alpha = $yAxis->getGlowColorObject()->getAlpha(); + $this->writeColor($objWriter, $type, $color, $alpha, false); $objWriter->endElement(); // glow } @@ -1559,19 +1536,10 @@ private function writeGridlinesLn(XMLWriter $objWriter, $gridlines): void } $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 - } + $type = $gridlines->getLineColorProperty('type'); + $value = $gridlines->getLineColorProperty('value'); + $alpha = $gridlines->getLineColorProperty('alpha'); + $this->writeColor($objWriter, (string) $type, (string) $value, $alpha); $dash = $gridlines->getLineStyleProperty('dash'); if (!empty($dash)) { @@ -1613,4 +1581,27 @@ private function writeNotEmpty(XMLWriter $objWriter, string $name, ?string $valu $objWriter->writeAttribute($name, $value); } } + + /** + * @param null|int|string $alpha + */ + private function writeColor(XMLWriter $objWriter, ?string $type, ?string $value, $alpha, bool $solidFill = true): void + { + if (!empty($type) && !empty($value)) { + if ($solidFill) { + $objWriter->startElement('a:solidFill'); + } + $objWriter->startElement("a:$type"); + $objWriter->writeAttribute('val', $value); + 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 da7d825bdd..8a376df420 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php @@ -256,14 +256,19 @@ public function writeRichTextForCharts(XMLWriter $objWriter, $richText = null, $ $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 From a9b081339c7708e166bf34fa4fabe3c5b08a1c7d Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Fri, 17 Jun 2022 01:08:54 -0700 Subject: [PATCH 2/2] Simplify Logic in Xlsx/Writer/Chart Minor change. --- src/PhpSpreadsheet/Chart/Axis.php | 5 ++++ src/PhpSpreadsheet/Writer/Xlsx/Chart.php | 34 +++++++----------------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/PhpSpreadsheet/Chart/Axis.php b/src/PhpSpreadsheet/Chart/Axis.php index 7343af46aa..69a25d9263 100644 --- a/src/PhpSpreadsheet/Chart/Axis.php +++ b/src/PhpSpreadsheet/Chart/Axis.php @@ -180,6 +180,11 @@ public function getFillProperty($property) return (string) $this->fillColor->getColorProperty($property); } + public function getFillColorObject(): ChartColor + { + return $this->fillColor; + } + /** * Get Line Color Property. * diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Chart.php b/src/PhpSpreadsheet/Writer/Xlsx/Chart.php index 9766aca370..acc6f3af34 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Chart.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Chart.php @@ -518,10 +518,7 @@ private function writeCategoryAxis(XMLWriter $objWriter, ?Title $xAxisLabel, $id } $objWriter->startElement('c:spPr'); - $type = $yAxis->getFillProperty('type'); - $value = $yAxis->getFillProperty('value'); - $alpha = $yAxis->getFillProperty('alpha'); - $this->writeColor($objWriter, $type, $value, $alpha); + $this->writeColor($objWriter, $yAxis->getFillColorObject()); $objWriter->startElement('a:effectLst'); $this->writeGlow($objWriter, $yAxis); @@ -716,10 +713,7 @@ private function writeValueAxis(XMLWriter $objWriter, ?Title $yAxisLabel, $group $objWriter->startElement('c:spPr'); - $type = $xAxis->getFillProperty('type'); - $value = $xAxis->getFillProperty('value'); - $alpha = $xAxis->getFillProperty('alpha'); - $this->writeColor($objWriter, $type, $value, $alpha); + $this->writeColor($objWriter, $xAxis->getFillColorObject()); $this->writeGridlinesLn($objWriter, $xAxis); @@ -1477,11 +1471,7 @@ private function writeShadow(XMLWriter $objWriter, $xAxis): void $objWriter->writeAttribute('rotWithShape', (string) (int) $rotWithShape); } - $colorObject = $xAxis->getShadowColorObject(); - $colorType = $colorObject->getType(); - $colorValue = $colorObject->getValue(); - $alpha = $colorObject->getAlpha(); - $this->writeColor($objWriter, $colorType, $colorValue, $alpha, false); + $this->writeColor($objWriter, $xAxis->getShadowColorObject(), false); $objWriter->endElement(); } @@ -1499,10 +1489,7 @@ private function writeGlow(XMLWriter $objWriter, $yAxis): void } $objWriter->startElement('a:glow'); $objWriter->writeAttribute('rad', Properties::pointsToXml((float) $size)); - $type = $yAxis->getGlowColorObject()->getType(); - $color = $yAxis->getGlowColorObject()->getValue(); - $alpha = $yAxis->getGlowColorObject()->getAlpha(); - $this->writeColor($objWriter, $type, $color, $alpha, false); + $this->writeColor($objWriter, $yAxis->getGlowColorObject(), false); $objWriter->endElement(); // glow } @@ -1536,10 +1523,7 @@ private function writeGridlinesLn(XMLWriter $objWriter, $gridlines): void } $this->writeNotEmpty($objWriter, 'cap', $gridlines->getLineStyleProperty('cap')); $this->writeNotEmpty($objWriter, 'cmpd', $gridlines->getLineStyleProperty('compound')); - $type = $gridlines->getLineColorProperty('type'); - $value = $gridlines->getLineColorProperty('value'); - $alpha = $gridlines->getLineColorProperty('alpha'); - $this->writeColor($objWriter, (string) $type, (string) $value, $alpha); + $this->writeColor($objWriter, $gridlines->getLineColor()); $dash = $gridlines->getLineStyleProperty('dash'); if (!empty($dash)) { @@ -1582,17 +1566,17 @@ private function writeNotEmpty(XMLWriter $objWriter, string $name, ?string $valu } } - /** - * @param null|int|string $alpha - */ - private function writeColor(XMLWriter $objWriter, ?string $type, ?string $value, $alpha, bool $solidFill = true): void + 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));