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.
This commit is contained in:
oleibman 2022-06-19 19:11:40 -07:00 committed by GitHub
parent 4ae947ce64
commit 6fae406aca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 388 additions and 263 deletions

View File

@ -10,6 +10,12 @@ namespace PhpOffice\PhpSpreadsheet\Chart;
*/ */
class Axis extends Properties class Axis extends Properties
{ {
public function __construct()
{
parent::__construct();
$this->fillColor = new ChartColor();
}
/** /**
* Axis Number. * Axis Number.
* *
@ -42,13 +48,9 @@ class Axis extends Properties
/** /**
* Fill Properties. * Fill Properties.
* *
* @var mixed[] * @var ChartColor
*/ */
private $fillProperties = [ private $fillColor;
'type' => self::EXCEL_COLOR_TYPE_ARGB,
'value' => null,
'alpha' => 0,
];
private const NUMERIC_FORMAT = [ private const NUMERIC_FORMAT = [
Properties::FORMAT_CODE_NUMBER, 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 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) 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. * Get Line Color Property.
* *
* @Deprecated 1.24.0
*
* @See Properties::getLineColorProperty()
* Use the getLineColor property in the Properties class instead
*
* @param string $propertyName * @param string $propertyName
* *
* @return null|int|string * @return null|int|string
*/ */
public function getLineProperty($propertyName) public function getLineProperty($propertyName)
{ {
return $this->lineProperties['color'][$propertyName]; return $this->getLineColorProperty($propertyName);
} }
/** @var string */ /** @var string */

View File

@ -0,0 +1,133 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Chart;
class ChartColor
{
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,
];
/** @var string */
private $value = '';
/** @var string */
private $type = '';
/** @var ?int */
private $alpha;
public function getValue(): string
{
return $this->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);
}
}

View File

@ -10,15 +10,12 @@ namespace PhpOffice\PhpSpreadsheet\Chart;
*/ */
abstract class Properties abstract class Properties
{ {
const /** @deprecated 1.24 use constant from ChartColor instead */
EXCEL_COLOR_TYPE_STANDARD = 'prstClr'; const EXCEL_COLOR_TYPE_STANDARD = ChartColor::EXCEL_COLOR_TYPE_STANDARD;
const EXCEL_COLOR_TYPE_SCHEME = 'schemeClr'; /** @deprecated 1.24 use constant from ChartColor instead */
const EXCEL_COLOR_TYPE_ARGB = 'srgbClr'; const EXCEL_COLOR_TYPE_SCHEME = ChartColor::EXCEL_COLOR_TYPE_SCHEME;
const EXCEL_COLOR_TYPES = [ /** @deprecated 1.24 use constant from ChartColor instead */
self::EXCEL_COLOR_TYPE_ARGB, const EXCEL_COLOR_TYPE_ARGB = ChartColor::EXCEL_COLOR_TYPE_ARGB;
self::EXCEL_COLOR_TYPE_SCHEME,
self::EXCEL_COLOR_TYPE_STANDARD,
];
const const
AXIS_LABELS_LOW = 'low'; AXIS_LABELS_LOW = 'low';
@ -123,15 +120,11 @@ abstract class Properties
/** @var bool */ /** @var bool */
protected $objectState = false; // used only for minor gridlines protected $objectState = false; // used only for minor gridlines
/** @var array */ /** @var ?float */
protected $glowProperties = [ protected $glowSize;
'size' => null,
'color' => [ /** @var ChartColor */
'type' => self::EXCEL_COLOR_TYPE_STANDARD, protected $glowColor;
'value' => 'black',
'alpha' => 40,
],
];
/** @var array */ /** @var array */
protected $softEdges = [ protected $softEdges = [
@ -141,6 +134,19 @@ abstract class Properties
/** @var array */ /** @var array */
protected $shadowProperties = self::PRESETS_OPTIONS[0]; 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. * Get Object State.
* *
@ -193,19 +199,6 @@ abstract class Properties
return ((float) $value) / self::PERCENTAGE_MULTIPLIER; 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 * @param null|float|int|string $alpha
*/ */
@ -223,11 +216,11 @@ abstract class Properties
0 => [ 0 => [
'presets' => self::SHADOW_PRESETS_NOSHADOW, 'presets' => self::SHADOW_PRESETS_NOSHADOW,
'effect' => null, 'effect' => null,
'color' => [ //'color' => [
'type' => self::EXCEL_COLOR_TYPE_STANDARD, // 'type' => ChartColor::EXCEL_COLOR_TYPE_STANDARD,
'value' => 'black', // 'value' => 'black',
'alpha' => 40, // 'alpha' => 40,
], //],
'size' => [ 'size' => [
'sx' => null, 'sx' => null,
'sy' => null, 'sy' => null,
@ -457,8 +450,14 @@ abstract class Properties
{ {
$this $this
->activateObject() ->activateObject()
->setGlowSize($size) ->setGlowSize($size);
->setGlowColor($colorValue, $colorAlpha, $colorType); $this->glowColor->setColorPropertiesArray(
[
'value' => $colorValue,
'type' => $colorType,
'alpha' => $colorAlpha,
]
);
} }
/** /**
@ -466,11 +465,24 @@ abstract class Properties
* *
* @param array|string $property * @param array|string $property
* *
* @return null|string * @return null|array|float|int|string
*/ */
public function getGlowProperty($property) 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 * @param string $propertyName
* *
* @return string * @return null|int|string
*/ */
public function getGlowColor($propertyName) public function getGlowColor($propertyName)
{ {
return $this->glowProperties['color'][$propertyName]; return $this->glowColor->getColorProperty($propertyName);
}
public function getGlowColorObject(): ChartColor
{
return $this->glowColor;
} }
/** /**
* Get Glow Size. * Get Glow Size.
* *
* @return string * @return ?float
*/ */
public function getGlowSize() public function getGlowSize()
{ {
return $this->glowProperties['size']; return $this->glowSize;
} }
/** /**
* Set Glow Size. * Set Glow Size.
* *
* @param float $size * @param ?float $size
* *
* @return $this * @return $this
*/ */
protected function setGlowSize($size) protected function setGlowSize($size)
{ {
$this->glowProperties['size'] = $size; $this->glowSize = $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;
}
return $this; return $this;
} }
@ -562,7 +555,11 @@ abstract class Properties
public function setShadowProperty(string $propertyName, $value): self public function setShadowProperty(string $propertyName, $value): self
{ {
$this->activateObject(); $this->activateObject();
if ($propertyName === 'color' && is_array($value)) {
$this->shadowColor->setColorPropertiesArray($value);
} else {
$this->shadowProperties[$propertyName] = $value; $this->shadowProperties[$propertyName] = $value;
}
return $this; 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 public function setShadowProperties($presets, $colorValue = null, $colorType = null, $colorAlpha = null, $blur = null, $angle = null, $distance = null): void
{ {
$this->activateObject() $this->activateObject()->setShadowPresetsProperties((int) $presets);
->setShadowPresetsProperties((int) $presets) if ($presets === 0) {
->setShadowColor( $this->shadowColor->setType(ChartColor::EXCEL_COLOR_TYPE_STANDARD);
$colorValue ?? $this->shadowProperties['color']['value'], $this->shadowColor->setValue('black');
$colorAlpha === null ? (int) $this->shadowProperties['color']['alpha'] : (int) $colorAlpha, $this->shadowColor->setAlpha(40);
$colorType ?? $this->shadowProperties['color']['type'] }
) 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) ->setShadowBlur($blur)
->setShadowAngle($angle) ->setShadowAngle($angle)
->setShadowDistance($distance); ->setShadowDistance($distance);
@ -709,26 +715,36 @@ abstract class Properties
return $this; return $this;
} }
public function getShadowColorObject(): ChartColor
{
return $this->shadowColor;
}
/** /**
* Get Shadow Property. * Get Shadow Property.
* *
* @param string|string[] $elements * @param string|string[] $elements
* *
* @return string * @return array|string
*/ */
public function getShadowProperty($elements) 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); return $this->getArrayElementsValue($this->shadowProperties, $elements);
} }
/** @var ChartColor */
protected $lineColor;
/** @var array */ /** @var array */
protected $lineProperties = [ protected $lineStyleProperties = [
'color' => [
'type' => '', //self::EXCEL_COLOR_TYPE_STANDARD,
'value' => '', //null,
'alpha' => null,
],
'style' => [
'width' => null, //'9525', 'width' => null, //'9525',
'compound' => '', //self::LINE_STYLE_COMPOUND_SIMPLE, 'compound' => '', //self::LINE_STYLE_COMPOUND_SIMPLE,
'dash' => '', //self::LINE_STYLE_DASH_SOLID, 'dash' => '', //self::LINE_STYLE_DASH_SOLID,
@ -748,9 +764,13 @@ abstract class Properties
'len' => '', 'len' => '',
], ],
], ],
],
]; ];
public function getLineColor(): ChartColor
{
return $this->lineColor;
}
/** /**
* Set Line Color Properties. * Set Line Color Properties.
* *
@ -758,22 +778,18 @@ abstract class Properties
* @param ?int $alpha * @param ?int $alpha
* @param string $colorType * @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() $this->activateObject();
->lineProperties['color'] = $this->setColorProperties( $this->lineColor->setColorPropertiesArray(
$this->setColorProperties(
$value, $value,
$alpha, $alpha,
$colorType $colorType
)
); );
} }
public function setColorPropertiesArray(array $color): void
{
$this->activateObject()
->lineProperties['color'] = $color;
}
/** /**
* Get Line Color Property. * Get Line Color Property.
* *
@ -783,7 +799,7 @@ abstract class Properties
*/ */
public function getLineColorProperty($propertyName) public function getLineColorProperty($propertyName)
{ {
return $this->lineProperties['color'][$propertyName]; return $this->lineColor->getColorProperty($propertyName);
} }
/** /**
@ -807,47 +823,47 @@ abstract class Properties
{ {
$this->activateObject(); $this->activateObject();
if (is_numeric($lineWidth)) { if (is_numeric($lineWidth)) {
$this->lineProperties['style']['width'] = $lineWidth; $this->lineStyleProperties['width'] = $lineWidth;
} }
if ($compoundType !== '') { if ($compoundType !== '') {
$this->lineProperties['style']['compound'] = $compoundType; $this->lineStyleProperties['compound'] = $compoundType;
} }
if ($dashType !== '') { if ($dashType !== '') {
$this->lineProperties['style']['dash'] = $dashType; $this->lineStyleProperties['dash'] = $dashType;
} }
if ($capType !== '') { if ($capType !== '') {
$this->lineProperties['style']['cap'] = $capType; $this->lineStyleProperties['cap'] = $capType;
} }
if ($joinType !== '') { if ($joinType !== '') {
$this->lineProperties['style']['join'] = $joinType; $this->lineStyleProperties['join'] = $joinType;
} }
if ($headArrowType !== '') { if ($headArrowType !== '') {
$this->lineProperties['style']['arrow']['head']['type'] = $headArrowType; $this->lineStyleProperties['arrow']['head']['type'] = $headArrowType;
} }
if (array_key_exists($headArrowSize, self::ARROW_SIZES)) { if (array_key_exists($headArrowSize, self::ARROW_SIZES)) {
$this->lineProperties['style']['arrow']['head']['size'] = $headArrowSize; $this->lineStyleProperties['arrow']['head']['size'] = $headArrowSize;
$this->lineProperties['style']['arrow']['head']['w'] = self::ARROW_SIZES[$headArrowSize]['w']; $this->lineStyleProperties['arrow']['head']['w'] = self::ARROW_SIZES[$headArrowSize]['w'];
$this->lineProperties['style']['arrow']['head']['len'] = self::ARROW_SIZES[$headArrowSize]['len']; $this->lineStyleProperties['arrow']['head']['len'] = self::ARROW_SIZES[$headArrowSize]['len'];
} }
if ($endArrowType !== '') { if ($endArrowType !== '') {
$this->lineProperties['style']['arrow']['end']['type'] = $endArrowType; $this->lineStyleProperties['arrow']['end']['type'] = $endArrowType;
} }
if (array_key_exists($endArrowSize, self::ARROW_SIZES)) { if (array_key_exists($endArrowSize, self::ARROW_SIZES)) {
$this->lineProperties['style']['arrow']['end']['size'] = $endArrowSize; $this->lineStyleProperties['arrow']['end']['size'] = $endArrowSize;
$this->lineProperties['style']['arrow']['end']['w'] = self::ARROW_SIZES[$endArrowSize]['w']; $this->lineStyleProperties['arrow']['end']['w'] = self::ARROW_SIZES[$endArrowSize]['w'];
$this->lineProperties['style']['arrow']['end']['len'] = self::ARROW_SIZES[$endArrowSize]['len']; $this->lineStyleProperties['arrow']['end']['len'] = self::ARROW_SIZES[$endArrowSize]['len'];
} }
if ($headArrowWidth !== '') { if ($headArrowWidth !== '') {
$this->lineProperties['style']['arrow']['head']['w'] = $headArrowWidth; $this->lineStyleProperties['arrow']['head']['w'] = $headArrowWidth;
} }
if ($headArrowLength !== '') { if ($headArrowLength !== '') {
$this->lineProperties['style']['arrow']['head']['len'] = $headArrowLength; $this->lineStyleProperties['arrow']['head']['len'] = $headArrowLength;
} }
if ($endArrowWidth !== '') { if ($endArrowWidth !== '') {
$this->lineProperties['style']['arrow']['end']['w'] = $endArrowWidth; $this->lineStyleProperties['arrow']['end']['w'] = $endArrowWidth;
} }
if ($endArrowLength !== '') { 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) public function getLineStyleProperty($elements)
{ {
return $this->getArrayElementsValue($this->lineProperties['style'], $elements); return $this->getArrayElementsValue($this->lineStyleProperties, $elements);
} }
protected const ARROW_SIZES = [ protected const ARROW_SIZES = [
@ -890,7 +906,7 @@ abstract class Properties
*/ */
public function getLineStyleArrowParameters($arrowSelector, $propertySelector) public function getLineStyleArrowParameters($arrowSelector, $propertySelector)
{ {
return $this->getLineStyleArrowSize($this->lineProperties['style']['arrow'][$arrowSelector]['size'], $propertySelector); return $this->getLineStyleArrowSize($this->lineStyleProperties['arrow'][$arrowSelector]['size'], $propertySelector);
} }
/** /**

View File

@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
use PhpOffice\PhpSpreadsheet\Chart\Axis; use PhpOffice\PhpSpreadsheet\Chart\Axis;
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries; use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues; use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
use PhpOffice\PhpSpreadsheet\Chart\GridLines; use PhpOffice\PhpSpreadsheet\Chart\GridLines;
@ -756,7 +757,7 @@ class Chart
$complexScript = null; $complexScript = null;
$fontSrgbClr = ''; $fontSrgbClr = '';
$fontSchemeClr = ''; $fontSchemeClr = '';
$uSchemeClr = null; $underlineColor = null;
if (isset($titleDetailElement->rPr)) { if (isset($titleDetailElement->rPr)) {
// not used now, not sure it ever was, grandfathering // not used now, not sure it ever was, grandfathering
if (isset($titleDetailElement->rPr->rFont['val'])) { if (isset($titleDetailElement->rPr->rFont['val'])) {
@ -797,9 +798,8 @@ class Chart
/** @var ?string */ /** @var ?string */
$underscore = self::getAttribute($titleDetailElement->rPr, 'u', 'string'); $underscore = self::getAttribute($titleDetailElement->rPr, 'u', 'string');
if (isset($titleDetailElement->rPr->uFill->solidFill->schemeClr)) { if (isset($titleDetailElement->rPr->uFill->solidFill)) {
/** @var ?string */ $underlineColor = $this->readColor($titleDetailElement->rPr->uFill->solidFill);
$uSchemeClr = self::getAttribute($titleDetailElement->rPr->uFill->solidFill->schemeClr, 'val', 'string');
} }
/** @var ?string */ /** @var ?string */
@ -883,8 +883,8 @@ class Chart
$objText->getFont()->setUnderline(Font::UNDERLINE_NONE); $objText->getFont()->setUnderline(Font::UNDERLINE_NONE);
} }
$fontFound = true; $fontFound = true;
if ($uSchemeClr) { if ($underlineColor) {
$objText->getFont()->setUSchemeClr($uSchemeClr); $objText->getFont()->setUnderlineColor($underlineColor);
} }
} }
@ -1066,7 +1066,7 @@ class Chart
'value' => null, 'value' => null,
'alpha' => null, 'alpha' => null,
]; ];
foreach (Properties::EXCEL_COLOR_TYPES as $type) { foreach (ChartColor::EXCEL_COLOR_TYPES as $type) {
if (isset($colorXml->$type)) { if (isset($colorXml->$type)) {
$result['type'] = $type; $result['type'] = $type;
$result['value'] = self::getAttribute($colorXml->$type, 'val', 'string'); $result['value'] = self::getAttribute($colorXml->$type, 'val', 'string');
@ -1078,9 +1078,11 @@ class Chart
$prstClr = $result['value']; $prstClr = $result['value'];
} }
if (isset($colorXml->$type->alpha)) { if (isset($colorXml->$type->alpha)) {
$alpha = (int) self::getAttribute($colorXml->$type->alpha, 'val', 'string'); /** @var string */
$alpha = 100 - (int) ($alpha / 1000); $alpha = self::getAttribute($colorXml->$type->alpha, 'val', 'string');
$result['alpha'] = $alpha; if (is_numeric($alpha)) {
$result['alpha'] = ChartColor::alphaFromXml($alpha);
}
} }
break; break;
@ -1154,7 +1156,7 @@ class Chart
$endArrowLength $endArrowLength
); );
$colorArray = $this->readColor($sppr->ln->solidFill); $colorArray = $this->readColor($sppr->ln->solidFill);
$chartObject->setColorPropertiesArray($colorArray); $chartObject->getLineColor()->setColorPropertiesArray($colorArray);
} }
private function setAxisProperties(SimpleXMLElement $chartDetail, ?Axis $whichAxis): void private function setAxisProperties(SimpleXMLElement $chartDetail, ?Axis $whichAxis): void

View File

@ -2,6 +2,8 @@
namespace PhpOffice\PhpSpreadsheet\Style; namespace PhpOffice\PhpSpreadsheet\Style;
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
class Font extends Supervisor class Font extends Supervisor
{ {
// Underline types // Underline types
@ -19,7 +21,7 @@ class Font extends Supervisor
protected $name = 'Calibri'; 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 *@var string
*/ */
@ -37,11 +39,8 @@ class Font extends Supervisor
/** @var string */ /** @var string */
private $strikeType = ''; private $strikeType = '';
/** @var string */ /** @var ?ChartColor */
private $uSchemeClr = ''; private $underlineColor;
/** @var string */
private $uSrgbClr = '';
// end of chart title items // end of chart title items
/** /**
@ -582,47 +581,24 @@ class Font extends Supervisor
return $this; return $this;
} }
public function getUSchemeClr(): string public function getUnderlineColor(): ?ChartColor
{ {
if ($this->isSupervisor) { 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) { if (!$this->isSupervisor) {
$this->uSchemeClr = $uSchemeClr; $this->underlineColor = new ChartColor();
$this->underlineColor->setColorPropertiesArray($colorArray);
} else { } else {
// should never be true // should never be true
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
$styleArray = $this->getStyleArray(['uSchemeClr' => $uSchemeClr]); $styleArray = $this->getStyleArray(['underlineColor' => $colorArray]);
$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]);
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
} }
@ -747,6 +723,14 @@ class Font extends Supervisor
if ($this->isSupervisor) { if ($this->isSupervisor) {
return $this->getSharedComponent()->getHashCode(); return $this->getSharedComponent()->getHashCode();
} }
if ($this->underlineColor === null) {
$underlineColor = '';
} else {
$underlineColor =
$this->underlineColor->getValue()
. $this->underlineColor->getType()
. (string) $this->underlineColor->getAlpha();
}
return md5( return md5(
$this->name . $this->name .
@ -765,8 +749,7 @@ class Font extends Supervisor
$this->eastAsian, $this->eastAsian,
$this->complexScript, $this->complexScript,
$this->strikeType, $this->strikeType,
$this->uSchemeClr, $underlineColor,
$this->uSrgbClr,
(string) $this->baseLine, (string) $this->baseLine,
] ]
) . ) .
@ -791,8 +774,7 @@ class Font extends Supervisor
$this->exportArray2($exportedArray, 'subscript', $this->getSubscript()); $this->exportArray2($exportedArray, 'subscript', $this->getSubscript());
$this->exportArray2($exportedArray, 'superscript', $this->getSuperscript()); $this->exportArray2($exportedArray, 'superscript', $this->getSuperscript());
$this->exportArray2($exportedArray, 'underline', $this->getUnderline()); $this->exportArray2($exportedArray, 'underline', $this->getUnderline());
$this->exportArray2($exportedArray, 'uSchemeClr', $this->getUSchemeClr()); $this->exportArray2($exportedArray, 'underlineColor', $this->getUnderlineColor());
$this->exportArray2($exportedArray, 'uSrgbClr', $this->getUSrgbClr());
return $exportedArray; return $exportedArray;
} }

View File

@ -3,6 +3,7 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx; namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Chart\Axis; use PhpOffice\PhpSpreadsheet\Chart\Axis;
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries; use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues; use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
use PhpOffice\PhpSpreadsheet\Chart\GridLines; use PhpOffice\PhpSpreadsheet\Chart\GridLines;
@ -517,19 +518,8 @@ class Chart extends WriterPart
} }
$objWriter->startElement('c:spPr'); $objWriter->startElement('c:spPr');
if (!empty($yAxis->getFillProperty('value'))) { $this->writeColor($objWriter, $yAxis->getFillColorObject());
$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();
}
$objWriter->startElement('a:effectLst'); $objWriter->startElement('a:effectLst');
$this->writeGlow($objWriter, $yAxis); $this->writeGlow($objWriter, $yAxis);
$this->writeShadow($objWriter, $yAxis); $this->writeShadow($objWriter, $yAxis);
@ -723,19 +713,7 @@ class Chart extends WriterPart
$objWriter->startElement('c:spPr'); $objWriter->startElement('c:spPr');
if (!empty($xAxis->getFillProperty('value'))) { $this->writeColor($objWriter, $xAxis->getFillColorObject());
$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->writeGridlinesLn($objWriter, $xAxis); $this->writeGridlinesLn($objWriter, $xAxis);
@ -1472,8 +1450,9 @@ class Chart extends WriterPart
if (is_numeric($xAxis->getShadowProperty('direction'))) { if (is_numeric($xAxis->getShadowProperty('direction'))) {
$objWriter->writeAttribute('dir', Properties::angleToXml((float) $xAxis->getShadowProperty('direction'))); $objWriter->writeAttribute('dir', Properties::angleToXml((float) $xAxis->getShadowProperty('direction')));
} }
if ($xAxis->getShadowProperty('algn') !== null) { $algn = $xAxis->getShadowProperty('algn');
$objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn')); if (is_string($algn) && $algn !== '') {
$objWriter->writeAttribute('algn', $algn);
} }
foreach (['sx', 'sy'] as $sizeType) { foreach (['sx', 'sy'] as $sizeType) {
$sizeValue = $xAxis->getShadowProperty(['size', $sizeType]); $sizeValue = $xAxis->getShadowProperty(['size', $sizeType]);
@ -1487,19 +1466,12 @@ class Chart extends WriterPart
$objWriter->writeAttribute($sizeType, Properties::angleToXml((float) $sizeValue)); $objWriter->writeAttribute($sizeType, Properties::angleToXml((float) $sizeValue));
} }
} }
if ($xAxis->getShadowProperty('rotWithShape') !== null) { $rotWithShape = $xAxis->getShadowProperty('rotWithShape');
$objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape')); if (is_numeric($rotWithShape)) {
$objWriter->writeAttribute('rotWithShape', (string) (int) $rotWithShape);
} }
$objWriter->startElement("a:{$xAxis->getShadowProperty(['color', 'type'])}"); $this->writeColor($objWriter, $xAxis->getShadowColorObject(), false);
$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();
$objWriter->endElement(); $objWriter->endElement();
} }
@ -1517,15 +1489,7 @@ class Chart extends WriterPart
} }
$objWriter->startElement('a:glow'); $objWriter->startElement('a:glow');
$objWriter->writeAttribute('rad', Properties::pointsToXml((float) $size)); $objWriter->writeAttribute('rad', Properties::pointsToXml((float) $size));
$objWriter->startElement("a:{$yAxis->getGlowProperty(['color', 'type'])}"); $this->writeColor($objWriter, $yAxis->getGlowColorObject(), false);
$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
$objWriter->endElement(); // glow $objWriter->endElement(); // glow
} }
@ -1559,19 +1523,7 @@ class Chart extends WriterPart
} }
$this->writeNotEmpty($objWriter, 'cap', $gridlines->getLineStyleProperty('cap')); $this->writeNotEmpty($objWriter, 'cap', $gridlines->getLineStyleProperty('cap'));
$this->writeNotEmpty($objWriter, 'cmpd', $gridlines->getLineStyleProperty('compound')); $this->writeNotEmpty($objWriter, 'cmpd', $gridlines->getLineStyleProperty('compound'));
if (!empty($gridlines->getLineColorProperty('value'))) { $this->writeColor($objWriter, $gridlines->getLineColor());
$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
}
$dash = $gridlines->getLineStyleProperty('dash'); $dash = $gridlines->getLineStyleProperty('dash');
if (!empty($dash)) { if (!empty($dash)) {
@ -1613,4 +1565,27 @@ class Chart extends WriterPart
$objWriter->writeAttribute($name, $value); $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
}
}
}
} }

View File

@ -256,15 +256,20 @@ class StringTable extends WriterPart
$objWriter->endElement(); // solidFill $objWriter->endElement(); // solidFill
// Underscore Color // Underscore Color
if ($element->getFont()->getUSchemeClr()) { $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 . 'uFill');
$objWriter->startElement($prefix . 'solidFill'); $objWriter->startElement($prefix . 'solidFill');
$objWriter->startElement($prefix . 'schemeClr'); $objWriter->startElement($prefix . $type);
$objWriter->writeAttribute('val', $element->getFont()->getUSchemeClr()); $objWriter->writeAttribute('val', $value);
$objWriter->endElement(); // schemeClr $objWriter->endElement(); // schemeClr
$objWriter->endElement(); // solidFill $objWriter->endElement(); // solidFill
$objWriter->endElement(); // uFill $objWriter->endElement(); // uFill
} }
}
// fontName // fontName
if ($element->getFont()->getLatin()) { if ($element->getFont()->getLatin()) {