Merge branch 'master' into Issue-2833_Null-handling-in-PRODUCT()-Function
This commit is contained in:
commit
a59b29ae11
|
|
@ -1215,26 +1215,6 @@ parameters:
|
|||
count: 2
|
||||
path: src/PhpSpreadsheet/Chart/DataSeries.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:refresh\\(\\) has parameter \\$flatten with no type specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Chart/DataSeriesValues.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:\\$dataSource \\(string\\) does not accept string\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Chart/DataSeriesValues.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:\\$dataTypeValues has no type specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Chart/DataSeriesValues.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:\\$fillColor \\(array\\<string\\>\\|string\\) does not accept array\\<string\\>\\|string\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Chart/DataSeriesValues.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$angle of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setShadowAngle\\(\\) expects int, int\\|null given\\.$#"
|
||||
count: 1
|
||||
|
|
@ -2560,56 +2540,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getFont\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\Run\\|null\\.$#"
|
||||
count: 12
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setBold\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setColor\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setItalic\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setName\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setStrikethrough\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 2
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setSubscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setSuperscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method setUnderline\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 3
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeries\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -2635,11 +2565,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValueSet\\(\\) has parameter \\$marker with no type specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValueSet\\(\\) has parameter \\$namespacesChartMeta with no type specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -2715,21 +2640,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:readColor\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:readColor\\(\\) has parameter \\$background with no type specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:readColor\\(\\) has parameter \\$color with no type specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$position of class PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Legend constructor expects string, bool\\|float\\|int\\|string\\|null given\\.$#"
|
||||
count: 1
|
||||
|
|
@ -4997,7 +4907,7 @@ parameters:
|
|||
|
||||
-
|
||||
message: "#^Cannot call method getBold\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 2
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php
|
||||
|
||||
-
|
||||
|
|
@ -5007,12 +4917,12 @@ parameters:
|
|||
|
||||
-
|
||||
message: "#^Cannot call method getItalic\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 2
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getName\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 2
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php
|
||||
|
||||
-
|
||||
|
|
@ -5022,7 +4932,7 @@ parameters:
|
|||
|
||||
-
|
||||
message: "#^Cannot call method getStrikethrough\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 2
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php
|
||||
|
||||
-
|
||||
|
|
@ -5037,7 +4947,7 @@ parameters:
|
|||
|
||||
-
|
||||
message: "#^Cannot call method getUnderline\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
|
||||
count: 2
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php
|
||||
|
||||
-
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -12,7 +12,7 @@ class DataSeriesValues
|
|||
const DATASERIES_TYPE_STRING = 'String';
|
||||
const DATASERIES_TYPE_NUMBER = 'Number';
|
||||
|
||||
private static $dataTypeValues = [
|
||||
private const DATA_TYPE_VALUES = [
|
||||
self::DATASERIES_TYPE_STRING,
|
||||
self::DATASERIES_TYPE_NUMBER,
|
||||
];
|
||||
|
|
@ -27,7 +27,7 @@ class DataSeriesValues
|
|||
/**
|
||||
* Series Data Source.
|
||||
*
|
||||
* @var string
|
||||
* @var ?string
|
||||
*/
|
||||
private $dataSource;
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ class DataSeriesValues
|
|||
/**
|
||||
* Fill color (can be array with colors if dataseries have custom colors).
|
||||
*
|
||||
* @var string|string[]
|
||||
* @var null|string|string[]
|
||||
*/
|
||||
private $fillColor;
|
||||
|
||||
|
|
@ -80,6 +80,9 @@ class DataSeriesValues
|
|||
*/
|
||||
private $lineWidth = 12700;
|
||||
|
||||
/** @var bool */
|
||||
private $scatterLines = true;
|
||||
|
||||
/**
|
||||
* Create a new DataSeriesValues object.
|
||||
*
|
||||
|
|
@ -90,8 +93,9 @@ class DataSeriesValues
|
|||
* @param mixed $dataValues
|
||||
* @param null|mixed $marker
|
||||
* @param null|string|string[] $fillColor
|
||||
* @param string $pointSize
|
||||
*/
|
||||
public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSource = null, $formatCode = null, $pointCount = 0, $dataValues = [], $marker = null, $fillColor = null)
|
||||
public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSource = null, $formatCode = null, $pointCount = 0, $dataValues = [], $marker = null, $fillColor = null, $pointSize = '3')
|
||||
{
|
||||
$this->setDataType($dataType);
|
||||
$this->dataSource = $dataSource;
|
||||
|
|
@ -100,6 +104,9 @@ class DataSeriesValues
|
|||
$this->dataValues = $dataValues;
|
||||
$this->pointMarker = $marker;
|
||||
$this->fillColor = $fillColor;
|
||||
if (is_numeric($pointSize)) {
|
||||
$this->pointSize = (int) $pointSize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -126,7 +133,7 @@ class DataSeriesValues
|
|||
*/
|
||||
public function setDataType($dataType)
|
||||
{
|
||||
if (!in_array($dataType, self::$dataTypeValues)) {
|
||||
if (!in_array($dataType, self::DATA_TYPE_VALUES)) {
|
||||
throw new Exception('Invalid datatype for chart data series values');
|
||||
}
|
||||
$this->dataType = $dataType;
|
||||
|
|
@ -137,7 +144,7 @@ class DataSeriesValues
|
|||
/**
|
||||
* Get Series Data Source (formula).
|
||||
*
|
||||
* @return string
|
||||
* @return ?string
|
||||
*/
|
||||
public function getDataSource()
|
||||
{
|
||||
|
|
@ -147,7 +154,7 @@ class DataSeriesValues
|
|||
/**
|
||||
* Set Series Data Source (formula).
|
||||
*
|
||||
* @param string $dataSource
|
||||
* @param ?string $dataSource
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
|
|
@ -239,7 +246,7 @@ class DataSeriesValues
|
|||
/**
|
||||
* Get fill color.
|
||||
*
|
||||
* @return string|string[] HEX color or array with HEX colors
|
||||
* @return null|string|string[] HEX color or array with HEX colors
|
||||
*/
|
||||
public function getFillColor()
|
||||
{
|
||||
|
|
@ -249,7 +256,7 @@ class DataSeriesValues
|
|||
/**
|
||||
* Set fill color for series.
|
||||
*
|
||||
* @param string|string[] $color HEX color or array with HEX colors
|
||||
* @param null|string|string[] $color HEX color or array with HEX colors
|
||||
*
|
||||
* @return DataSeriesValues
|
||||
*/
|
||||
|
|
@ -260,7 +267,7 @@ class DataSeriesValues
|
|||
$this->validateColor($colorValue);
|
||||
}
|
||||
} else {
|
||||
$this->validateColor($color);
|
||||
$this->validateColor("$color");
|
||||
}
|
||||
$this->fillColor = $color;
|
||||
|
||||
|
|
@ -379,7 +386,7 @@ class DataSeriesValues
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function refresh(Worksheet $worksheet, $flatten = true): void
|
||||
public function refresh(Worksheet $worksheet, bool $flatten = true): void
|
||||
{
|
||||
if ($this->dataSource !== null) {
|
||||
$calcEngine = Calculation::getInstance($worksheet->getParent());
|
||||
|
|
@ -421,4 +428,16 @@ class DataSeriesValues
|
|||
$this->pointCount = count($this->dataValues);
|
||||
}
|
||||
}
|
||||
|
||||
public function getScatterLines(): bool
|
||||
{
|
||||
return $this->scatterLines;
|
||||
}
|
||||
|
||||
public function setScatterLines(bool $scatterLines): self
|
||||
{
|
||||
$this->scatterLines = $scatterLines;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class Chart
|
|||
private static function getAttribute(SimpleXMLElement $component, $name, $format)
|
||||
{
|
||||
$attributes = $component->attributes();
|
||||
if (isset($attributes[$name])) {
|
||||
if (@isset($attributes[$name])) {
|
||||
if ($format == 'string') {
|
||||
return (string) $attributes[$name];
|
||||
} elseif ($format == 'integer') {
|
||||
|
|
@ -42,15 +42,6 @@ class Chart
|
|||
return null;
|
||||
}
|
||||
|
||||
private static function readColor($color, $background = false)
|
||||
{
|
||||
if (isset($color['rgb'])) {
|
||||
return (string) $color['rgb'];
|
||||
} elseif (isset($color['indexed'])) {
|
||||
return Color::indexedColor($color['indexed'] - 7, $background)->getARGB();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $chartName
|
||||
*
|
||||
|
|
@ -293,6 +284,10 @@ class Chart
|
|||
case 'ser':
|
||||
$marker = null;
|
||||
$seriesIndex = '';
|
||||
$srgbClr = null;
|
||||
$lineWidth = null;
|
||||
$pointSize = null;
|
||||
$noFill = false;
|
||||
foreach ($seriesDetails as $seriesKey => $seriesDetail) {
|
||||
switch ($seriesKey) {
|
||||
case 'idx':
|
||||
|
|
@ -307,9 +302,25 @@ class Chart
|
|||
case 'tx':
|
||||
$seriesLabel[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta);
|
||||
|
||||
break;
|
||||
case 'spPr':
|
||||
$ln = $seriesDetail->children($namespacesChartMeta['a'])->ln;
|
||||
$lineWidth = self::getAttribute($ln, 'w', 'string');
|
||||
if (is_countable($ln->noFill) && count($ln->noFill) === 1) {
|
||||
$noFill = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'marker':
|
||||
$marker = self::getAttribute($seriesDetail->symbol, 'val', 'string');
|
||||
$pointSize = self::getAttribute($seriesDetail->size, 'val', 'string');
|
||||
$pointSize = is_numeric($pointSize) ? ((int) $pointSize) : null;
|
||||
if (count($seriesDetail->spPr) === 1) {
|
||||
$ln = $seriesDetail->spPr->children($namespacesChartMeta['a']);
|
||||
if (count($ln->solidFill) === 1) {
|
||||
$srgbClr = self::getattribute($ln->solidFill->srgbClr, 'val', 'string');
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'smooth':
|
||||
|
|
@ -321,30 +332,52 @@ class Chart
|
|||
|
||||
break;
|
||||
case 'val':
|
||||
$seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker);
|
||||
$seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, "$marker", "$srgbClr", "$pointSize");
|
||||
|
||||
break;
|
||||
case 'xVal':
|
||||
$seriesCategory[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker);
|
||||
$seriesCategory[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, "$marker", "$srgbClr", "$pointSize");
|
||||
|
||||
break;
|
||||
case 'yVal':
|
||||
$seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker);
|
||||
$seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, "$marker", "$srgbClr", "$pointSize");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($noFill) {
|
||||
if (isset($seriesLabel[$seriesIndex])) {
|
||||
$seriesLabel[$seriesIndex]->setScatterLines(false);
|
||||
}
|
||||
if (isset($seriesCategory[$seriesIndex])) {
|
||||
$seriesCategory[$seriesIndex]->setScatterLines(false);
|
||||
}
|
||||
if (isset($seriesValues[$seriesIndex])) {
|
||||
$seriesValues[$seriesIndex]->setScatterLines(false);
|
||||
}
|
||||
}
|
||||
if (is_numeric($lineWidth)) {
|
||||
if (isset($seriesLabel[$seriesIndex])) {
|
||||
$seriesLabel[$seriesIndex]->setLineWidth((int) $lineWidth);
|
||||
}
|
||||
if (isset($seriesCategory[$seriesIndex])) {
|
||||
$seriesCategory[$seriesIndex]->setLineWidth((int) $lineWidth);
|
||||
}
|
||||
if (isset($seriesValues[$seriesIndex])) {
|
||||
$seriesValues[$seriesIndex]->setLineWidth((int) $lineWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new DataSeries($plotType, $multiSeriesType, $plotOrder, $seriesLabel, $seriesCategory, $seriesValues, $smoothLine);
|
||||
}
|
||||
|
||||
private static function chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null)
|
||||
private static function chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, ?string $marker = null, ?string $srgbClr = null, ?string $pointSize = null)
|
||||
{
|
||||
if (isset($seriesDetail->strRef)) {
|
||||
$seriesSource = (string) $seriesDetail->strRef->f;
|
||||
$seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, null, null, $marker);
|
||||
$seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, null, null, $marker, $srgbClr, "$pointSize");
|
||||
|
||||
if (isset($seriesDetail->strRef->strCache)) {
|
||||
$seriesData = self::chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']), 's');
|
||||
|
|
@ -356,7 +389,7 @@ class Chart
|
|||
return $seriesValues;
|
||||
} elseif (isset($seriesDetail->numRef)) {
|
||||
$seriesSource = (string) $seriesDetail->numRef->f;
|
||||
$seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, null, null, null, $marker);
|
||||
$seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, null, null, null, $marker, $srgbClr, "$pointSize");
|
||||
if (isset($seriesDetail->numRef->numCache)) {
|
||||
$seriesData = self::chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c']));
|
||||
$seriesValues
|
||||
|
|
@ -367,7 +400,7 @@ class Chart
|
|||
return $seriesValues;
|
||||
} elseif (isset($seriesDetail->multiLvlStrRef)) {
|
||||
$seriesSource = (string) $seriesDetail->multiLvlStrRef->f;
|
||||
$seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, null, null, $marker);
|
||||
$seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, null, null, $marker, $srgbClr, "$pointSize");
|
||||
|
||||
if (isset($seriesDetail->multiLvlStrRef->multiLvlStrCache)) {
|
||||
$seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']), 's');
|
||||
|
|
@ -379,7 +412,7 @@ class Chart
|
|||
return $seriesValues;
|
||||
} elseif (isset($seriesDetail->multiLvlNumRef)) {
|
||||
$seriesSource = (string) $seriesDetail->multiLvlNumRef->f;
|
||||
$seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, null, null, $marker);
|
||||
$seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, null, null, $marker, $srgbClr, "$pointSize");
|
||||
|
||||
if (isset($seriesDetail->multiLvlNumRef->multiLvlNumCache)) {
|
||||
$seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']), 's');
|
||||
|
|
@ -474,62 +507,138 @@ class Chart
|
|||
{
|
||||
$value = new RichText();
|
||||
$objText = null;
|
||||
$defaultFontSize = null;
|
||||
$defaultBold = null;
|
||||
$defaultItalic = null;
|
||||
$defaultUnderscore = null;
|
||||
$defaultStrikethrough = null;
|
||||
$defaultBaseline = null;
|
||||
$defaultFontName = null;
|
||||
$defaultColor = null;
|
||||
if (isset($titleDetailPart->pPr->defRPr)) {
|
||||
/** @var ?int */
|
||||
$defaultFontSize = self::getAttribute($titleDetailPart->pPr->defRPr, 'sz', 'integer');
|
||||
/** @var ?bool */
|
||||
$defaultBold = self::getAttribute($titleDetailPart->pPr->defRPr, 'b', 'boolean');
|
||||
/** @var ?bool */
|
||||
$defaultItalic = self::getAttribute($titleDetailPart->pPr->defRPr, 'i', 'boolean');
|
||||
/** @var ?string */
|
||||
$defaultUnderscore = self::getAttribute($titleDetailPart->pPr->defRPr, 'u', 'string');
|
||||
/** @var ?string */
|
||||
$defaultStrikethrough = self::getAttribute($titleDetailPart->pPr->defRPr, 'strike', 'string');
|
||||
/** @var ?int */
|
||||
$defaultBaseline = self::getAttribute($titleDetailPart->pPr->defRPr, 'baseline', 'integer');
|
||||
if (isset($titleDetailPart->pPr->defRPr->latin)) {
|
||||
/** @var ?string */
|
||||
$defaultFontName = self::getAttribute($titleDetailPart->pPr->defRPr->latin, 'typeface', 'string');
|
||||
}
|
||||
if (isset($titleDetailPart->pPr->defRPr->solidFill->srgbClr)) {
|
||||
/** @var ?string */
|
||||
$defaultColor = self::getAttribute($titleDetailPart->pPr->defRPr->solidFill->srgbClr, 'val', 'string');
|
||||
}
|
||||
}
|
||||
foreach ($titleDetailPart as $titleDetailElementKey => $titleDetailElement) {
|
||||
if (isset($titleDetailElement->t)) {
|
||||
$objText = $value->createTextRun((string) $titleDetailElement->t);
|
||||
}
|
||||
if ($objText === null || $objText->getFont() === null) {
|
||||
continue;
|
||||
}
|
||||
$fontSize = null;
|
||||
$bold = null;
|
||||
$italic = null;
|
||||
$underscore = null;
|
||||
$strikethrough = null;
|
||||
$baseline = null;
|
||||
$fontName = null;
|
||||
$fontColor = null;
|
||||
if (isset($titleDetailElement->rPr)) {
|
||||
// not used now, not sure it ever was, grandfathering
|
||||
if (isset($titleDetailElement->rPr->rFont['val'])) {
|
||||
$objText->getFont()->setName((string) $titleDetailElement->rPr->rFont['val']);
|
||||
}
|
||||
|
||||
$fontSize = (self::getAttribute($titleDetailElement->rPr, 'sz', 'integer'));
|
||||
if (is_int($fontSize)) {
|
||||
$objText->getFont()->setSize(floor($fontSize / 100));
|
||||
}
|
||||
|
||||
$fontColor = (self::getAttribute($titleDetailElement->rPr, 'color', 'string'));
|
||||
if ($fontColor !== null) {
|
||||
$objText->getFont()->setColor(new Color(self::readColor($fontColor)));
|
||||
$fontName = (string) $titleDetailElement->rPr->rFont['val'];
|
||||
}
|
||||
if (isset($titleDetailElement->rPr->latin)) {
|
||||
/** @var ?string */
|
||||
$fontName = self::getAttribute($titleDetailElement->rPr->latin, 'typeface', 'string');
|
||||
}
|
||||
/** @var ?int */
|
||||
$fontSize = self::getAttribute($titleDetailElement->rPr, 'sz', 'integer');
|
||||
|
||||
// not used now, not sure it ever was, grandfathering
|
||||
/** @var ?string */
|
||||
$fontColor = self::getAttribute($titleDetailElement->rPr, 'color', 'string');
|
||||
if (isset($titleDetailElement->rPr->solidFill->srgbClr)) {
|
||||
/** @var ?string */
|
||||
$fontColor = self::getAttribute($titleDetailElement->rPr->solidFill->srgbClr, 'val', 'string');
|
||||
}
|
||||
|
||||
/** @var ?bool */
|
||||
$bold = self::getAttribute($titleDetailElement->rPr, 'b', 'boolean');
|
||||
if ($bold !== null) {
|
||||
$objText->getFont()->setBold($bold);
|
||||
}
|
||||
|
||||
/** @var ?bool */
|
||||
$italic = self::getAttribute($titleDetailElement->rPr, 'i', 'boolean');
|
||||
if ($italic !== null) {
|
||||
$objText->getFont()->setItalic($italic);
|
||||
}
|
||||
|
||||
/** @var ?int */
|
||||
$baseline = self::getAttribute($titleDetailElement->rPr, 'baseline', 'integer');
|
||||
if ($baseline !== null) {
|
||||
if ($baseline > 0) {
|
||||
$objText->getFont()->setSuperscript(true);
|
||||
} elseif ($baseline < 0) {
|
||||
$objText->getFont()->setSubscript(true);
|
||||
}
|
||||
}
|
||||
|
||||
$underscore = (self::getAttribute($titleDetailElement->rPr, 'u', 'string'));
|
||||
if ($underscore !== null) {
|
||||
if ($underscore == 'sng') {
|
||||
$objText->getFont()->setUnderline(Font::UNDERLINE_SINGLE);
|
||||
} elseif ($underscore == 'dbl') {
|
||||
$objText->getFont()->setUnderline(Font::UNDERLINE_DOUBLE);
|
||||
} else {
|
||||
$objText->getFont()->setUnderline(Font::UNDERLINE_NONE);
|
||||
}
|
||||
}
|
||||
/** @var ?string */
|
||||
$underscore = self::getAttribute($titleDetailElement->rPr, 'u', 'string');
|
||||
|
||||
$strikethrough = (self::getAttribute($titleDetailElement->rPr, 's', 'string'));
|
||||
if ($strikethrough !== null) {
|
||||
if ($strikethrough == 'noStrike') {
|
||||
$objText->getFont()->setStrikethrough(false);
|
||||
} else {
|
||||
$objText->getFont()->setStrikethrough(true);
|
||||
}
|
||||
/** @var ?string */
|
||||
$strikethrough = self::getAttribute($titleDetailElement->rPr, 's', 'string');
|
||||
}
|
||||
|
||||
$fontName = $fontName ?? $defaultFontName;
|
||||
if ($fontName !== null) {
|
||||
$objText->getFont()->setName($fontName);
|
||||
}
|
||||
|
||||
$fontSize = $fontSize ?? $defaultFontSize;
|
||||
if (is_int($fontSize)) {
|
||||
$objText->getFont()->setSize(floor($fontSize / 100));
|
||||
}
|
||||
|
||||
$fontColor = $fontColor ?? $defaultColor;
|
||||
if ($fontColor !== null) {
|
||||
$objText->getFont()->setColor(new Color($fontColor));
|
||||
}
|
||||
|
||||
$bold = $bold ?? $defaultBold;
|
||||
if ($bold !== null) {
|
||||
$objText->getFont()->setBold($bold);
|
||||
}
|
||||
|
||||
$italic = $italic ?? $defaultItalic;
|
||||
if ($italic !== null) {
|
||||
$objText->getFont()->setItalic($italic);
|
||||
}
|
||||
|
||||
$baseline = $baseline ?? $defaultBaseline;
|
||||
if ($baseline !== null) {
|
||||
if ($baseline > 0) {
|
||||
$objText->getFont()->setSuperscript(true);
|
||||
} elseif ($baseline < 0) {
|
||||
$objText->getFont()->setSubscript(true);
|
||||
}
|
||||
}
|
||||
|
||||
$underscore = $underscore ?? $defaultUnderscore;
|
||||
if ($underscore !== null) {
|
||||
if ($underscore == 'sng') {
|
||||
$objText->getFont()->setUnderline(Font::UNDERLINE_SINGLE);
|
||||
} elseif ($underscore == 'dbl') {
|
||||
$objText->getFont()->setUnderline(Font::UNDERLINE_DOUBLE);
|
||||
} else {
|
||||
$objText->getFont()->setUnderline(Font::UNDERLINE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
$strikethrough = $strikethrough ?? $defaultStrikethrough;
|
||||
if ($strikethrough !== null) {
|
||||
if ($strikethrough == 'noStrike') {
|
||||
$objText->getFont()->setStrikethrough(false);
|
||||
} else {
|
||||
$objText->getFont()->setStrikethrough(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ class Chart extends WriterPart
|
|||
if ($chartType === DataSeries::TYPE_BUBBLECHART) {
|
||||
$this->writeValueAxis($objWriter, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $majorGridlines, $minorGridlines);
|
||||
} else {
|
||||
$this->writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $catIsMultiLevelSeries, $xAxis);
|
||||
$this->writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $catIsMultiLevelSeries, $xAxis, ($chartType === DataSeries::TYPE_SCATTERCHART) ? 'c:valAx' : 'c:catAx');
|
||||
}
|
||||
|
||||
$this->writeValueAxis($objWriter, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $yAxis, $majorGridlines, $minorGridlines);
|
||||
|
|
@ -367,9 +367,9 @@ class Chart extends WriterPart
|
|||
* @param string $id2
|
||||
* @param bool $isMultiLevelSeries
|
||||
*/
|
||||
private function writeCategoryAxis(XMLWriter $objWriter, ?Title $xAxisLabel, $id1, $id2, $isMultiLevelSeries, Axis $yAxis): void
|
||||
private function writeCategoryAxis(XMLWriter $objWriter, ?Title $xAxisLabel, $id1, $id2, $isMultiLevelSeries, Axis $yAxis, string $element = 'c:catAx'): void
|
||||
{
|
||||
$objWriter->startElement('c:catAx');
|
||||
$objWriter->startElement($element);
|
||||
|
||||
if ($id1 > 0) {
|
||||
$objWriter->startElement('c:axId');
|
||||
|
|
@ -1016,7 +1016,7 @@ class Chart extends WriterPart
|
|||
* @param bool $valIsMultiLevelSeries Is value set a multi-series set
|
||||
* @param string $plotGroupingType Type of grouping for multi-series values
|
||||
*/
|
||||
private function writePlotGroup(?DataSeries $plotGroup, $groupType, XMLWriter $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType): void
|
||||
private function writePlotGroup(?DataSeries $plotGroup, string $groupType, XMLWriter $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType): void
|
||||
{
|
||||
if ($plotGroup === null) {
|
||||
return;
|
||||
|
|
@ -1104,7 +1104,7 @@ class Chart extends WriterPart
|
|||
}
|
||||
|
||||
// Formatting for the points
|
||||
if (($groupType == DataSeries::TYPE_LINECHART) || ($groupType == DataSeries::TYPE_STOCKCHART)) {
|
||||
if (($groupType == DataSeries::TYPE_LINECHART) || ($groupType == DataSeries::TYPE_STOCKCHART || ($groupType === DataSeries::TYPE_SCATTERCHART && $plotSeriesValues !== false && !$plotSeriesValues->getScatterLines()))) {
|
||||
$plotLineWidth = 12700;
|
||||
if ($plotSeriesValues) {
|
||||
$plotLineWidth = $plotSeriesValues->getLineWidth();
|
||||
|
|
@ -1113,7 +1113,7 @@ class Chart extends WriterPart
|
|||
$objWriter->startElement('c:spPr');
|
||||
$objWriter->startElement('a:ln');
|
||||
$objWriter->writeAttribute('w', $plotLineWidth);
|
||||
if ($groupType == DataSeries::TYPE_STOCKCHART) {
|
||||
if ($groupType == DataSeries::TYPE_STOCKCHART || $groupType === DataSeries::TYPE_SCATTERCHART) {
|
||||
$objWriter->startElement('a:noFill');
|
||||
$objWriter->endElement();
|
||||
} elseif ($plotLabel) {
|
||||
|
|
@ -1142,6 +1142,16 @@ class Chart extends WriterPart
|
|||
$objWriter->startElement('c:size');
|
||||
$objWriter->writeAttribute('val', (string) $plotSeriesValues->getPointSize());
|
||||
$objWriter->endElement();
|
||||
$fillColor = $plotSeriesValues->getFillColor();
|
||||
if (is_string($fillColor) && $fillColor !== '') {
|
||||
$objWriter->startElement('c:spPr');
|
||||
$objWriter->startElement('a:solidFill');
|
||||
$objWriter->startElement('a:srgbClr');
|
||||
$objWriter->writeAttribute('val', $fillColor);
|
||||
$objWriter->endElement(); // srgbClr
|
||||
$objWriter->endElement(); // solidFill
|
||||
$objWriter->endElement(); // spPr
|
||||
}
|
||||
}
|
||||
|
||||
$objWriter->endElement();
|
||||
|
|
@ -1192,6 +1202,11 @@ class Chart extends WriterPart
|
|||
|
||||
$this->writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num');
|
||||
$objWriter->endElement();
|
||||
if ($groupType === DataSeries::TYPE_SCATTERCHART && $plotGroup->getPlotStyle() === 'smoothMarker') {
|
||||
$objWriter->startElement('c:smooth');
|
||||
$objWriter->writeAttribute('val', '1');
|
||||
$objWriter->endElement();
|
||||
}
|
||||
}
|
||||
|
||||
if ($groupType === DataSeries::TYPE_BUBBLECHART) {
|
||||
|
|
|
|||
|
|
@ -215,36 +215,48 @@ class StringTable extends WriterPart
|
|||
foreach ($elements as $element) {
|
||||
// r
|
||||
$objWriter->startElement($prefix . 'r');
|
||||
if ($element->getFont() !== null) {
|
||||
// rPr
|
||||
$objWriter->startElement($prefix . 'rPr');
|
||||
$size = $element->getFont()->getSize();
|
||||
if (is_numeric($size)) {
|
||||
$objWriter->writeAttribute('sz', (string) (int) ($size * 100));
|
||||
}
|
||||
|
||||
// rPr
|
||||
$objWriter->startElement($prefix . 'rPr');
|
||||
// Bold
|
||||
$objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0));
|
||||
// Italic
|
||||
$objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0));
|
||||
// Underline
|
||||
$underlineType = $element->getFont()->getUnderline();
|
||||
switch ($underlineType) {
|
||||
case 'single':
|
||||
$underlineType = 'sng';
|
||||
|
||||
// Bold
|
||||
$objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0));
|
||||
// Italic
|
||||
$objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0));
|
||||
// Underline
|
||||
$underlineType = $element->getFont()->getUnderline();
|
||||
switch ($underlineType) {
|
||||
case 'single':
|
||||
$underlineType = 'sng';
|
||||
break;
|
||||
case 'double':
|
||||
$underlineType = 'dbl';
|
||||
|
||||
break;
|
||||
case 'double':
|
||||
$underlineType = 'dbl';
|
||||
break;
|
||||
}
|
||||
$objWriter->writeAttribute('u', $underlineType);
|
||||
// Strikethrough
|
||||
$objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike'));
|
||||
|
||||
break;
|
||||
// Color
|
||||
$objWriter->startElement($prefix . 'solidFill');
|
||||
$objWriter->startElement($prefix . 'srgbClr');
|
||||
$objWriter->writeAttribute('val', $element->getFont()->getColor()->getRGB());
|
||||
$objWriter->endElement(); // srgbClr
|
||||
$objWriter->endElement(); // solidFill
|
||||
|
||||
// fontName
|
||||
$objWriter->startElement($prefix . 'latin');
|
||||
$objWriter->writeAttribute('typeface', $element->getFont()->getName());
|
||||
$objWriter->endElement();
|
||||
|
||||
$objWriter->endElement();
|
||||
}
|
||||
$objWriter->writeAttribute('u', $underlineType);
|
||||
// Strikethrough
|
||||
$objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike'));
|
||||
|
||||
// rFont
|
||||
$objWriter->startElement($prefix . 'latin');
|
||||
$objWriter->writeAttribute('typeface', $element->getFont()->getName());
|
||||
$objWriter->endElement();
|
||||
|
||||
$objWriter->endElement();
|
||||
|
||||
// t
|
||||
$objWriter->startElement($prefix . 't');
|
||||
|
|
|
|||
|
|
@ -19,10 +19,13 @@ abstract class AbstractFunctional extends TestCase
|
|||
*
|
||||
* @return Spreadsheet
|
||||
*/
|
||||
protected function writeAndReload(Spreadsheet $spreadsheet, $format, ?callable $readerCustomizer = null)
|
||||
protected function writeAndReload(Spreadsheet $spreadsheet, $format, ?callable $readerCustomizer = null, ?callable $writerCustomizer = null)
|
||||
{
|
||||
$filename = File::temporaryFilename();
|
||||
$writer = IOFactory::createWriter($spreadsheet, $format);
|
||||
if ($writerCustomizer) {
|
||||
$writerCustomizer($writer);
|
||||
}
|
||||
$writer->save($filename);
|
||||
|
||||
$reader = IOFactory::createReader($format);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,261 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
|
||||
use PhpOffice\PhpSpreadsheet\RichText\RichText;
|
||||
use PhpOffice\PhpSpreadsheet\RichText\Run;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Font;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
|
||||
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
||||
|
||||
class Charts32ScatterTest extends AbstractFunctional
|
||||
{
|
||||
private const DIRECTORY = 'samples' . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR;
|
||||
|
||||
public function readCharts(XlsxReader $reader): void
|
||||
{
|
||||
$reader->setIncludeCharts(true);
|
||||
}
|
||||
|
||||
public function writeCharts(XlsxWriter $writer): void
|
||||
{
|
||||
$writer->setIncludeCharts(true);
|
||||
}
|
||||
|
||||
public function testScatter1(): void
|
||||
{
|
||||
$file = self::DIRECTORY . '32readwriteScatterChart1.xlsx';
|
||||
$reader = new XlsxReader();
|
||||
$reader->setIncludeCharts(true);
|
||||
$spreadsheet = $reader->load($file);
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame(1, $sheet->getChartCount());
|
||||
/** @var callable */
|
||||
$callableReader = [$this, 'readCharts'];
|
||||
/** @var callable */
|
||||
$callableWriter = [$this, 'writeCharts'];
|
||||
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx', $callableReader, $callableWriter);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
|
||||
$sheet = $reloadedSpreadsheet->getActiveSheet();
|
||||
self::assertSame('Charts', $sheet->getTitle());
|
||||
$charts = $sheet->getChartCollection();
|
||||
self::assertCount(1, $charts);
|
||||
$chart = $charts[0];
|
||||
self::assertNotNull($chart);
|
||||
$title = $chart->getTitle();
|
||||
$captionArray = $title->getCaption();
|
||||
self::assertIsArray($captionArray);
|
||||
self::assertCount(1, $captionArray);
|
||||
$caption = $captionArray[0];
|
||||
self::assertInstanceOf(RichText::class, $caption);
|
||||
self::assertSame('Scatter - No Join and Markers', $caption->getPlainText());
|
||||
$elements = $caption->getRichTextElements();
|
||||
self::assertCount(1, $elements);
|
||||
$run = $elements[0];
|
||||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Calibri', $font->getName());
|
||||
self::assertEquals(12, $font->getSize());
|
||||
self::assertTrue($font->getBold());
|
||||
self::assertFalse($font->getItalic());
|
||||
self::assertFalse($font->getSuperscript());
|
||||
self::assertFalse($font->getSubscript());
|
||||
self::assertFalse($font->getStrikethrough());
|
||||
self::assertSame('none', $font->getUnderline());
|
||||
self::assertSame('000000', $font->getColor()->getRGB());
|
||||
|
||||
$plotArea = $chart->getPlotArea();
|
||||
$plotSeries = $plotArea->getPlotGroup();
|
||||
self::assertCount(1, $plotSeries);
|
||||
$dataSeries = $plotSeries[0];
|
||||
$plotValues = $dataSeries->getPlotValues();
|
||||
self::assertCount(3, $plotValues);
|
||||
$values = $plotValues[0];
|
||||
self::assertFalse($values->getScatterLines());
|
||||
self::assertSame(28575, $values->getLineWidth());
|
||||
self::assertSame(3, $values->getPointSize());
|
||||
self::assertSame('', $values->getFillColor());
|
||||
$values = $plotValues[1];
|
||||
self::assertFalse($values->getScatterLines());
|
||||
self::assertSame(28575, $values->getLineWidth());
|
||||
self::assertSame(3, $values->getPointSize());
|
||||
self::assertSame('', $values->getFillColor());
|
||||
$values = $plotValues[2];
|
||||
self::assertFalse($values->getScatterLines());
|
||||
self::assertSame(28575, $values->getLineWidth());
|
||||
self::assertSame(7, $values->getPointSize());
|
||||
self::assertSame('FFFF00', $values->getFillColor());
|
||||
|
||||
$reloadedSpreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
public function testScatter6(): void
|
||||
{
|
||||
$file = self::DIRECTORY . '32readwriteScatterChart6.xlsx';
|
||||
$reader = new XlsxReader();
|
||||
$reader->setIncludeCharts(true);
|
||||
$spreadsheet = $reader->load($file);
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame(1, $sheet->getChartCount());
|
||||
/** @var callable */
|
||||
$callableReader = [$this, 'readCharts'];
|
||||
/** @var callable */
|
||||
$callableWriter = [$this, 'writeCharts'];
|
||||
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx', $callableReader, $callableWriter);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
|
||||
$sheet = $reloadedSpreadsheet->getActiveSheet();
|
||||
self::assertSame('Charts', $sheet->getTitle());
|
||||
$charts = $sheet->getChartCollection();
|
||||
self::assertCount(1, $charts);
|
||||
$chart = $charts[0];
|
||||
self::assertNotNull($chart);
|
||||
$title = $chart->getTitle();
|
||||
$captionArray = $title->getCaption();
|
||||
self::assertIsArray($captionArray);
|
||||
self::assertCount(1, $captionArray);
|
||||
$caption = $captionArray[0];
|
||||
self::assertInstanceOf(RichText::class, $caption);
|
||||
self::assertSame('Scatter - Rich Text Title No Join and Markers', $caption->getPlainText());
|
||||
$elements = $caption->getRichTextElements();
|
||||
self::assertCount(3, $elements);
|
||||
|
||||
$run = $elements[0];
|
||||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Calibri', $font->getName());
|
||||
self::assertEquals(12, $font->getSize());
|
||||
self::assertTrue($font->getBold());
|
||||
self::assertFalse($font->getItalic());
|
||||
self::assertFalse($font->getSuperscript());
|
||||
self::assertFalse($font->getSubscript());
|
||||
self::assertFalse($font->getStrikethrough());
|
||||
self::assertSame('none', $font->getUnderline());
|
||||
self::assertSame('000000', $font->getColor()->getRGB());
|
||||
|
||||
$run = $elements[1];
|
||||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Courier New', $font->getName());
|
||||
self::assertEquals(10, $font->getSize());
|
||||
self::assertFalse($font->getBold());
|
||||
self::assertFalse($font->getItalic());
|
||||
self::assertFalse($font->getSuperscript());
|
||||
self::assertFalse($font->getSubscript());
|
||||
self::assertFalse($font->getStrikethrough());
|
||||
self::assertSame('single', $font->getUnderline());
|
||||
self::assertSame('00B0F0', $font->getColor()->getRGB());
|
||||
|
||||
$run = $elements[2];
|
||||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Calibri', $font->getName());
|
||||
self::assertEquals(12, $font->getSize());
|
||||
self::assertTrue($font->getBold());
|
||||
self::assertFalse($font->getItalic());
|
||||
self::assertFalse($font->getSuperscript());
|
||||
self::assertFalse($font->getSubscript());
|
||||
self::assertFalse($font->getStrikethrough());
|
||||
self::assertSame('none', $font->getUnderline());
|
||||
self::assertSame('000000', $font->getColor()->getRGB());
|
||||
|
||||
$plotArea = $chart->getPlotArea();
|
||||
$plotSeries = $plotArea->getPlotGroup();
|
||||
self::assertCount(1, $plotSeries);
|
||||
$dataSeries = $plotSeries[0];
|
||||
$plotValues = $dataSeries->getPlotValues();
|
||||
self::assertCount(3, $plotValues);
|
||||
$values = $plotValues[0];
|
||||
self::assertFalse($values->getScatterLines());
|
||||
self::assertSame(28575, $values->getLineWidth());
|
||||
self::assertSame(3, $values->getPointSize());
|
||||
self::assertSame('', $values->getFillColor());
|
||||
$values = $plotValues[1];
|
||||
self::assertFalse($values->getScatterLines());
|
||||
self::assertSame(28575, $values->getLineWidth());
|
||||
self::assertSame(3, $values->getPointSize());
|
||||
self::assertSame('', $values->getFillColor());
|
||||
$values = $plotValues[2];
|
||||
self::assertFalse($values->getScatterLines());
|
||||
self::assertSame(28575, $values->getLineWidth());
|
||||
self::assertSame(7, $values->getPointSize());
|
||||
self::assertSame('FFFF00', $values->getFillColor());
|
||||
|
||||
$reloadedSpreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
public function testScatter3(): void
|
||||
{
|
||||
$file = self::DIRECTORY . '32readwriteScatterChart3.xlsx';
|
||||
$reader = new XlsxReader();
|
||||
$reader->setIncludeCharts(true);
|
||||
$spreadsheet = $reader->load($file);
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame(1, $sheet->getChartCount());
|
||||
/** @var callable */
|
||||
$callableReader = [$this, 'readCharts'];
|
||||
/** @var callable */
|
||||
$callableWriter = [$this, 'writeCharts'];
|
||||
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx', $callableReader, $callableWriter);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
|
||||
$sheet = $reloadedSpreadsheet->getActiveSheet();
|
||||
self::assertSame('Charts', $sheet->getTitle());
|
||||
$charts = $sheet->getChartCollection();
|
||||
self::assertCount(1, $charts);
|
||||
$chart = $charts[0];
|
||||
self::assertNotNull($chart);
|
||||
$title = $chart->getTitle();
|
||||
$captionArray = $title->getCaption();
|
||||
self::assertIsArray($captionArray);
|
||||
self::assertCount(1, $captionArray);
|
||||
$caption = $captionArray[0];
|
||||
self::assertInstanceOf(RichText::class, $caption);
|
||||
self::assertSame('Scatter - Join Straight Lines and Markers', $caption->getPlainText());
|
||||
$elements = $caption->getRichTextElements();
|
||||
self::assertCount(1, $elements);
|
||||
$run = $elements[0];
|
||||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Calibri', $font->getName());
|
||||
self::assertEquals(12, $font->getSize());
|
||||
self::assertTrue($font->getBold());
|
||||
self::assertFalse($font->getItalic());
|
||||
self::assertFalse($font->getSuperscript());
|
||||
self::assertFalse($font->getSubscript());
|
||||
self::assertFalse($font->getStrikethrough());
|
||||
self::assertSame('none', $font->getUnderline());
|
||||
self::assertSame('000000', $font->getColor()->getRGB());
|
||||
|
||||
$plotArea = $chart->getPlotArea();
|
||||
$plotSeries = $plotArea->getPlotGroup();
|
||||
self::assertCount(1, $plotSeries);
|
||||
$dataSeries = $plotSeries[0];
|
||||
$plotValues = $dataSeries->getPlotValues();
|
||||
self::assertCount(3, $plotValues);
|
||||
$values = $plotValues[0];
|
||||
self::assertTrue($values->getScatterLines());
|
||||
self::assertSame(12700, $values->getLineWidth());
|
||||
self::assertSame(3, $values->getPointSize());
|
||||
self::assertSame('', $values->getFillColor());
|
||||
$values = $plotValues[1];
|
||||
self::assertTrue($values->getScatterLines());
|
||||
self::assertSame(12700, $values->getLineWidth());
|
||||
self::assertSame(3, $values->getPointSize());
|
||||
self::assertSame('', $values->getFillColor());
|
||||
$values = $plotValues[2];
|
||||
self::assertTrue($values->getScatterLines());
|
||||
self::assertSame(12700, $values->getLineWidth());
|
||||
self::assertSame(3, $values->getPointSize());
|
||||
self::assertSame('', $values->getFillColor());
|
||||
|
||||
$reloadedSpreadsheet->disconnectWorksheets();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\File;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class Charts32XmlTest extends TestCase
|
||||
{
|
||||
// These tests can only be performed by examining xml.
|
||||
private const DIRECTORY = 'samples' . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR;
|
||||
|
||||
/** @var string */
|
||||
private $outputFileName = '';
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
if ($this->outputFileName !== '') {
|
||||
unlink($this->outputFileName);
|
||||
$this->outputFileName = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerScatterCharts
|
||||
*/
|
||||
public function testBezierCount(int $expectedCount, string $inputFile): void
|
||||
{
|
||||
$file = self::DIRECTORY . $inputFile;
|
||||
$reader = new XlsxReader();
|
||||
$reader->setIncludeCharts(true);
|
||||
$spreadsheet = $reader->load($file);
|
||||
|
||||
$writer = new XlsxWriter($spreadsheet);
|
||||
$writer->setIncludeCharts(true);
|
||||
$this->outputFileName = File::temporaryFilename();
|
||||
$writer->save($this->outputFileName);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
|
||||
$file = 'zip://';
|
||||
$file .= $this->outputFileName;
|
||||
$file .= '#xl/charts/chart2.xml';
|
||||
$data = file_get_contents($file);
|
||||
// confirm that file contains expected tags
|
||||
if ($data === false) {
|
||||
self::fail('Unable to read file');
|
||||
} else {
|
||||
self::assertSame(1, substr_count($data, '<c:scatterStyle val='));
|
||||
self::assertSame($expectedCount ? 1 : 0, substr_count($data, '<c:scatterStyle val="smoothMarker"/>'));
|
||||
self::assertSame($expectedCount, substr_count($data, '<c:smooth val="1"/>'));
|
||||
}
|
||||
}
|
||||
|
||||
public function providerScatterCharts(): array
|
||||
{
|
||||
return [
|
||||
'no line' => [0, '32readwriteScatterChart1.xlsx'],
|
||||
'smooth line (Bezier)' => [3, '32readwriteScatterChart2.xlsx'],
|
||||
'straight line' => [0, '32readwriteScatterChart3.xlsx'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testAreaPercentageNoCat(): void
|
||||
{
|
||||
$file = self::DIRECTORY . '32readwriteAreaPercentageChart1.xlsx';
|
||||
$reader = new XlsxReader();
|
||||
$reader->setIncludeCharts(true);
|
||||
$spreadsheet = $reader->load($file);
|
||||
|
||||
$writer = new XlsxWriter($spreadsheet);
|
||||
$writer->setIncludeCharts(true);
|
||||
$this->outputFileName = File::temporaryFilename();
|
||||
$writer->save($this->outputFileName);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
|
||||
$file = 'zip://';
|
||||
$file .= $this->outputFileName;
|
||||
$file .= '#xl/charts/chart1.xml';
|
||||
$data = file_get_contents($file);
|
||||
// confirm that file contains expected tags
|
||||
if ($data === false) {
|
||||
self::fail('Unable to read file');
|
||||
} else {
|
||||
self::assertSame(0, substr_count($data, '<c:cat>'));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue