Add Support to Chart/Axis and Gridlines for Shadow (#2872)

* Add Support to Chart/Axis and Gridlines for Shadow

Continuing the work from #2865. Support is added for Shadow properties for Axis and Gridlines, and Glow and SoftEdges are extended to Gridlines. Tests are added. Some chart tests are moved from Reader/Xlsx and Writer/Xlsx so that most chart tests are under a single directory.

This is a minor breaking change. Since the support for these properties was just added, it can't really affect much in userland. Some properties had been stored in the form which the XML requires them rather than as the user would enter them to Excel. So, for example, setting the Glow size to 10 points would have caused it to be stored internally as 127,000. This change will store the size internally as 10, obviously making the appropriate conversion when reading from or writing to XML. This makes unit tests much simpler, and I think this is also what a user would expect, especially considering the difficulties in keeping track of the trailing zeros.

* More Tests

Confirm value change between internal and xml.

* Still More Tests

Add a little more coverage, and use a neat trick suggested by @MarkBaker in the discussion of PR #2724 to greatly simplify MultiplierTest.
This commit is contained in:
oleibman 2022-06-09 18:08:56 -07:00 committed by GitHub
parent 1f1fc360af
commit 4f22b39b89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1285 additions and 538 deletions

View File

@ -1170,21 +1170,11 @@ parameters:
count: 2
path: src/PhpSpreadsheet/Chart/DataSeries.php
-
message: "#^Parameter \\#1 \\$angle of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setShadowAngle\\(\\) expects int, int\\|null given\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/GridLines.php
-
message: "#^Parameter \\#1 \\$color of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setGlowColor\\(\\) expects string, string\\|null given\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/GridLines.php
-
message: "#^Parameter \\#1 \\$distance of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setShadowDistance\\(\\) expects float, float\\|null given\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/GridLines.php
-
message: "#^Parameter \\#2 \\$alpha of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setGlowColor\\(\\) expects int, int\\|null given\\.$#"
count: 1
@ -1275,36 +1265,6 @@ parameters:
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getTrueAlpha\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getTrueAlpha\\(\\) has parameter \\$alpha with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:setColorProperties\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:setColorProperties\\(\\) has parameter \\$alpha with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:setColorProperties\\(\\) has parameter \\$color with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:setColorProperties\\(\\) has parameter \\$colorType with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:formatDataSetLabels\\(\\) has no return type specified\\.$#"
count: 1
@ -4477,12 +4437,12 @@ parameters:
-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, array\\|int\\|string given\\.$#"
count: 8
count: 2
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, array\\|int\\|string\\|null given\\.$#"
count: 2
count: 1
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
@ -4525,11 +4485,6 @@ parameters:
count: 2
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Part \\$xAxis\\-\\>getShadowProperty\\('effect'\\) \\(array\\|int\\|string\\|null\\) of encapsed string cannot be cast to string\\.$#"
count: 1
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Part \\$xAxis\\-\\>getShadowProperty\\(\\['color', 'type'\\]\\) \\(array\\|int\\|string\\|null\\) of encapsed string cannot be cast to string\\.$#"
count: 1

View File

@ -89,25 +89,7 @@ class Axis extends Properties
*
* @var mixed[]
*/
private $shadowProperties = [
'presets' => self::SHADOW_PRESETS_NOSHADOW,
'effect' => null,
'color' => [
'type' => self::EXCEL_COLOR_TYPE_STANDARD,
'value' => 'black',
'alpha' => 40,
],
'size' => [
'sx' => null,
'sy' => null,
'kx' => null,
],
'blur' => null,
'direction' => null,
'distance' => null,
'algn' => null,
'rotWithShape' => null,
];
private $shadowProperties = Properties::PRESETS_OPTIONS[0];
/**
* Glow Properties.
@ -340,6 +322,20 @@ class Axis extends Properties
return $this->getLineStyleArrowSize($this->lineStyleProperties['arrow'][$arrow]['size'], 'len');
}
/**
* @param mixed $value
*/
public function setShadowProperty(string $propertyName, $value): self
{
if ($propertyName === 'color' && is_array($value)) {
$this->setShadowColor($value['value'], $value['alpha'], $value['type']);
} else {
$this->shadowProperties[$propertyName] = $value;
}
return $this;
}
/**
* Set Shadow Properties.
*
@ -379,6 +375,8 @@ class Axis extends Properties
return $this;
}
private const SHADOW_ARRAY_KEYS = ['size', 'color'];
/**
* Set Shadow Properties from Mapped Values.
*
@ -391,12 +389,10 @@ class Axis extends Properties
$base_reference = $reference;
foreach ($propertiesMap as $property_key => $property_val) {
if (is_array($property_val)) {
if ($reference === null) {
if (in_array($property_key, self::SHADOW_ARRAY_KEYS, true)) {
$reference = &$this->shadowProperties[$property_key];
} else {
$reference = &$reference[$property_key];
$this->setShadowPropertiesMapValues($property_val, $reference);
}
$this->setShadowPropertiesMapValues($property_val, $reference);
} else {
if ($base_reference === null) {
$this->shadowProperties[$property_key] = $property_val;
@ -435,7 +431,7 @@ class Axis extends Properties
private function setShadowBlur($blur)
{
if ($blur !== null) {
$this->shadowProperties['blur'] = (string) $this->getExcelPointsWidth($blur);
$this->shadowProperties['blur'] = $blur;
}
return $this;
@ -444,14 +440,14 @@ class Axis extends Properties
/**
* Set Shadow Angle.
*
* @param null|int $angle
* @param null|float|int $angle
*
* @return $this
*/
private function setShadowAngle($angle)
{
if ($angle !== null) {
$this->shadowProperties['direction'] = (string) $this->getExcelPointsAngle($angle);
if (is_numeric($angle)) {
$this->shadowProperties['direction'] = $angle;
}
return $this;
@ -467,7 +463,7 @@ class Axis extends Properties
private function setShadowDistance($distance)
{
if ($distance !== null) {
$this->shadowProperties['distance'] = (string) $this->getExcelPointsWidth($distance);
$this->shadowProperties['distance'] = $distance;
}
return $this;
@ -525,7 +521,7 @@ class Axis extends Properties
private function setGlowSize($size)
{
if ($size !== null) {
$this->glowProperties['size'] = $this->getExcelPointsWidth($size);
$this->glowProperties['size'] = $size;
}
return $this;
@ -555,7 +551,7 @@ class Axis extends Properties
public function setSoftEdges($size): void
{
if ($size !== null) {
$this->softEdges['size'] = (string) $this->getExcelPointsWidth($size);
$this->softEdges['size'] = $size;
}
}

View File

@ -45,25 +45,7 @@ class GridLines extends Properties
],
];
private $shadowProperties = [
'presets' => self::SHADOW_PRESETS_NOSHADOW,
'effect' => null,
'color' => [
'type' => self::EXCEL_COLOR_TYPE_STANDARD,
'value' => 'black',
'alpha' => 85,
],
'size' => [
'sx' => null,
'sy' => null,
'kx' => null,
],
'blur' => null,
'direction' => null,
'distance' => null,
'algn' => null,
'rotWithShape' => null,
];
private $shadowProperties = Properties::PRESETS_OPTIONS[0];
private $glowProperties = [
'size' => null,
@ -202,6 +184,18 @@ class GridLines extends Properties
->setGlowColor($colorValue, $colorAlpha, $colorType);
}
/**
* Get Glow Property.
*
* @param array|string $property
*
* @return null|string
*/
public function getGlowProperty($property)
{
return $this->getArrayElementsValue($this->glowProperties, $property);
}
/**
* Get Glow Color Property.
*
@ -233,7 +227,7 @@ class GridLines extends Properties
*/
private function setGlowSize($size)
{
$this->glowProperties['size'] = $this->getExcelPointsWidth((float) $size);
$this->glowProperties['size'] = $size;
return $this;
}
@ -253,7 +247,7 @@ class GridLines extends Properties
$this->glowProperties['color']['value'] = (string) $color;
}
if ($alpha !== null) {
$this->glowProperties['color']['alpha'] = $this->getTrueAlpha((int) $alpha);
$this->glowProperties['color']['alpha'] = (int) $alpha;
}
if ($colorType !== null) {
$this->glowProperties['color']['type'] = (string) $colorType;
@ -275,16 +269,27 @@ class GridLines extends Properties
return $this->getLineStyleArrowSize($this->lineProperties['style']['arrow'][$arrowSelector]['size'], $propertySelector);
}
/**
* @param mixed $value
*/
public function setShadowProperty(string $propertyName, $value): self
{
$this->activateObject();
$this->shadowProperties[$propertyName] = $value;
return $this;
}
/**
* Set Shadow Properties.
*
* @param int $presets
* @param string $colorValue
* @param string $colorType
* @param string $colorAlpha
* @param string $blur
* @param int $angle
* @param float $distance
* @param null|float|int|string $colorAlpha
* @param null|float $blur
* @param null|int $angle
* @param null|float $distance
*/
public function setShadowProperties($presets, $colorValue = null, $colorType = null, $colorAlpha = null, $blur = null, $angle = null, $distance = null): void
{
@ -292,10 +297,10 @@ class GridLines extends Properties
->setShadowPresetsProperties((int) $presets)
->setShadowColor(
$colorValue ?? $this->shadowProperties['color']['value'],
$colorAlpha === null ? (int) $this->shadowProperties['color']['alpha'] : $this->getTrueAlpha($colorAlpha),
$colorAlpha === null ? (int) $this->shadowProperties['color']['alpha'] : (int) $colorAlpha,
$colorType ?? $this->shadowProperties['color']['type']
)
->setShadowBlur((float) $blur)
->setShadowBlur($blur)
->setShadowAngle($angle)
->setShadowDistance($distance);
}
@ -315,6 +320,8 @@ class GridLines extends Properties
return $this;
}
private const SHADOW_ARRAY_KEYS = ['size', 'color'];
/**
* Set Shadow Properties Values.
*
@ -327,12 +334,10 @@ class GridLines extends Properties
$base_reference = $reference;
foreach ($propertiesMap as $property_key => $property_val) {
if (is_array($property_val)) {
if ($reference === null) {
if (in_array($property_key, self::SHADOW_ARRAY_KEYS, true)) {
$reference = &$this->shadowProperties[$property_key];
} else {
$reference = &$reference[$property_key];
$this->setShadowPropertiesMapValues($property_val, $reference);
}
$this->setShadowPropertiesMapValues($property_val, $reference);
} else {
if ($base_reference === null) {
$this->shadowProperties[$property_key] = $property_val;
@ -360,7 +365,7 @@ class GridLines extends Properties
$this->shadowProperties['color']['value'] = (string) $color;
}
if ($alpha !== null) {
$this->shadowProperties['color']['alpha'] = $this->getTrueAlpha((int) $alpha);
$this->shadowProperties['color']['alpha'] = (int) $alpha;
}
if ($colorType !== null) {
$this->shadowProperties['color']['type'] = (string) $colorType;
@ -372,14 +377,14 @@ class GridLines extends Properties
/**
* Set Shadow Blur.
*
* @param float $blur
* @param ?float $blur
*
* @return $this
*/
private function setShadowBlur($blur)
{
if ($blur !== null) {
$this->shadowProperties['blur'] = (string) $this->getExcelPointsWidth($blur);
$this->shadowProperties['blur'] = $blur;
}
return $this;
@ -388,14 +393,14 @@ class GridLines extends Properties
/**
* Set Shadow Angle.
*
* @param int $angle
* @param null|float|int|string $angle
*
* @return $this
*/
private function setShadowAngle($angle)
{
if ($angle !== null) {
$this->shadowProperties['direction'] = (string) $this->getExcelPointsAngle($angle);
if (is_numeric($angle)) {
$this->shadowProperties['direction'] = $angle;
}
return $this;
@ -404,14 +409,14 @@ class GridLines extends Properties
/**
* Set Shadow Distance.
*
* @param float $distance
* @param ?float $distance
*
* @return $this
*/
private function setShadowDistance($distance)
{
if ($distance !== null) {
$this->shadowProperties['distance'] = (string) $this->getExcelPointsWidth($distance);
$this->shadowProperties['distance'] = $distance;
}
return $this;
@ -434,11 +439,11 @@ class GridLines extends Properties
*
* @param float $size
*/
public function setSoftEdgesSize($size): void
public function setSoftEdges($size): void
{
if ($size !== null) {
$this->activateObject();
$this->softEdges['size'] = (string) $this->getExcelPointsWidth($size);
$this->softEdges['size'] = $size;
}
}

View File

@ -110,7 +110,10 @@ abstract class Properties
const SHADOW_PRESETS_PERSPECTIVE_UPPER_LEFT = 21;
const SHADOW_PRESETS_PERSPECTIVE_LOWER_RIGHT = 22;
const SHADOW_PRESETS_PERSPECTIVE_LOWER_LEFT = 23;
const POINTS_WIDTH_MULTIPLIER = 12700;
const ANGLE_MULTIPLIER = 60000; // direction and size-kx size-ky
const PERCENTAGE_MULTIPLIER = 100000; // size sx and sy
/**
* @param float $width
@ -122,27 +125,58 @@ abstract class Properties
return $width * self::POINTS_WIDTH_MULTIPLIER;
}
/**
* @param float $angle
*
* @return float
*/
protected function getExcelPointsAngle($angle)
public static function pointsToXml(float $width): string
{
return $angle * 60000;
return (string) (int) ($width * self::POINTS_WIDTH_MULTIPLIER);
}
protected function getTrueAlpha($alpha)
public static function xmlToPoints(string $width): float
{
return ((float) $width) / self::POINTS_WIDTH_MULTIPLIER;
}
public static function angleToXml(float $angle): string
{
return (string) (int) ($angle * self::ANGLE_MULTIPLIER);
}
public static function xmlToAngle(string $angle): float
{
return ((float) $angle) / self::ANGLE_MULTIPLIER;
}
public static function tenthOfPercentToXml(float $value): string
{
return (string) (int) ($value * self::PERCENTAGE_MULTIPLIER);
}
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';
}
protected function setColorProperties($color, $alpha, $colorType)
/**
* @param float|int|string $alpha
*/
public static function alphaFromXml($alpha): int
{
return 100 - ((int) $alpha / 1000);
}
/**
* @param null|float|int|string $alpha
*/
protected function setColorProperties(?string $color, $alpha, ?string $colorType): array
{
return [
'type' => (string) $colorType,
'value' => (string) $color,
'alpha' => (string) $this->getTrueAlpha($alpha),
'type' => $colorType,
'value' => $color,
'alpha' => (int) $alpha,
];
}
@ -163,196 +197,217 @@ abstract class Properties
return $sizes[$arraySelector][$arrayKaySelector];
}
protected const PRESETS_OPTIONS = [
//NONE
0 => [
'presets' => self::SHADOW_PRESETS_NOSHADOW,
'effect' => null,
'color' => [
'type' => self::EXCEL_COLOR_TYPE_STANDARD,
'value' => 'black',
'alpha' => 40,
],
'size' => [
'sx' => null,
'sy' => null,
'kx' => null,
'ky' => null,
],
'blur' => null,
'direction' => null,
'distance' => null,
'algn' => null,
'rotWithShape' => null,
],
//OUTER
1 => [
'effect' => 'outerShdw',
'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 2700000 / self::ANGLE_MULTIPLIER,
'algn' => 'tl',
'rotWithShape' => '0',
],
2 => [
'effect' => 'outerShdw',
'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 5400000 / self::ANGLE_MULTIPLIER,
'algn' => 't',
'rotWithShape' => '0',
],
3 => [
'effect' => 'outerShdw',
'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 8100000 / self::ANGLE_MULTIPLIER,
'algn' => 'tr',
'rotWithShape' => '0',
],
4 => [
'effect' => 'outerShdw',
'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
'algn' => 'l',
'rotWithShape' => '0',
],
5 => [
'effect' => 'outerShdw',
'size' => [
'sx' => 102000 / self::PERCENTAGE_MULTIPLIER,
'sy' => 102000 / self::PERCENTAGE_MULTIPLIER,
],
'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
'algn' => 'ctr',
'rotWithShape' => '0',
],
6 => [
'effect' => 'outerShdw',
'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 10800000 / self::ANGLE_MULTIPLIER,
'algn' => 'r',
'rotWithShape' => '0',
],
7 => [
'effect' => 'outerShdw',
'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 18900000 / self::ANGLE_MULTIPLIER,
'algn' => 'bl',
'rotWithShape' => '0',
],
8 => [
'effect' => 'outerShdw',
'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 16200000 / self::ANGLE_MULTIPLIER,
'rotWithShape' => '0',
],
9 => [
'effect' => 'outerShdw',
'blur' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 38100 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 13500000 / self::ANGLE_MULTIPLIER,
'algn' => 'br',
'rotWithShape' => '0',
],
//INNER
10 => [
'effect' => 'innerShdw',
'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 2700000 / self::ANGLE_MULTIPLIER,
],
11 => [
'effect' => 'innerShdw',
'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 5400000 / self::ANGLE_MULTIPLIER,
],
12 => [
'effect' => 'innerShdw',
'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 8100000 / self::ANGLE_MULTIPLIER,
],
13 => [
'effect' => 'innerShdw',
'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
],
14 => [
'effect' => 'innerShdw',
'blur' => 114300 / self::POINTS_WIDTH_MULTIPLIER,
],
15 => [
'effect' => 'innerShdw',
'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 10800000 / self::ANGLE_MULTIPLIER,
],
16 => [
'effect' => 'innerShdw',
'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 18900000 / self::ANGLE_MULTIPLIER,
],
17 => [
'effect' => 'innerShdw',
'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 16200000 / self::ANGLE_MULTIPLIER,
],
18 => [
'effect' => 'innerShdw',
'blur' => 63500 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 50800 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 13500000 / self::ANGLE_MULTIPLIER,
],
//perspective
19 => [
'effect' => 'outerShdw',
'blur' => 152400 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 317500 / self::POINTS_WIDTH_MULTIPLIER,
'size' => [
'sx' => 90000 / self::PERCENTAGE_MULTIPLIER,
'sy' => -19000 / self::PERCENTAGE_MULTIPLIER,
],
'direction' => 5400000 / self::ANGLE_MULTIPLIER,
'rotWithShape' => '0',
],
20 => [
'effect' => 'outerShdw',
'blur' => 76200 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 18900000 / self::ANGLE_MULTIPLIER,
'size' => [
'sy' => 23000 / self::PERCENTAGE_MULTIPLIER,
'kx' => -1200000 / self::ANGLE_MULTIPLIER,
],
'algn' => 'bl',
'rotWithShape' => '0',
],
21 => [
'effect' => 'outerShdw',
'blur' => 76200 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 13500000 / self::ANGLE_MULTIPLIER,
'size' => [
'sy' => 23000 / self::PERCENTAGE_MULTIPLIER,
'kx' => 1200000 / self::ANGLE_MULTIPLIER,
],
'algn' => 'br',
'rotWithShape' => '0',
],
22 => [
'effect' => 'outerShdw',
'blur' => 76200 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 12700 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 2700000 / self::ANGLE_MULTIPLIER,
'size' => [
'sy' => -23000 / self::PERCENTAGE_MULTIPLIER,
'kx' => -800400 / self::ANGLE_MULTIPLIER,
],
'algn' => 'bl',
'rotWithShape' => '0',
],
23 => [
'effect' => 'outerShdw',
'blur' => 76200 / self::POINTS_WIDTH_MULTIPLIER,
'distance' => 12700 / self::POINTS_WIDTH_MULTIPLIER,
'direction' => 8100000 / self::ANGLE_MULTIPLIER,
'size' => [
'sy' => -23000 / self::PERCENTAGE_MULTIPLIER,
'kx' => 800400 / self::ANGLE_MULTIPLIER,
],
'algn' => 'br',
'rotWithShape' => '0',
],
];
protected function getShadowPresetsMap($presetsOption)
{
$presets_options = [
//OUTER
1 => [
'effect' => 'outerShdw',
'blur' => '50800',
'distance' => '38100',
'direction' => '2700000',
'algn' => 'tl',
'rotWithShape' => '0',
],
2 => [
'effect' => 'outerShdw',
'blur' => '50800',
'distance' => '38100',
'direction' => '5400000',
'algn' => 't',
'rotWithShape' => '0',
],
3 => [
'effect' => 'outerShdw',
'blur' => '50800',
'distance' => '38100',
'direction' => '8100000',
'algn' => 'tr',
'rotWithShape' => '0',
],
4 => [
'effect' => 'outerShdw',
'blur' => '50800',
'distance' => '38100',
'algn' => 'l',
'rotWithShape' => '0',
],
5 => [
'effect' => 'outerShdw',
'size' => [
'sx' => '102000',
'sy' => '102000',
],
'blur' => '63500',
'distance' => '38100',
'algn' => 'ctr',
'rotWithShape' => '0',
],
6 => [
'effect' => 'outerShdw',
'blur' => '50800',
'distance' => '38100',
'direction' => '10800000',
'algn' => 'r',
'rotWithShape' => '0',
],
7 => [
'effect' => 'outerShdw',
'blur' => '50800',
'distance' => '38100',
'direction' => '18900000',
'algn' => 'bl',
'rotWithShape' => '0',
],
8 => [
'effect' => 'outerShdw',
'blur' => '50800',
'distance' => '38100',
'direction' => '16200000',
'rotWithShape' => '0',
],
9 => [
'effect' => 'outerShdw',
'blur' => '50800',
'distance' => '38100',
'direction' => '13500000',
'algn' => 'br',
'rotWithShape' => '0',
],
//INNER
10 => [
'effect' => 'innerShdw',
'blur' => '63500',
'distance' => '50800',
'direction' => '2700000',
],
11 => [
'effect' => 'innerShdw',
'blur' => '63500',
'distance' => '50800',
'direction' => '5400000',
],
12 => [
'effect' => 'innerShdw',
'blur' => '63500',
'distance' => '50800',
'direction' => '8100000',
],
13 => [
'effect' => 'innerShdw',
'blur' => '63500',
'distance' => '50800',
],
14 => [
'effect' => 'innerShdw',
'blur' => '114300',
],
15 => [
'effect' => 'innerShdw',
'blur' => '63500',
'distance' => '50800',
'direction' => '10800000',
],
16 => [
'effect' => 'innerShdw',
'blur' => '63500',
'distance' => '50800',
'direction' => '18900000',
],
17 => [
'effect' => 'innerShdw',
'blur' => '63500',
'distance' => '50800',
'direction' => '16200000',
],
18 => [
'effect' => 'innerShdw',
'blur' => '63500',
'distance' => '50800',
'direction' => '13500000',
],
//perspective
19 => [
'effect' => 'outerShdw',
'blur' => '152400',
'distance' => '317500',
'size' => [
'sx' => '90000',
'sy' => '-19000',
],
'direction' => '5400000',
'rotWithShape' => '0',
],
20 => [
'effect' => 'outerShdw',
'blur' => '76200',
'direction' => '18900000',
'size' => [
'sy' => '23000',
'kx' => '-1200000',
],
'algn' => 'bl',
'rotWithShape' => '0',
],
21 => [
'effect' => 'outerShdw',
'blur' => '76200',
'direction' => '13500000',
'size' => [
'sy' => '23000',
'kx' => '1200000',
],
'algn' => 'br',
'rotWithShape' => '0',
],
22 => [
'effect' => 'outerShdw',
'blur' => '76200',
'distance' => '12700',
'direction' => '2700000',
'size' => [
'sy' => '-23000',
'kx' => '-800400',
],
'algn' => 'bl',
'rotWithShape' => '0',
],
23 => [
'effect' => 'outerShdw',
'blur' => '76200',
'distance' => '12700',
'direction' => '8100000',
'size' => [
'sy' => '-23000',
'kx' => '800400',
],
'algn' => 'br',
'rotWithShape' => '0',
],
];
return $presets_options[$presetsOption];
return self::PRESETS_OPTIONS[$presetsOption] ?? self::PRESETS_OPTIONS[0];
}
protected function getArrayElementsValue($properties, $elements)

View File

@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
use PhpOffice\PhpSpreadsheet\Chart\Axis;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
use PhpOffice\PhpSpreadsheet\Chart\GridLines;
use PhpOffice\PhpSpreadsheet\Chart\Layout;
use PhpOffice\PhpSpreadsheet\Chart\Legend;
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
@ -71,6 +72,7 @@ class Chart
$rotX = $rotY = $rAngAx = $perspective = null;
$xAxis = new Axis();
$yAxis = new Axis();
$majorGridlines = $minorGridlines = null;
foreach ($chartElementsC as $chartElementKey => $chartElement) {
switch ($chartElementKey) {
case 'chart':
@ -108,26 +110,52 @@ class Chart
break;
case 'valAx':
$whichAxis = null;
if (isset($chartDetail->title, $chartDetail->axPos)) {
$axisLabel = $this->chartTitle($chartDetail->title->children($this->cNamespace));
$axPos = null;
if (isset($chartDetail->axPos)) {
$axPos = self::getAttribute($chartDetail->axPos, 'val', 'string');
switch ($axPos) {
case 't':
case 'b':
$XaxisLabel = $axisLabel;
$whichAxis = $xAxis;
break;
case 'r':
case 'l':
$YaxisLabel = $axisLabel;
$whichAxis = $yAxis;
break;
}
}
if (isset($chartDetail->title)) {
$axisLabel = $this->chartTitle($chartDetail->title->children($this->cNamespace));
switch ($axPos) {
case 't':
case 'b':
$XaxisLabel = $axisLabel;
break;
case 'r':
case 'l':
$YaxisLabel = $axisLabel;
break;
}
}
$this->readEffects($chartDetail, $whichAxis);
if (isset($chartDetail->majorGridlines)) {
$majorGridlines = new GridLines();
if (isset($chartDetail->majorGridlines->spPr)) {
$this->readEffects($chartDetail->majorGridlines, $majorGridlines);
}
}
if (isset($chartDetail->minorGridlines)) {
$minorGridlines = new GridLines();
if (isset($chartDetail->minorGridlines->spPr)) {
$this->readEffects($chartDetail->minorGridlines, $minorGridlines);
}
}
break;
case 'barChart':
@ -249,7 +277,7 @@ class Chart
}
}
}
$chart = new \PhpOffice\PhpSpreadsheet\Chart\Chart($chartName, $title, $legend, $plotArea, $plotVisOnly, (string) $dispBlanksAs, $XaxisLabel, $YaxisLabel, $xAxis, $yAxis);
$chart = new \PhpOffice\PhpSpreadsheet\Chart\Chart($chartName, $title, $legend, $plotArea, $plotVisOnly, (string) $dispBlanksAs, $XaxisLabel, $YaxisLabel, $xAxis, $yAxis, $majorGridlines, $minorGridlines);
if (is_int($rotX)) {
$chart->setRotX($rotX);
}
@ -893,7 +921,7 @@ class Chart
}
/**
* @param null|Axis $chartObject may be extended to include other types
* @param null|Axis|GridLines $chartObject may be extended to include other types
*/
private function readEffects(SimpleXMLElement $chartDetail, $chartObject): void
{
@ -905,18 +933,75 @@ class Chart
if (isset($sppr->effectLst->glow)) {
$axisGlowSize = (float) self::getAttribute($sppr->effectLst->glow, 'rad', 'integer') / Properties::POINTS_WIDTH_MULTIPLIER;
if ($axisGlowSize != 0.0) {
$srgbClr = $schemeClr = '';
$colorArray = $this->readColor($sppr->effectLst->glow, $srgbClr, $schemeClr);
$colorArray = $this->readColor($sppr->effectLst->glow);
$chartObject->setGlowProperties($axisGlowSize, $colorArray['value'], $colorArray['alpha'], $colorArray['type']);
}
}
if (isset($sppr->effectLst->softEdge)) {
$chartObject->setSoftEdges((float) self::getAttribute($sppr->effectLst->softEdge, 'rad', 'string') / Properties::POINTS_WIDTH_MULTIPLIER);
/** @var string */
$softEdgeSize = self::getAttribute($sppr->effectLst->softEdge, 'rad', 'string');
if (is_numeric($softEdgeSize)) {
$chartObject->setSoftEdges((float) Properties::xmlToPoints($softEdgeSize));
}
}
$type = '';
foreach (self::SHADOW_TYPES as $shadowType) {
if (isset($sppr->effectLst->$shadowType)) {
$type = $shadowType;
break;
}
}
if ($type !== '') {
/** @var string */
$blur = self::getAttribute($sppr->effectLst->$type, 'blurRad', 'string');
$blur = is_numeric($blur) ? Properties::xmlToPoints($blur) : null;
/** @var string */
$dist = self::getAttribute($sppr->effectLst->$type, 'dist', 'string');
$dist = is_numeric($dist) ? Properties::xmlToPoints($dist) : null;
/** @var string */
$direction = self::getAttribute($sppr->effectLst->$type, 'dir', 'string');
$direction = is_numeric($direction) ? Properties::xmlToAngle($direction) : null;
$algn = self::getAttribute($sppr->effectLst->$type, 'algn', 'string');
$rot = self::getAttribute($sppr->effectLst->$type, 'rotWithShape', 'string');
$size = [];
foreach (['sx', 'sy'] as $sizeType) {
$sizeValue = self::getAttribute($sppr->effectLst->$type, $sizeType, 'string');
if (is_numeric($sizeValue)) {
$size[$sizeType] = Properties::xmlToTenthOfPercent((string) $sizeValue);
} else {
$size[$sizeType] = null;
}
}
foreach (['kx', 'ky'] as $sizeType) {
$sizeValue = self::getAttribute($sppr->effectLst->$type, $sizeType, 'string');
if (is_numeric($sizeValue)) {
$size[$sizeType] = Properties::xmlToAngle((string) $sizeValue);
} else {
$size[$sizeType] = null;
}
}
$colorArray = $this->readColor($sppr->effectLst->$type);
$chartObject
->setShadowProperty('effect', $type)
->setShadowProperty('blur', $blur)
->setShadowProperty('direction', $direction)
->setShadowProperty('distance', $dist)
->setShadowProperty('algn', $algn)
->setShadowProperty('rotWithShape', $rot)
->setShadowProperty('size', $size)
->setShadowProperty('color', $colorArray);
}
}
private function readColor(SimpleXMLElement $colorXml, ?string &$srgbClr, ?string &$schemeClr): array
private const SHADOW_TYPES = [
'outerShdw',
'innerShdw',
];
private function readColor(SimpleXMLElement $colorXml, ?string &$srgbClr = null, ?string &$schemeClr = null): array
{
$result = [
'type' => null,
@ -927,16 +1012,27 @@ class Chart
$result['type'] = Properties::EXCEL_COLOR_TYPE_ARGB;
$result['value'] = $srgbClr = self::getAttribute($colorXml->srgbClr, 'val', 'string');
if (isset($colorXml->srgbClr->alpha)) {
$alpha = (int) self::getAttribute($colorXml->srgbClr->alpha, 'val', 'string');
$alpha = 100 - (int) ($alpha / 1000);
/** @var string */
$alpha = self::getAttribute($colorXml->srgbClr->alpha, 'val', 'string');
$alpha = Properties::alphaFromXml($alpha);
$result['alpha'] = $alpha;
}
} elseif (isset($colorXml->schemeClr)) {
$result['type'] = Properties::EXCEL_COLOR_TYPE_SCHEME;
$result['value'] = $schemeClr = self::getAttribute($colorXml->schemeClr, 'val', 'string');
if (isset($colorXml->schemeClr->alpha)) {
$alpha = (int) self::getAttribute($colorXml->schemeClr->alpha, 'val', 'string');
$alpha = 100 - (int) ($alpha / 1000);
/** @var string */
$alpha = self::getAttribute($colorXml->schemeClr->alpha, 'val', 'string');
$alpha = Properties::alphaFromXml($alpha);
$result['alpha'] = $alpha;
}
} elseif (isset($colorXml->prstClr)) {
$result['type'] = Properties::EXCEL_COLOR_TYPE_STANDARD;
$result['value'] = self::getAttribute($colorXml->prstClr, 'val', 'string');
if (isset($colorXml->prstClr->alpha)) {
/** @var string */
$alpha = self::getAttribute($colorXml->prstClr->alpha, 'val', 'string');
$alpha = Properties::alphaFromXml($alpha);
$result['alpha'] = $alpha;
}
}

View File

@ -9,6 +9,7 @@ use PhpOffice\PhpSpreadsheet\Chart\GridLines;
use PhpOffice\PhpSpreadsheet\Chart\Layout;
use PhpOffice\PhpSpreadsheet\Chart\Legend;
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
use PhpOffice\PhpSpreadsheet\Chart\Properties;
use PhpOffice\PhpSpreadsheet\Chart\Title;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
@ -499,22 +500,9 @@ class Chart extends WriterPart
$objWriter->startElement('c:spPr');
$objWriter->startElement('a:effectLst');
if ($yAxis->getGlowProperty('size') !== null) {
$objWriter->startElement('a:glow');
$objWriter->writeAttribute('rad', $yAxis->getGlowProperty('size'));
$objWriter->startElement("a:{$yAxis->getGlowProperty(['color', 'type'])}");
$objWriter->writeAttribute('val', (string) $yAxis->getGlowProperty(['color', 'value']));
$objWriter->startElement('a:alpha');
$objWriter->writeAttribute('val', (string) $yAxis->getGlowProperty(['color', 'alpha']));
$objWriter->endElement();
$objWriter->endElement();
$objWriter->endElement();
}
if ($yAxis->getSoftEdgesSize() !== null) {
$objWriter->startElement('a:softEdge');
$objWriter->writeAttribute('rad', $yAxis->getSoftEdgesSize());
$objWriter->endElement(); //end softEdge
}
$this->writeGlow($objWriter, $yAxis);
$this->writeShadow($objWriter, $yAxis);
$this->writeSoftEdge($objWriter, $yAxis);
$objWriter->endElement(); // effectLst
$objWriter->endElement(); // spPr
@ -640,61 +628,9 @@ class Chart extends WriterPart
$objWriter->endElement(); //end ln
}
$objWriter->startElement('a:effectLst');
if ($majorGridlines->getGlowSize() !== null) {
$objWriter->startElement('a:glow');
$objWriter->writeAttribute('rad', $majorGridlines->getGlowSize());
$objWriter->startElement("a:{$majorGridlines->getGlowColor('type')}");
$objWriter->writeAttribute('val', $majorGridlines->getGlowColor('value'));
$objWriter->startElement('a:alpha');
$objWriter->writeAttribute('val', $majorGridlines->getGlowColor('alpha'));
$objWriter->endElement(); //end alpha
$objWriter->endElement(); //end schemeClr
$objWriter->endElement(); //end glow
}
if ($majorGridlines->getShadowProperty('presets') !== null) {
$objWriter->startElement("a:{$majorGridlines->getShadowProperty('effect')}");
if ($majorGridlines->getShadowProperty('blur') !== null) {
$objWriter->writeAttribute('blurRad', $majorGridlines->getShadowProperty('blur'));
}
if ($majorGridlines->getShadowProperty('distance') !== null) {
$objWriter->writeAttribute('dist', $majorGridlines->getShadowProperty('distance'));
}
if ($majorGridlines->getShadowProperty('direction') !== null) {
$objWriter->writeAttribute('dir', $majorGridlines->getShadowProperty('direction'));
}
if ($majorGridlines->getShadowProperty('algn') !== null) {
$objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn'));
}
if ($majorGridlines->getShadowProperty(['size', 'sx']) !== null) {
$objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(['size', 'sx']));
}
if ($majorGridlines->getShadowProperty(['size', 'sy']) !== null) {
$objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(['size', 'sy']));
}
if ($majorGridlines->getShadowProperty(['size', 'kx']) !== null) {
$objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(['size', 'kx']));
}
if ($majorGridlines->getShadowProperty('rotWithShape') !== null) {
$objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape'));
}
$objWriter->startElement("a:{$majorGridlines->getShadowProperty(['color', 'type'])}");
$objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'value']));
$objWriter->startElement('a:alpha');
$objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'alpha']));
$objWriter->endElement(); //end alpha
$objWriter->endElement(); //end color:type
$objWriter->endElement(); //end shadow
}
if ($majorGridlines->getSoftEdgesSize() !== null) {
$objWriter->startElement('a:softEdge');
$objWriter->writeAttribute('rad', $majorGridlines->getSoftEdgesSize());
$objWriter->endElement(); //end softEdge
}
$this->writeGlow($objWriter, $majorGridlines);
$this->writeShadow($objWriter, $majorGridlines);
$this->writeSoftEdge($objWriter, $majorGridlines);
$objWriter->endElement(); //end effectLst
$objWriter->endElement(); //end spPr
@ -748,61 +684,11 @@ class Chart extends WriterPart
}
$objWriter->startElement('a:effectLst');
if ($minorGridlines->getGlowSize() !== null) {
$objWriter->startElement('a:glow');
$objWriter->writeAttribute('rad', $minorGridlines->getGlowSize());
$objWriter->startElement("a:{$minorGridlines->getGlowColor('type')}");
$objWriter->writeAttribute('val', $minorGridlines->getGlowColor('value'));
$objWriter->startElement('a:alpha');
$objWriter->writeAttribute('val', $minorGridlines->getGlowColor('alpha'));
$objWriter->endElement(); //end alpha
$objWriter->endElement(); //end schemeClr
$objWriter->endElement(); //end glow
}
if ($minorGridlines->getShadowProperty('presets') !== null) {
$objWriter->startElement("a:{$minorGridlines->getShadowProperty('effect')}");
if ($minorGridlines->getShadowProperty('blur') !== null) {
$objWriter->writeAttribute('blurRad', $minorGridlines->getShadowProperty('blur'));
}
if ($minorGridlines->getShadowProperty('distance') !== null) {
$objWriter->writeAttribute('dist', $minorGridlines->getShadowProperty('distance'));
}
if ($minorGridlines->getShadowProperty('direction') !== null) {
$objWriter->writeAttribute('dir', $minorGridlines->getShadowProperty('direction'));
}
if ($minorGridlines->getShadowProperty('algn') !== null) {
$objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn'));
}
if ($minorGridlines->getShadowProperty(['size', 'sx']) !== null) {
$objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(['size', 'sx']));
}
if ($minorGridlines->getShadowProperty(['size', 'sy']) !== null) {
$objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(['size', 'sy']));
}
if ($minorGridlines->getShadowProperty(['size', 'kx']) !== null) {
$objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(['size', 'kx']));
}
if ($minorGridlines->getShadowProperty('rotWithShape') !== null) {
$objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape'));
}
$objWriter->startElement("a:{$minorGridlines->getShadowProperty(['color', 'type'])}");
$objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'value']));
$objWriter->startElement('a:alpha');
$objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'alpha']));
$objWriter->endElement(); //end alpha
$objWriter->endElement(); //end color:type
$objWriter->endElement(); //end shadow
}
if ($minorGridlines->getSoftEdgesSize() !== null) {
$objWriter->startElement('a:softEdge');
$objWriter->writeAttribute('rad', $minorGridlines->getSoftEdgesSize());
$objWriter->endElement(); //end softEdge
}
$this->writeGlow($objWriter, $minorGridlines);
$this->writeShadow($objWriter, $minorGridlines);
$this->writeSoftEdge($objWriter, $minorGridlines);
$objWriter->endElement(); //end effectLst
$objWriter->endElement(); //end spPr
$objWriter->endElement(); //end minorGridLines
}
@ -925,64 +811,11 @@ class Chart extends WriterPart
$objWriter->endElement();
$objWriter->startElement('a:effectLst');
if ($xAxis->getGlowProperty('size') !== null) {
$objWriter->startElement('a:glow');
$objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size'));
$objWriter->startElement("a:{$xAxis->getGlowProperty(['color', 'type'])}");
$objWriter->writeAttribute('val', (string) $xAxis->getGlowProperty(['color', 'value']));
$objWriter->startElement('a:alpha');
$objWriter->writeAttribute('val', (string) $xAxis->getGlowProperty(['color', 'alpha']));
$objWriter->endElement();
$objWriter->endElement();
$objWriter->endElement();
}
if ($xAxis->getShadowProperty('presets') !== null) {
$objWriter->startElement("a:{$xAxis->getShadowProperty('effect')}");
if ($xAxis->getShadowProperty('blur') !== null) {
$objWriter->writeAttribute('blurRad', $xAxis->getShadowProperty('blur'));
}
if ($xAxis->getShadowProperty('distance') !== null) {
$objWriter->writeAttribute('dist', $xAxis->getShadowProperty('distance'));
}
if ($xAxis->getShadowProperty('direction') !== null) {
$objWriter->writeAttribute('dir', $xAxis->getShadowProperty('direction'));
}
if ($xAxis->getShadowProperty('algn') !== null) {
$objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn'));
}
if ($xAxis->getShadowProperty(['size', 'sx']) !== null) {
$objWriter->writeAttribute('sx', $xAxis->getShadowProperty(['size', 'sx']));
}
if ($xAxis->getShadowProperty(['size', 'sy']) !== null) {
$objWriter->writeAttribute('sy', $xAxis->getShadowProperty(['size', 'sy']));
}
if ($xAxis->getShadowProperty(['size', 'kx']) !== null) {
$objWriter->writeAttribute('kx', $xAxis->getShadowProperty(['size', 'kx']));
}
if ($xAxis->getShadowProperty('rotWithShape') !== null) {
$objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape'));
}
$objWriter->startElement("a:{$xAxis->getShadowProperty(['color', 'type'])}");
$objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color', 'value']));
$objWriter->startElement('a:alpha');
$objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color', 'alpha']));
$objWriter->endElement();
$objWriter->endElement();
$objWriter->endElement();
}
if ($xAxis->getSoftEdgesSize() !== null) {
$objWriter->startElement('a:softEdge');
$objWriter->writeAttribute('rad', $xAxis->getSoftEdgesSize());
$objWriter->endElement();
}
$this->writeGlow($objWriter, $xAxis);
$this->writeShadow($objWriter, $xAxis);
$this->writeSoftEdge($objWriter, $xAxis);
$objWriter->endElement(); //effectList
$objWriter->endElement(); //end spPr
if ($id1 !== '0') {
@ -1658,4 +1491,100 @@ class Chart extends WriterPart
$objWriter->endElement();
}
/**
* Write shadow properties.
*
* @param Axis|GridLines $xAxis
*/
private function writeShadow(XMLWriter $objWriter, $xAxis): void
{
if ($xAxis->getShadowProperty('effect') === null) {
return;
}
/** @var string */
$effect = $xAxis->getShadowProperty('effect');
$objWriter->startElement("a:$effect");
if (is_numeric($xAxis->getShadowProperty('blur'))) {
$objWriter->writeAttribute('blurRad', Properties::pointsToXml((float) $xAxis->getShadowProperty('blur')));
}
if (is_numeric($xAxis->getShadowProperty('distance'))) {
$objWriter->writeAttribute('dist', Properties::pointsToXml((float) $xAxis->getShadowProperty('distance')));
}
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'));
}
foreach (['sx', 'sy'] as $sizeType) {
$sizeValue = $xAxis->getShadowProperty(['size', $sizeType]);
if (is_numeric($sizeValue)) {
$objWriter->writeAttribute($sizeType, Properties::tenthOfPercentToXml((float) $sizeValue));
}
}
foreach (['kx', 'ky'] as $sizeType) {
$sizeValue = $xAxis->getShadowProperty(['size', $sizeType]);
if (is_numeric($sizeValue)) {
$objWriter->writeAttribute($sizeType, Properties::angleToXml((float) $sizeValue));
}
}
if ($xAxis->getShadowProperty('rotWithShape') !== null) {
$objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('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();
$objWriter->endElement();
}
/**
* Write glow properties.
*
* @param Axis|GridLines $yAxis
*/
private function writeGlow(XMLWriter $objWriter, $yAxis): void
{
$size = $yAxis->getGlowProperty('size');
if (empty($size)) {
return;
}
$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
$objWriter->endElement(); // glow
}
/**
* Write soft edge properties.
*
* @param Axis|GridLines $yAxis
*/
private function writeSoftEdge(XMLWriter $objWriter, $yAxis): void
{
$softEdgeSize = $yAxis->getSoftEdgesSize();
if (empty($softEdgeSize)) {
return;
}
$objWriter->startElement('a:softEdge');
$objWriter->writeAttribute('rad', Properties::pointsToXml((float) $softEdgeSize));
$objWriter->endElement(); //end softEdge
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
@ -106,21 +106,21 @@ class AxisGlowTest extends AbstractFunctional
);
$yAxis = $chart->getChartAxisY();
$xAxis = $chart->getChartAxisX();
$yAxis->setGlowProperties(10, 'FFFF00', 30, Properties::EXCEL_COLOR_TYPE_ARGB);
$expectedSize = 127000.0;
$yGlowSize = 10.0;
$yAxis->setGlowProperties($yGlowSize, 'FFFF00', 30, Properties::EXCEL_COLOR_TYPE_ARGB);
$expectedGlowColor = [
'type' => 'srgbClr',
'value' => 'FFFF00',
'alpha' => '70000',
'alpha' => 30,
];
$yAxis->setSoftEdges(2.5);
$xAxis->setSoftEdges(5);
$expectedSoftEdgesY = '31750';
$expectedSoftEdgesX = '63500';
self::assertEquals($expectedSize, $yAxis->getGlowProperty('size'));
$softEdgesY = 2.5;
$yAxis->setSoftEdges($softEdgesY);
$softEdgesX = 5;
$xAxis->setSoftEdges($softEdgesX);
self::assertEquals($yGlowSize, $yAxis->getGlowProperty('size'));
self::assertEquals($expectedGlowColor, $yAxis->getGlowProperty('color'));
self::assertEquals($expectedSoftEdgesY, $yAxis->getSoftEdgesSize());
self::assertEquals($expectedSoftEdgesX, $xAxis->getSoftEdgesSize());
self::assertEquals($softEdgesY, $yAxis->getSoftEdgesSize());
self::assertEquals($softEdgesX, $xAxis->getSoftEdgesSize());
// Set the position where the chart should appear in the worksheet
$chart->setTopLeftPosition('A7');
@ -142,9 +142,9 @@ class AxisGlowTest extends AbstractFunctional
$chart2 = $charts2[0];
self::assertNotNull($chart2);
$yAxis2 = $chart2->getChartAxisY();
self::assertEquals($expectedSize, $yAxis2->getGlowProperty('size'));
self::assertEquals($yGlowSize, $yAxis2->getGlowProperty('size'));
self::assertEquals($expectedGlowColor, $yAxis2->getGlowProperty('color'));
self::assertEquals($expectedSoftEdgesY, $yAxis2->getSoftEdgesSize());
self::assertEquals($softEdgesY, $yAxis2->getSoftEdgesSize());
$xAxis2 = $chart2->getChartAxisX();
self::assertNull($xAxis2->getGlowProperty('size'));
$reloadedSpreadsheet->disconnectWorksheets();
@ -229,14 +229,14 @@ class AxisGlowTest extends AbstractFunctional
$yAxisLabel // yAxisLabel
);
$yAxis = $chart->getChartAxisX(); // deliberate
$yAxis->setGlowProperties(20, 'accent1', 20, Properties::EXCEL_COLOR_TYPE_SCHEME);
$expectedSize = 254000.0;
$yGlowSize = 20.0;
$yAxis->setGlowProperties($yGlowSize, 'accent1', 20, Properties::EXCEL_COLOR_TYPE_SCHEME);
$expectedGlowColor = [
'type' => 'schemeClr',
'value' => 'accent1',
'alpha' => '80000',
'alpha' => 20,
];
self::assertEquals($expectedSize, $yAxis->getGlowProperty('size'));
self::assertEquals($yGlowSize, $yAxis->getGlowProperty('size'));
self::assertEquals($expectedGlowColor, $yAxis->getGlowProperty('color'));
// Set the position where the chart should appear in the worksheet
@ -259,7 +259,7 @@ class AxisGlowTest extends AbstractFunctional
$chart2 = $charts2[0];
self::assertNotNull($chart2);
$yAxis2 = $chart2->getChartAxisX(); // deliberate
self::assertEquals($expectedSize, $yAxis2->getGlowProperty('size'));
self::assertEquals($yGlowSize, $yAxis2->getGlowProperty('size'));
self::assertEquals($expectedGlowColor, $yAxis2->getGlowProperty('color'));
$xAxis2 = $chart2->getChartAxisY(); // deliberate
self::assertNull($xAxis2->getGlowProperty('size'));

View File

@ -0,0 +1,184 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
use PhpOffice\PhpSpreadsheet\Chart\Legend as ChartLegend;
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
use PhpOffice\PhpSpreadsheet\Chart\Properties;
use PhpOffice\PhpSpreadsheet\Chart\Title;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
class AxisShadowTest extends AbstractFunctional
{
public function readCharts(XlsxReader $reader): void
{
$reader->setIncludeCharts(true);
}
public function writeCharts(XlsxWriter $writer): void
{
$writer->setIncludeCharts(true);
}
public function testGlowY(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$worksheet->fromArray(
[
['', 2010, 2011, 2012],
['Q1', 12, 15, 21],
['Q2', 56, 73, 86],
['Q3', 52, 61, 69],
['Q4', 30, 32, 0],
]
);
// Set the Labels for each data series we want to plot
// Datatype
// Cell reference for data
// Format Code
// Number of datapoints in series
// Data values
// Data Marker
$dataSeriesLabels = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
];
// Set the X-Axis Labels
// Datatype
// Cell reference for data
// Format Code
// Number of datapoints in series
// Data values
// Data Marker
$xAxisTickValues = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
];
// Set the Data values for each data series we want to plot
// Datatype
// Cell reference for data
// Format Code
// Number of datapoints in series
// Data values
// Data Marker
$dataSeriesValues = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
];
// Build the dataseries
$series = new DataSeries(
DataSeries::TYPE_AREACHART, // plotType
DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping
range(0, count($dataSeriesValues) - 1), // plotOrder
$dataSeriesLabels, // plotLabel
$xAxisTickValues, // plotCategory
$dataSeriesValues // plotValues
);
// Set the series in the plot area
$plotArea = new PlotArea(null, [$series]);
// Set the chart legend
$legend = new ChartLegend(ChartLegend::POSITION_TOPRIGHT, null, false);
$title = new Title('Test %age-Stacked Area Chart');
$yAxisLabel = new Title('Value ($k)');
// Create the chart
$chart = new Chart(
'chart1', // name
$title, // title
$legend, // legend
$plotArea, // plotArea
true, // plotVisibleOnly
DataSeries::EMPTY_AS_GAP, // displayBlanksAs
null, // xAxisLabel
$yAxisLabel // yAxisLabel
);
$yAxis = $chart->getChartAxisY();
$expectedY = [
'effect' => 'outerShdw',
'algn' => 'tl',
'blur' => 5,
'direction' => 45,
'distance' => 3,
'rotWithShape' => 0,
'color' => [
'type' => Properties::EXCEL_COLOR_TYPE_STANDARD,
'value' => 'black',
'alpha' => 40,
],
];
foreach ($expectedY as $key => $value) {
$yAxis->setShadowProperty($key, $value);
}
foreach ($expectedY as $key => $value) {
self::assertEquals($value, $yAxis->getShadowProperty($key), $key);
}
$xAxis = $chart->getChartAxisX();
$expectedX = [
'effect' => 'outerShdw',
'algn' => 'bl',
'blur' => 6,
'direction' => 315,
'distance' => 3,
'rotWithShape' => 0,
'size' => [
'sx' => null,
'sy' => 254,
'kx' => -94,
'ky' => null,
],
'color' => [
'type' => Properties::EXCEL_COLOR_TYPE_ARGB,
'value' => 'FF0000',
'alpha' => 20,
],
];
foreach ($expectedX as $key => $value) {
$xAxis->setShadowProperty($key, $value);
}
foreach ($expectedX as $key => $value) {
self::assertEquals($value, $xAxis->getShadowProperty($key), $key);
}
// Set the position where the chart should appear in the worksheet
$chart->setTopLeftPosition('A7');
$chart->setBottomRightPosition('H20');
// Add the chart to the worksheet
$worksheet->addChart($chart);
/** @var callable */
$callableReader = [$this, 'readCharts'];
/** @var callable */
$callableWriter = [$this, 'writeCharts'];
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx', $callableReader, $callableWriter);
$spreadsheet->disconnectWorksheets();
$sheet = $reloadedSpreadsheet->getActiveSheet();
$charts2 = $sheet->getChartCollection();
self::assertCount(1, $charts2);
$chart2 = $charts2[0];
self::assertNotNull($chart2);
$yAxis2 = $chart2->getChartAxisY();
foreach ($expectedY as $key => $value) {
self::assertEquals($value, $yAxis2->getShadowProperty($key), $key);
}
$xAxis2 = $chart2->getChartAxisX();
foreach ($expectedX as $key => $value) {
self::assertEquals($value, $xAxis2->getShadowProperty($key), $key);
}
$reloadedSpreadsheet->disconnectWorksheets();
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Chart\Axis;
use PhpOffice\PhpSpreadsheet\Chart\Chart;

View File

@ -1,6 +1,6 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PhpOffice\PhpSpreadsheet\RichText\RichText;

View File

@ -1,6 +1,6 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PhpOffice\PhpSpreadsheet\RichText\RichText;

View File

@ -1,6 +1,6 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Chart\Properties;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;

View File

@ -1,6 +1,6 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PHPUnit\Framework\TestCase;

View File

@ -1,6 +1,6 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Chart\Title;
use PhpOffice\PhpSpreadsheet\IOFactory;

View File

@ -0,0 +1,187 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
use PhpOffice\PhpSpreadsheet\Chart\GridLines;
use PhpOffice\PhpSpreadsheet\Chart\Legend as ChartLegend;
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
use PhpOffice\PhpSpreadsheet\Chart\Properties;
use PhpOffice\PhpSpreadsheet\Chart\Title;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
class GridlinesShadowGlowTest extends AbstractFunctional
{
public function readCharts(XlsxReader $reader): void
{
$reader->setIncludeCharts(true);
}
public function writeCharts(XlsxWriter $writer): void
{
$writer->setIncludeCharts(true);
}
public function testGlowY(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$worksheet->fromArray(
[
['', 2010, 2011, 2012],
['Q1', 12, 15, 21],
['Q2', 56, 73, 86],
['Q3', 52, 61, 69],
['Q4', 30, 32, 0],
]
);
// Set the Labels for each data series we want to plot
// Datatype
// Cell reference for data
// Format Code
// Number of datapoints in series
// Data values
// Data Marker
$dataSeriesLabels = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
];
// Set the X-Axis Labels
// Datatype
// Cell reference for data
// Format Code
// Number of datapoints in series
// Data values
// Data Marker
$xAxisTickValues = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
];
// Set the Data values for each data series we want to plot
// Datatype
// Cell reference for data
// Format Code
// Number of datapoints in series
// Data values
// Data Marker
$dataSeriesValues = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
];
// Build the dataseries
$series = new DataSeries(
DataSeries::TYPE_LINECHART, // plotType
DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping
range(0, count($dataSeriesValues) - 1), // plotOrder
$dataSeriesLabels, // plotLabel
$xAxisTickValues, // plotCategory
$dataSeriesValues // plotValues
);
// Set the series in the plot area
$plotArea = new PlotArea(null, [$series]);
// Set the chart legend
$legend = new ChartLegend(ChartLegend::POSITION_TOPRIGHT, null, false);
$title = new Title('Test %age-Stacked Area Chart');
$yAxisLabel = new Title('Value ($k)');
$majorGridlines = new GridLines();
$majorGlowSize = 10.0;
$majorGridlines->setGlowProperties($majorGlowSize, 'FFFF00', 30, Properties::EXCEL_COLOR_TYPE_ARGB);
$softEdgeSize = 2.5;
$majorGridlines->setSoftEdges($softEdgeSize);
$expectedGlowColor = [
'type' => 'srgbClr',
'value' => 'FFFF00',
'alpha' => 30,
];
self::assertEquals($majorGlowSize, $majorGridlines->getGlowProperty('size'));
self::assertEquals($majorGlowSize, $majorGridlines->getGlowSize());
self::assertEquals($expectedGlowColor['value'], $majorGridlines->getGlowColor('value'));
self::assertEquals($expectedGlowColor, $majorGridlines->getGlowProperty('color'));
self::assertEquals($softEdgeSize, $majorGridlines->getSoftEdgesSize());
$minorGridlines = new GridLines();
$expectedShadow = [
'effect' => 'outerShdw',
'algn' => 'tl',
'blur' => 4,
'direction' => 45,
'distance' => 3,
'rotWithShape' => 0,
'color' => [
'type' => Properties::EXCEL_COLOR_TYPE_STANDARD,
'value' => 'black',
'alpha' => 40,
],
];
foreach ($expectedShadow as $key => $value) {
$minorGridlines->setShadowProperty($key, $value);
}
foreach ($expectedShadow as $key => $value) {
self::assertEquals($value, $minorGridlines->getShadowProperty($key), $key);
}
// Create the chart
$chart = new Chart(
'chart1', // name
$title, // title
$legend, // legend
$plotArea, // plotArea
true, // plotVisibleOnly
DataSeries::EMPTY_AS_GAP, // displayBlanksAs
null, // xAxisLabel
$yAxisLabel, // yAxisLabel
null, // xAxis
null, // yAxis
$majorGridlines,
$minorGridlines
);
$majorGridlines2 = $chart->getMajorGridlines();
self::assertEquals($majorGlowSize, $majorGridlines2->getGlowProperty('size'));
self::assertEquals($expectedGlowColor, $majorGridlines2->getGlowProperty('color'));
self::assertEquals($softEdgeSize, $majorGridlines2->getSoftEdgesSize());
$minorGridlines2 = $chart->getMinorGridlines();
foreach ($expectedShadow as $key => $value) {
self::assertEquals($value, $minorGridlines2->getShadowProperty($key), $key);
}
// Set the position where the chart should appear in the worksheet
$chart->setTopLeftPosition('A7');
$chart->setBottomRightPosition('H20');
// Add the chart to the worksheet
$worksheet->addChart($chart);
/** @var callable */
$callableReader = [$this, 'readCharts'];
/** @var callable */
$callableWriter = [$this, 'writeCharts'];
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx', $callableReader, $callableWriter);
$spreadsheet->disconnectWorksheets();
$sheet = $reloadedSpreadsheet->getActiveSheet();
$charts2 = $sheet->getChartCollection();
self::assertCount(1, $charts2);
$chart2 = $charts2[0];
self::assertNotNull($chart2);
$majorGridlines3 = $chart2->getMajorGridlines();
self::assertEquals($majorGlowSize, $majorGridlines3->getGlowProperty('size'));
self::assertEquals($expectedGlowColor, $majorGridlines3->getGlowProperty('color'));
self::assertEquals($softEdgeSize, $majorGridlines3->getSoftEdgesSize());
$minorGridlines3 = $chart->getMinorGridlines();
foreach ($expectedShadow as $key => $value) {
self::assertEquals($value, $minorGridlines3->getShadowProperty($key), $key);
}
$reloadedSpreadsheet->disconnectWorksheets();
}
}

View File

@ -0,0 +1,157 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
use PhpOffice\PhpSpreadsheet\Chart\Legend as ChartLegend;
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
use PhpOffice\PhpSpreadsheet\Chart\Properties;
use PhpOffice\PhpSpreadsheet\Chart\Title;
use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
use PHPUnit\Framework\TestCase;
class MultiplierTest extends TestCase
{
public function testMultiplier(): void
{
$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();
$worksheet->fromArray(
[
['', 2010, 2011, 2012],
['Q1', 12, 15, 21],
['Q2', 56, 73, 86],
['Q3', 52, 61, 69],
['Q4', 30, 32, 0],
]
);
// Set the Labels for each data series we want to plot
// Datatype
// Cell reference for data
// Format Code
// Number of datapoints in series
// Data values
// Data Marker
$dataSeriesLabels = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
];
// Set the X-Axis Labels
// Datatype
// Cell reference for data
// Format Code
// Number of datapoints in series
// Data values
// Data Marker
$xAxisTickValues = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
];
// Set the Data values for each data series we want to plot
// Datatype
// Cell reference for data
// Format Code
// Number of datapoints in series
// Data values
// Data Marker
$dataSeriesValues = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
];
// Build the dataseries
$series = new DataSeries(
DataSeries::TYPE_AREACHART, // plotType
DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping
range(0, count($dataSeriesValues) - 1), // plotOrder
$dataSeriesLabels, // plotLabel
$xAxisTickValues, // plotCategory
$dataSeriesValues // plotValues
);
// Set the series in the plot area
$plotArea = new PlotArea(null, [$series]);
// Set the chart legend
$legend = new ChartLegend(ChartLegend::POSITION_TOPRIGHT, null, false);
$title = new Title('Test %age-Stacked Area Chart');
$yAxisLabel = new Title('Value ($k)');
// Create the chart
$chart = new Chart(
'chart1', // name
$title, // title
$legend, // legend
$plotArea, // plotArea
true, // plotVisibleOnly
DataSeries::EMPTY_AS_GAP, // displayBlanksAs
null, // xAxisLabel
$yAxisLabel // yAxisLabel
);
$xAxis = $chart->getChartAxisX();
$expectedX = [
'effect' => 'outerShdw',
'algn' => 'bl',
'blur' => 6,
'direction' => 315,
'distance' => 3,
'rotWithShape' => 0,
'size' => [
'sx' => null,
'sy' => 254,
'kx' => -94,
'ky' => null,
],
'color' => [
'type' => Properties::EXCEL_COLOR_TYPE_ARGB,
'value' => 'FF0000',
'alpha' => 20,
],
];
$expectedXmlX = [
'<a:outerShdw ',
' algn="bl"',
' blurRad="76200"',
' dir="18900000"',
' dist="38100"',
' rotWithShape="0"',
' sy="25400000"',
' kx="-5640000"',
'<a:srgbClr val="FF0000">',
'<a:alpha val="80000"/>',
];
$expectedXmlNoX = [
' sx=',
' ky=',
];
foreach ($expectedX as $key => $value) {
$xAxis->setShadowProperty($key, $value);
}
// Set the position where the chart should appear in the worksheet
$chart->setTopLeftPosition('A7');
$chart->setBottomRightPosition('H20');
// Add the chart to the worksheet
$worksheet->addChart($chart);
$writer = new XlsxWriter($spreadsheet);
$writer->setIncludeCharts(true);
$writerChart = new XlsxWriter\Chart($writer);
$data = $writerChart->writeChart($chart);
// confirm that file contains expected tags
foreach ($expectedXmlX as $expected) {
self::assertSame(1, substr_count($data, $expected), $expected);
}
foreach ($expectedXmlNoX as $expected) {
self::assertSame(0, substr_count($data, $expected), $expected);
}
$spreadsheet->disconnectWorksheets();
}
}

View File

@ -0,0 +1,183 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Chart\Axis;
use PhpOffice\PhpSpreadsheet\Chart\GridLines;
use PhpOffice\PhpSpreadsheet\Chart\Properties;
use PHPUnit\Framework\TestCase;
class ShadowPresetsTest extends TestCase
{
public function testGridlineShadowPresets(): void
{
$gridlines = new GridLines();
$gridlines->setShadowProperties(17);
$expectedShadow = [
'effect' => 'innerShdw',
'distance' => 4,
'direction' => 270,
'blur' => 5,
];
foreach ($expectedShadow as $key => $value) {
self::assertEquals($gridlines->getShadowProperty($key), $value, $key);
}
}
public function testGridlineShadowPresetsWithArray(): void
{
$gridlines = new GridLines();
$gridlines->setShadowProperties(20);
$expectedShadow = [
'effect' => 'outerShdw',
'blur' => 6,
'direction' => 315,
'size' => [
'sx' => null,
'sy' => 0.23,
'kx' => -20,
'ky' => null,
],
'algn' => 'bl',
'rotWithShape' => '0',
];
foreach ($expectedShadow as $key => $value) {
self::assertEquals($gridlines->getShadowProperty($key), $value, $key);
}
}
public function testAxisShadowPresets(): void
{
$axis = new Axis();
$axis->setShadowProperties(9);
$expectedShadow = [
'effect' => 'outerShdw',
'blur' => 4,
'distance' => 3,
'direction' => 225,
'algn' => 'br',
'rotWithShape' => '0',
];
foreach ($expectedShadow as $key => $value) {
self::assertEquals($axis->getShadowProperty($key), $value, $key);
}
}
public function testAxisShadowPresetsWithChanges(): void
{
$axis = new Axis();
$axis->setShadowProperties(
9, // preset
'FF0000', // colorValue
'srgbClr', // colorType
20, // alpha
6, // blur
30, // direction
4, // distance
);
$expectedShadow = [
'effect' => 'outerShdw',
'blur' => 6,
'distance' => 4,
'direction' => 30,
'algn' => 'br',
'rotWithShape' => '0',
'color' => [
'value' => 'FF0000',
'type' => 'srgbClr',
'alpha' => 20,
],
];
foreach ($expectedShadow as $key => $value) {
self::assertEquals($axis->getShadowProperty($key), $value, $key);
}
}
public function testGridlinesShadowPresetsWithChanges(): void
{
$gridline = new GridLines();
$gridline->setShadowProperties(
9, // preset
'FF0000', // colorValue
'srgbClr', // colorType
20, // alpha
6, // blur
30, // direction
4, // distance
);
$expectedShadow = [
'effect' => 'outerShdw',
'blur' => 6,
'distance' => 4,
'direction' => 30,
'algn' => 'br',
'rotWithShape' => '0',
'color' => [
'value' => 'FF0000',
'type' => 'srgbClr',
'alpha' => 20,
],
];
foreach ($expectedShadow as $key => $value) {
self::assertEquals($gridline->getShadowProperty($key), $value, $key);
}
}
public function testOutOfRangePresets(): void
{
$axis = new Axis();
$axis->setShadowProperties(99);
$expectedShadow = [
'presets' => Properties::SHADOW_PRESETS_NOSHADOW,
'effect' => null,
'color' => [
'type' => Properties::EXCEL_COLOR_TYPE_STANDARD,
'value' => 'black',
'alpha' => 40,
],
'size' => [
'sx' => null,
'sy' => null,
'kx' => null,
'ky' => null,
],
'blur' => null,
'direction' => null,
'distance' => null,
'algn' => null,
'rotWithShape' => null,
];
foreach ($expectedShadow as $key => $value) {
self::assertEquals($value, $axis->getShadowProperty($key), $key);
}
}
public function testOutOfRangeGridlines(): void
{
$gridline = new GridLines();
$gridline->setShadowProperties(99);
$expectedShadow = [
'presets' => Properties::SHADOW_PRESETS_NOSHADOW,
'effect' => null,
'color' => [
'type' => Properties::EXCEL_COLOR_TYPE_STANDARD,
'value' => 'black',
'alpha' => 40,
],
'size' => [
'sx' => null,
'sy' => null,
'kx' => null,
'ky' => null,
],
'blur' => null,
'direction' => null,
'distance' => null,
'algn' => null,
'rotWithShape' => null,
];
foreach ($expectedShadow as $key => $value) {
self::assertEquals($value, $gridline->getShadowProperty($key), $key);
}
}
}