More Chart Fixes (#2841)
* More Chart Fixes Taking up where #2828 left off. Most of the following changes are demonstrated in 32readwriteChartWithImages1: - Adds support for "scheme" colors (because rgb, theme, and index colors just weren't enough for Excel) for DataSeriesValues. See issue #2299. - For chart titles (including axis labels), rather than a font name, Excel supplies a 3-fold series of font names for Latin, East Asian, and Complex Scripts. New properties `latin`, `eastAsian`, and `complexScript` are added to the Font class. I frankly have no idea how, or even if, you can set these in Excel; my test case (sample 32readwriteScatterChart7) is a result of manually editing the XML. - Add support for subscript/superscript to chart titles. This requires a new property `baseLine` in Font (positive=superscript negative=subscript baseline value says how high/low). - Support for underscore with different scheme color than its text, using a new string property `uSchemeClr` in Font. - Support for extra options for strikethrough, using a new string property `strikeType` in Font. - Support for extra options for underscore type, using the existing string property `underline` in Font. - I do not anticipate that any of the new Font properties will be used except for chart titles. - If no default font overrides are found for a Rich Text element in chart titles, and no explicit font overrides are found for a Run under such an element, the font element of the Run is set to null. - PhpSpreadsheet will always write a tag `a:pPr` and, underneath that, an empty tag `a:defRPr`, for default font settings for chart titles and axis labels. Combined with the previous bullet item, this will prevent PhpSpreadsheet from inadvertently overriding the Excel defaults (18 point bold Calibri for chart title, 10 point bold Calibri for axis labels). - Axis labels will now be written to XML in the same manner as chart titles. Among other considerations, this means that they can now have colors. Fix #2700. Supersedes PR #2701. Demonstrated in sample 32readwriteStockChart5. * Fix Some Chart Corruption Fix #2817, where @bridgeplayr gives an excellent description of the problem and how it should be solved. * Fix Bubble Charts Sample produced corrupt output - see issue #2763. After a lot of research, solution was just re-ordering of parameters in a single function call. Bubble 3D had not been supported at all. It is now. Surface Charts remain corrupted.
This commit is contained in:
parent
9d36e442e9
commit
ef031e74e1
|
|
@ -4792,7 +4792,7 @@ parameters:
|
|||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#"
|
||||
count: 44
|
||||
count: 43
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
|
||||
|
||||
-
|
||||
|
|
@ -4982,7 +4982,7 @@ parameters:
|
|||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 5
|
||||
count: 4
|
||||
path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php
|
||||
|
||||
-
|
||||
|
|
|
|||
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Axis;
|
||||
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\IOFactory;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
|
||||
require __DIR__ . '/../Header.php';
|
||||
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
// changed data to simulate a trend chart - Xaxis are dates; Yaxis are 3 meausurements from each date
|
||||
$worksheet->fromArray(
|
||||
[
|
||||
['', 'metric1', 'metric2', 'metric3'],
|
||||
['=DATEVALUE("2021-01-01")', 12.1, 15.1, 21.1],
|
||||
['=DATEVALUE("2021-01-04")', 56.2, 73.2, 86.2],
|
||||
['=DATEVALUE("2021-01-07")', 52.2, 61.2, 69.2],
|
||||
['=DATEVALUE("2021-01-10")', 30.2, 32.2, 0.2],
|
||||
]
|
||||
);
|
||||
$worksheet->getStyle('A2:A5')->getNumberFormat()->setFormatCode('yyyy-mm-dd');
|
||||
$worksheet->getColumnDimension('A')->setAutoSize(true);
|
||||
$worksheet->setSelectedCells('A1');
|
||||
|
||||
// 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), // was 2010
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // was 2011
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // was 2012
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
// changed from STRING to NUMBER
|
||||
// added 2 additional x-axis values associated with each of the 3 metrics
|
||||
// added FORMATE_CODE_NUMBER
|
||||
$xAxisTickValues = [
|
||||
//new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$A$2:$A$5', Properties::FORMAT_CODE_DATE, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$A$2:$A$5', Properties::FORMAT_CODE_DATE, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$A$2:$A$5', Properties::FORMAT_CODE_DATE, 4),
|
||||
];
|
||||
// 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
|
||||
// added FORMAT_CODE_NUMBER
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', Properties::FORMAT_CODE_NUMBER, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', Properties::FORMAT_CODE_NUMBER, 4),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', Properties::FORMAT_CODE_NUMBER, 4),
|
||||
];
|
||||
// Added so that Xaxis shows dates instead of Excel-equivalent-year1900-numbers
|
||||
$xAxis = new Axis();
|
||||
//$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE );
|
||||
$xAxis->setAxisNumberProperties('yyyy-mm-dd');
|
||||
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_SCATTERCHART, // plotType
|
||||
null, // plotGrouping (Scatter charts don't have any grouping)
|
||||
range(0, count($dataSeriesValues) - 1), // plotOrder
|
||||
$dataSeriesLabels, // plotLabel
|
||||
$xAxisTickValues, // plotCategory
|
||||
$dataSeriesValues, // plotValues
|
||||
null, // plotDirection
|
||||
null, // smooth line
|
||||
//DataSeries::STYLE_LINEMARKER // plotStyle
|
||||
DataSeries::STYLE_MARKER // plotStyle
|
||||
);
|
||||
|
||||
// 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 Scatter Trend 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
|
||||
// added xAxis for correct date display
|
||||
$xAxis, // xAxis
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('A7');
|
||||
$chart->setBottomRightPosition('N20');
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
|
||||
// Save Excel 2007 file
|
||||
$filename = $helper->getFilename(__FILE__);
|
||||
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
|
||||
$writer->setIncludeCharts(true);
|
||||
$callStartTime = microtime(true);
|
||||
$writer->save($filename);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
$helper->logWrite($writer, $filename, $callStartTime);
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -73,6 +73,9 @@ class DataSeriesValues
|
|||
*/
|
||||
private $fillColor;
|
||||
|
||||
/** @var string */
|
||||
private $schemeClr = '';
|
||||
|
||||
/**
|
||||
* Line Width.
|
||||
*
|
||||
|
|
@ -83,6 +86,9 @@ class DataSeriesValues
|
|||
/** @var bool */
|
||||
private $scatterLines = true;
|
||||
|
||||
/** @var bool */
|
||||
private $bubble3D = false;
|
||||
|
||||
/**
|
||||
* Create a new DataSeriesValues object.
|
||||
*
|
||||
|
|
@ -440,4 +446,28 @@ class DataSeriesValues
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBubble3D(): bool
|
||||
{
|
||||
return $this->bubble3D;
|
||||
}
|
||||
|
||||
public function setBubble3D(bool $bubble3D): self
|
||||
{
|
||||
$this->bubble3D = $bubble3D;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSchemeClr(): string
|
||||
{
|
||||
return $this->schemeClr;
|
||||
}
|
||||
|
||||
public function setSchemeClr(string $schemeClr): self
|
||||
{
|
||||
$this->schemeClr = $schemeClr;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -288,6 +288,8 @@ class Chart
|
|||
$lineWidth = null;
|
||||
$pointSize = null;
|
||||
$noFill = false;
|
||||
$schemeClr = '';
|
||||
$bubble3D = false;
|
||||
foreach ($seriesDetails as $seriesKey => $seriesDetail) {
|
||||
switch ($seriesKey) {
|
||||
case 'idx':
|
||||
|
|
@ -304,11 +306,16 @@ class Chart
|
|||
|
||||
break;
|
||||
case 'spPr':
|
||||
$ln = $seriesDetail->children($namespacesChartMeta['a'])->ln;
|
||||
$children = $seriesDetail->children($namespacesChartMeta['a']);
|
||||
$ln = $children->ln;
|
||||
$lineWidth = self::getAttribute($ln, 'w', 'string');
|
||||
if (is_countable($ln->noFill) && count($ln->noFill) === 1) {
|
||||
$noFill = true;
|
||||
}
|
||||
$sf = $children->solidFill->schemeClr;
|
||||
if ($sf) {
|
||||
$schemeClr = self::getAttribute($sf, 'val', 'string');
|
||||
}
|
||||
|
||||
break;
|
||||
case 'marker':
|
||||
|
|
@ -342,6 +349,10 @@ class Chart
|
|||
case 'yVal':
|
||||
$seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, "$marker", "$srgbClr", "$pointSize");
|
||||
|
||||
break;
|
||||
case 'bubble3D':
|
||||
$bubble3D = self::getAttribute($seriesDetail, 'val', 'boolean');
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -367,6 +378,28 @@ class Chart
|
|||
$seriesValues[$seriesIndex]->setLineWidth((int) $lineWidth);
|
||||
}
|
||||
}
|
||||
if ($schemeClr) {
|
||||
if (isset($seriesLabel[$seriesIndex])) {
|
||||
$seriesLabel[$seriesIndex]->setSchemeClr($schemeClr);
|
||||
}
|
||||
if (isset($seriesCategory[$seriesIndex])) {
|
||||
$seriesCategory[$seriesIndex]->setSchemeClr($schemeClr);
|
||||
}
|
||||
if (isset($seriesValues[$seriesIndex])) {
|
||||
$seriesValues[$seriesIndex]->setSchemeClr($schemeClr);
|
||||
}
|
||||
}
|
||||
if ($bubble3D) {
|
||||
if (isset($seriesLabel[$seriesIndex])) {
|
||||
$seriesLabel[$seriesIndex]->setBubble3D($bubble3D);
|
||||
}
|
||||
if (isset($seriesCategory[$seriesIndex])) {
|
||||
$seriesCategory[$seriesIndex]->setBubble3D($bubble3D);
|
||||
}
|
||||
if (isset($seriesValues[$seriesIndex])) {
|
||||
$seriesValues[$seriesIndex]->setBubble3D($bubble3D);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -514,6 +547,9 @@ class Chart
|
|||
$defaultStrikethrough = null;
|
||||
$defaultBaseline = null;
|
||||
$defaultFontName = null;
|
||||
$defaultLatin = null;
|
||||
$defaultEastAsian = null;
|
||||
$defaultComplexScript = null;
|
||||
$defaultColor = null;
|
||||
if (isset($titleDetailPart->pPr->defRPr)) {
|
||||
/** @var ?int */
|
||||
|
|
@ -528,9 +564,20 @@ class Chart
|
|||
$defaultStrikethrough = self::getAttribute($titleDetailPart->pPr->defRPr, 'strike', 'string');
|
||||
/** @var ?int */
|
||||
$defaultBaseline = self::getAttribute($titleDetailPart->pPr->defRPr, 'baseline', 'integer');
|
||||
if (isset($titleDetailPart->defRPr->rFont['val'])) {
|
||||
$defaultFontName = (string) $titleDetailPart->defRPr->rFont['val'];
|
||||
}
|
||||
if (isset($titleDetailPart->pPr->defRPr->latin)) {
|
||||
/** @var ?string */
|
||||
$defaultFontName = self::getAttribute($titleDetailPart->pPr->defRPr->latin, 'typeface', 'string');
|
||||
$defaultLatin = self::getAttribute($titleDetailPart->pPr->defRPr->latin, 'typeface', 'string');
|
||||
}
|
||||
if (isset($titleDetailPart->pPr->defRPr->ea)) {
|
||||
/** @var ?string */
|
||||
$defaultEastAsian = self::getAttribute($titleDetailPart->pPr->defRPr->ea, 'typeface', 'string');
|
||||
}
|
||||
if (isset($titleDetailPart->pPr->defRPr->cs)) {
|
||||
/** @var ?string */
|
||||
$defaultComplexScript = self::getAttribute($titleDetailPart->pPr->defRPr->cs, 'typeface', 'string');
|
||||
}
|
||||
if (isset($titleDetailPart->pPr->defRPr->solidFill->srgbClr)) {
|
||||
/** @var ?string */
|
||||
|
|
@ -538,12 +585,18 @@ class Chart
|
|||
}
|
||||
}
|
||||
foreach ($titleDetailPart as $titleDetailElementKey => $titleDetailElement) {
|
||||
if (isset($titleDetailElement->t)) {
|
||||
$objText = $value->createTextRun((string) $titleDetailElement->t);
|
||||
}
|
||||
if ($objText === null || $objText->getFont() === null) {
|
||||
if (
|
||||
(string) $titleDetailElementKey !== 'r'
|
||||
|| !isset($titleDetailElement->t)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
$objText = $value->createTextRun((string) $titleDetailElement->t);
|
||||
if ($objText->getFont() === null) {
|
||||
// @codeCoverageIgnoreStart
|
||||
continue;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
$fontSize = null;
|
||||
$bold = null;
|
||||
$italic = null;
|
||||
|
|
@ -551,15 +604,29 @@ class Chart
|
|||
$strikethrough = null;
|
||||
$baseline = null;
|
||||
$fontName = null;
|
||||
$latinName = null;
|
||||
$eastAsian = null;
|
||||
$complexScript = null;
|
||||
$fontColor = null;
|
||||
$uSchemeClr = null;
|
||||
if (isset($titleDetailElement->rPr)) {
|
||||
// not used now, not sure it ever was, grandfathering
|
||||
if (isset($titleDetailElement->rPr->rFont['val'])) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$fontName = (string) $titleDetailElement->rPr->rFont['val'];
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
if (isset($titleDetailElement->rPr->latin)) {
|
||||
/** @var ?string */
|
||||
$fontName = self::getAttribute($titleDetailElement->rPr->latin, 'typeface', 'string');
|
||||
$latinName = self::getAttribute($titleDetailElement->rPr->latin, 'typeface', 'string');
|
||||
}
|
||||
if (isset($titleDetailElement->rPr->ea)) {
|
||||
/** @var ?string */
|
||||
$eastAsian = self::getAttribute($titleDetailElement->rPr->ea, 'typeface', 'string');
|
||||
}
|
||||
if (isset($titleDetailElement->rPr->cs)) {
|
||||
/** @var ?string */
|
||||
$complexScript = self::getAttribute($titleDetailElement->rPr->cs, 'typeface', 'string');
|
||||
}
|
||||
/** @var ?int */
|
||||
$fontSize = self::getAttribute($titleDetailElement->rPr, 'sz', 'integer');
|
||||
|
|
@ -583,43 +650,72 @@ class Chart
|
|||
|
||||
/** @var ?string */
|
||||
$underscore = self::getAttribute($titleDetailElement->rPr, 'u', 'string');
|
||||
if (isset($titleDetailElement->rPr->uFill->solidFill->schemeClr)) {
|
||||
/** @var ?string */
|
||||
$uSchemeClr = self::getAttribute($titleDetailElement->rPr->uFill->solidFill->schemeClr, 'val', 'string');
|
||||
}
|
||||
|
||||
/** @var ?string */
|
||||
$strikethrough = self::getAttribute($titleDetailElement->rPr, 's', 'string');
|
||||
$strikethrough = self::getAttribute($titleDetailElement->rPr, 'strike', 'string');
|
||||
}
|
||||
|
||||
$fontFound = false;
|
||||
$latinName = $latinName ?? $defaultLatin;
|
||||
if ($latinName !== null) {
|
||||
$objText->getFont()->setLatin($latinName);
|
||||
$fontFound = true;
|
||||
}
|
||||
$eastAsian = $eastAsian ?? $defaultEastAsian;
|
||||
if ($eastAsian !== null) {
|
||||
$objText->getFont()->setEastAsian($eastAsian);
|
||||
$fontFound = true;
|
||||
}
|
||||
$complexScript = $complexScript ?? $defaultComplexScript;
|
||||
if ($complexScript !== null) {
|
||||
$objText->getFont()->setComplexScript($complexScript);
|
||||
$fontFound = true;
|
||||
}
|
||||
$fontName = $fontName ?? $defaultFontName;
|
||||
if ($fontName !== null) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$objText->getFont()->setName($fontName);
|
||||
$fontFound = true;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
$fontSize = $fontSize ?? $defaultFontSize;
|
||||
if (is_int($fontSize)) {
|
||||
$objText->getFont()->setSize(floor($fontSize / 100));
|
||||
$fontFound = true;
|
||||
}
|
||||
|
||||
$fontColor = $fontColor ?? $defaultColor;
|
||||
if ($fontColor !== null) {
|
||||
$objText->getFont()->setColor(new Color($fontColor));
|
||||
$fontFound = true;
|
||||
}
|
||||
|
||||
$bold = $bold ?? $defaultBold;
|
||||
if ($bold !== null) {
|
||||
$objText->getFont()->setBold($bold);
|
||||
$fontFound = true;
|
||||
}
|
||||
|
||||
$italic = $italic ?? $defaultItalic;
|
||||
if ($italic !== null) {
|
||||
$objText->getFont()->setItalic($italic);
|
||||
$fontFound = true;
|
||||
}
|
||||
|
||||
$baseline = $baseline ?? $defaultBaseline;
|
||||
if ($baseline !== null) {
|
||||
$objText->getFont()->setBaseLine($baseline);
|
||||
if ($baseline > 0) {
|
||||
$objText->getFont()->setSuperscript(true);
|
||||
} elseif ($baseline < 0) {
|
||||
$objText->getFont()->setSubscript(true);
|
||||
}
|
||||
$fontFound = true;
|
||||
}
|
||||
|
||||
$underscore = $underscore ?? $defaultUnderscore;
|
||||
|
|
@ -628,18 +724,29 @@ class Chart
|
|||
$objText->getFont()->setUnderline(Font::UNDERLINE_SINGLE);
|
||||
} elseif ($underscore == 'dbl') {
|
||||
$objText->getFont()->setUnderline(Font::UNDERLINE_DOUBLE);
|
||||
} elseif ($underscore !== '') {
|
||||
$objText->getFont()->setUnderline($underscore);
|
||||
} else {
|
||||
$objText->getFont()->setUnderline(Font::UNDERLINE_NONE);
|
||||
}
|
||||
$fontFound = true;
|
||||
if ($uSchemeClr) {
|
||||
$objText->getFont()->setUSchemeClr($uSchemeClr);
|
||||
}
|
||||
}
|
||||
|
||||
$strikethrough = $strikethrough ?? $defaultStrikethrough;
|
||||
if ($strikethrough !== null) {
|
||||
$objText->getFont()->setStrikeType($strikethrough);
|
||||
if ($strikethrough == 'noStrike') {
|
||||
$objText->getFont()->setStrikethrough(false);
|
||||
} else {
|
||||
$objText->getFont()->setStrikethrough(true);
|
||||
}
|
||||
$fontFound = true;
|
||||
}
|
||||
if ($fontFound === false) {
|
||||
$objText->setFont(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,29 @@ class Font extends Supervisor
|
|||
*/
|
||||
protected $name = 'Calibri';
|
||||
|
||||
/**
|
||||
* The following 6 are used only for chart titles, I think.
|
||||
*
|
||||
*@var string
|
||||
*/
|
||||
private $latin = '';
|
||||
|
||||
/** @var string */
|
||||
private $eastAsian = '';
|
||||
|
||||
/** @var string */
|
||||
private $complexScript = '';
|
||||
|
||||
/** @var int */
|
||||
private $baseLine = 0;
|
||||
|
||||
/** @var string */
|
||||
private $strikeType = '';
|
||||
|
||||
/** @var string */
|
||||
private $uSchemeClr = '';
|
||||
// end of chart title items
|
||||
|
||||
/**
|
||||
* Font Size.
|
||||
*
|
||||
|
|
@ -170,6 +193,15 @@ class Font extends Supervisor
|
|||
if (isset($styleArray['name'])) {
|
||||
$this->setName($styleArray['name']);
|
||||
}
|
||||
if (isset($styleArray['latin'])) {
|
||||
$this->setLatin($styleArray['latin']);
|
||||
}
|
||||
if (isset($styleArray['eastAsian'])) {
|
||||
$this->setEastAsian($styleArray['eastAsian']);
|
||||
}
|
||||
if (isset($styleArray['complexScript'])) {
|
||||
$this->setComplexScript($styleArray['complexScript']);
|
||||
}
|
||||
if (isset($styleArray['bold'])) {
|
||||
$this->setBold($styleArray['bold']);
|
||||
}
|
||||
|
|
@ -213,6 +245,33 @@ class Font extends Supervisor
|
|||
return $this->name;
|
||||
}
|
||||
|
||||
public function getLatin(): string
|
||||
{
|
||||
if ($this->isSupervisor) {
|
||||
return $this->getSharedComponent()->getLatin();
|
||||
}
|
||||
|
||||
return $this->latin;
|
||||
}
|
||||
|
||||
public function getEastAsian(): string
|
||||
{
|
||||
if ($this->isSupervisor) {
|
||||
return $this->getSharedComponent()->getEastAsian();
|
||||
}
|
||||
|
||||
return $this->eastAsian;
|
||||
}
|
||||
|
||||
public function getComplexScript(): string
|
||||
{
|
||||
if ($this->isSupervisor) {
|
||||
return $this->getSharedComponent()->getComplexScript();
|
||||
}
|
||||
|
||||
return $this->complexScript;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Name.
|
||||
*
|
||||
|
|
@ -235,6 +294,51 @@ class Font extends Supervisor
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setLatin(string $fontname): self
|
||||
{
|
||||
if ($fontname == '') {
|
||||
$fontname = 'Calibri';
|
||||
}
|
||||
if ($this->isSupervisor) {
|
||||
$styleArray = $this->getStyleArray(['latin' => $fontname]);
|
||||
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
|
||||
} else {
|
||||
$this->latin = $fontname;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setEastAsian(string $fontname): self
|
||||
{
|
||||
if ($fontname == '') {
|
||||
$fontname = 'Calibri';
|
||||
}
|
||||
if ($this->isSupervisor) {
|
||||
$styleArray = $this->getStyleArray(['eastAsian' => $fontname]);
|
||||
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
|
||||
} else {
|
||||
$this->eastAsian = $fontname;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setComplexScript(string $fontname): self
|
||||
{
|
||||
if ($fontname == '') {
|
||||
$fontname = 'Calibri';
|
||||
}
|
||||
if ($this->isSupervisor) {
|
||||
$styleArray = $this->getStyleArray(['complexScript' => $fontname]);
|
||||
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
|
||||
} else {
|
||||
$this->complexScript = $fontname;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Size.
|
||||
*
|
||||
|
|
@ -418,6 +522,69 @@ class Font extends Supervisor
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getBaseLine(): int
|
||||
{
|
||||
if ($this->isSupervisor) {
|
||||
return $this->getSharedComponent()->getBaseLine();
|
||||
}
|
||||
|
||||
return $this->baseLine;
|
||||
}
|
||||
|
||||
public function setBaseLine(int $baseLine): self
|
||||
{
|
||||
if ($this->isSupervisor) {
|
||||
$styleArray = $this->getStyleArray(['baseLine' => $baseLine]);
|
||||
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
|
||||
} else {
|
||||
$this->baseLine = $baseLine;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStrikeType(): string
|
||||
{
|
||||
if ($this->isSupervisor) {
|
||||
return $this->getSharedComponent()->getStrikeType();
|
||||
}
|
||||
|
||||
return $this->strikeType;
|
||||
}
|
||||
|
||||
public function setStrikeType(string $strikeType): self
|
||||
{
|
||||
if ($this->isSupervisor) {
|
||||
$styleArray = $this->getStyleArray(['strikeType' => $strikeType]);
|
||||
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
|
||||
} else {
|
||||
$this->strikeType = $strikeType;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUSchemeClr(): string
|
||||
{
|
||||
if ($this->isSupervisor) {
|
||||
return $this->getSharedComponent()->getUSchemeClr();
|
||||
}
|
||||
|
||||
return $this->uSchemeClr;
|
||||
}
|
||||
|
||||
public function setUSchemeClr(string $uSchemeClr): self
|
||||
{
|
||||
if ($this->isSupervisor) {
|
||||
$styleArray = $this->getStyleArray(['uSchemeClr' => $uSchemeClr]);
|
||||
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
|
||||
} else {
|
||||
$this->uSchemeClr = $uSchemeClr;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Underline.
|
||||
*
|
||||
|
|
@ -546,6 +713,15 @@ class Font extends Supervisor
|
|||
$this->underline .
|
||||
($this->strikethrough ? 't' : 'f') .
|
||||
$this->color->getHashCode() .
|
||||
'*' .
|
||||
$this->latin .
|
||||
'*' .
|
||||
$this->eastAsian .
|
||||
'*' .
|
||||
$this->complexScript .
|
||||
$this->strikeType .
|
||||
$this->uSchemeClr .
|
||||
(string) $this->baseLine .
|
||||
__CLASS__
|
||||
);
|
||||
}
|
||||
|
|
@ -553,12 +729,17 @@ class Font extends Supervisor
|
|||
protected function exportArray1(): array
|
||||
{
|
||||
$exportedArray = [];
|
||||
$this->exportArray2($exportedArray, 'baseLine', $this->getBaseLine());
|
||||
$this->exportArray2($exportedArray, 'bold', $this->getBold());
|
||||
$this->exportArray2($exportedArray, 'color', $this->getColor());
|
||||
$this->exportArray2($exportedArray, 'complexScript', $this->getComplexScript());
|
||||
$this->exportArray2($exportedArray, 'eastAsian', $this->getEastAsian());
|
||||
$this->exportArray2($exportedArray, 'italic', $this->getItalic());
|
||||
$this->exportArray2($exportedArray, 'latin', $this->getLatin());
|
||||
$this->exportArray2($exportedArray, 'name', $this->getName());
|
||||
$this->exportArray2($exportedArray, 'size', $this->getSize());
|
||||
$this->exportArray2($exportedArray, 'strikethrough', $this->getStrikethrough());
|
||||
$this->exportArray2($exportedArray, 'strikeType', $this->getStrikeType());
|
||||
$this->exportArray2($exportedArray, 'subscript', $this->getSubscript());
|
||||
$this->exportArray2($exportedArray, 'superscript', $this->getSuperscript());
|
||||
$this->exportArray2($exportedArray, 'underline', $this->getUnderline());
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ 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\StringHelper;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
|
||||
|
||||
|
|
@ -121,6 +121,10 @@ class Chart extends WriterPart
|
|||
$objWriter->endElement();
|
||||
|
||||
$objWriter->startElement('a:p');
|
||||
$objWriter->startElement('a:pPr');
|
||||
$objWriter->startElement('a:defRPr');
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
|
||||
$caption = $title->getCaption();
|
||||
if ((is_array($caption)) && (count($caption) > 0)) {
|
||||
|
|
@ -304,9 +308,9 @@ class Chart extends WriterPart
|
|||
|
||||
if (($chartType !== DataSeries::TYPE_PIECHART) && ($chartType !== DataSeries::TYPE_PIECHART_3D) && ($chartType !== DataSeries::TYPE_DONUTCHART)) {
|
||||
if ($chartType === DataSeries::TYPE_BUBBLECHART) {
|
||||
$this->writeValueAxis($objWriter, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $majorGridlines, $minorGridlines);
|
||||
$this->writeValueAxis($objWriter, $xAxisLabel, $chartType, $id2, $id1, $catIsMultiLevelSeries, $xAxis, $majorGridlines, $minorGridlines);
|
||||
} else {
|
||||
$this->writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $catIsMultiLevelSeries, $xAxis, ($chartType === DataSeries::TYPE_SCATTERCHART) ? 'c:valAx' : 'c:catAx');
|
||||
$this->writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $catIsMultiLevelSeries, $xAxis);
|
||||
}
|
||||
|
||||
$this->writeValueAxis($objWriter, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $yAxis, $majorGridlines, $minorGridlines);
|
||||
|
|
@ -367,9 +371,19 @@ class Chart extends WriterPart
|
|||
* @param string $id2
|
||||
* @param bool $isMultiLevelSeries
|
||||
*/
|
||||
private function writeCategoryAxis(XMLWriter $objWriter, ?Title $xAxisLabel, $id1, $id2, $isMultiLevelSeries, Axis $yAxis, string $element = 'c:catAx'): void
|
||||
private function writeCategoryAxis(XMLWriter $objWriter, ?Title $xAxisLabel, $id1, $id2, $isMultiLevelSeries, Axis $yAxis): void
|
||||
{
|
||||
$objWriter->startElement($element);
|
||||
// N.B. writeCategoryAxis may be invoked with the last parameter($yAxis) using $xAxis for ScatterChart, etc
|
||||
// In that case, xAxis is NOT a category.
|
||||
$AxisFormat = $yAxis->getAxisNumberFormat();
|
||||
if (
|
||||
$AxisFormat === Properties::FORMAT_CODE_DATE
|
||||
|| $AxisFormat == Properties::FORMAT_CODE_NUMBER
|
||||
) {
|
||||
$objWriter->startElement('c:valAx');
|
||||
} else {
|
||||
$objWriter->startElement('c:catAx');
|
||||
}
|
||||
|
||||
if ($id1 > 0) {
|
||||
$objWriter->startElement('c:axId');
|
||||
|
|
@ -403,20 +417,20 @@ class Chart extends WriterPart
|
|||
$objWriter->endElement();
|
||||
|
||||
$objWriter->startElement('a:p');
|
||||
$objWriter->startElement('a:r');
|
||||
$objWriter->startElement('a:pPr');
|
||||
$objWriter->startElement('a:defRPr');
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
|
||||
$caption = $xAxisLabel->getCaption();
|
||||
if (is_array($caption)) {
|
||||
$caption = $caption[0];
|
||||
}
|
||||
$objWriter->startElement('a:t');
|
||||
$objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($caption));
|
||||
$objWriter->endElement();
|
||||
$this->getParentWriter()->getWriterPartstringtable()->writeRichTextForCharts($objWriter, $caption, 'a');
|
||||
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
|
||||
$layout = $xAxisLabel->getLayout();
|
||||
$this->writeLayout($objWriter, $layout);
|
||||
|
|
@ -746,18 +760,17 @@ class Chart extends WriterPart
|
|||
$objWriter->endElement();
|
||||
|
||||
$objWriter->startElement('a:p');
|
||||
$objWriter->startElement('a:r');
|
||||
$objWriter->startElement('a:pPr');
|
||||
$objWriter->startElement('a:defRPr');
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
|
||||
$caption = $yAxisLabel->getCaption();
|
||||
if (is_array($caption)) {
|
||||
$caption = $caption[0];
|
||||
}
|
||||
$this->getParentWriter()->getWriterPartstringtable()->writeRichTextForCharts($objWriter, $caption, 'a');
|
||||
|
||||
$objWriter->startElement('a:t');
|
||||
$objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($caption));
|
||||
$objWriter->endElement();
|
||||
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
|
|
@ -1104,13 +1117,26 @@ class Chart extends WriterPart
|
|||
}
|
||||
|
||||
// Formatting for the points
|
||||
if (($groupType == DataSeries::TYPE_LINECHART) || ($groupType == DataSeries::TYPE_STOCKCHART || ($groupType === DataSeries::TYPE_SCATTERCHART && $plotSeriesValues !== false && !$plotSeriesValues->getScatterLines()))) {
|
||||
if (
|
||||
$groupType == DataSeries::TYPE_LINECHART
|
||||
|| $groupType == DataSeries::TYPE_STOCKCHART
|
||||
|| ($groupType === DataSeries::TYPE_SCATTERCHART && $plotSeriesValues !== false && !$plotSeriesValues->getScatterLines())
|
||||
|| ($plotSeriesValues !== false && $plotSeriesValues->getSchemeClr())
|
||||
) {
|
||||
$plotLineWidth = 12700;
|
||||
if ($plotSeriesValues) {
|
||||
$plotLineWidth = $plotSeriesValues->getLineWidth();
|
||||
}
|
||||
|
||||
$objWriter->startElement('c:spPr');
|
||||
$schemeClr = $plotLabel ? $plotLabel->getSchemeClr() : null;
|
||||
if ($schemeClr) {
|
||||
$objWriter->startElement('a:solidFill');
|
||||
$objWriter->startElement('a:schemeClr');
|
||||
$objWriter->writeAttribute('val', $schemeClr);
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
}
|
||||
$objWriter->startElement('a:ln');
|
||||
$objWriter->writeAttribute('w', $plotLineWidth);
|
||||
if ($groupType == DataSeries::TYPE_STOCKCHART || $groupType === DataSeries::TYPE_SCATTERCHART) {
|
||||
|
|
@ -1186,7 +1212,14 @@ class Chart extends WriterPart
|
|||
$objWriter->startElement('c:cat');
|
||||
}
|
||||
|
||||
$this->writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str');
|
||||
// xVals (Categories) are not always 'str'
|
||||
// Test X-axis Label's Datatype to decide 'str' vs 'num'
|
||||
$CategoryDatatype = $plotSeriesCategory->getDataType();
|
||||
if ($CategoryDatatype == DataSeriesValues::DATASERIES_TYPE_NUMBER) {
|
||||
$this->writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'num');
|
||||
} else {
|
||||
$this->writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str');
|
||||
}
|
||||
$objWriter->endElement();
|
||||
}
|
||||
|
||||
|
|
@ -1377,7 +1410,7 @@ class Chart extends WriterPart
|
|||
$objWriter->endElement();
|
||||
|
||||
$objWriter->startElement('c:bubble3D');
|
||||
$objWriter->writeAttribute('val', 0);
|
||||
$objWriter->writeAttribute('val', $plotSeriesValues->getBubble3D() ? '1' : '0');
|
||||
$objWriter->endElement();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -203,7 +203,8 @@ class StringTable extends WriterPart
|
|||
if (!$richText instanceof RichText) {
|
||||
$textRun = $richText;
|
||||
$richText = new RichText();
|
||||
$richText->createTextRun($textRun);
|
||||
$run = $richText->createTextRun($textRun);
|
||||
$run->setFont(null);
|
||||
}
|
||||
|
||||
if ($prefix !== null) {
|
||||
|
|
@ -241,7 +242,11 @@ class StringTable extends WriterPart
|
|||
}
|
||||
$objWriter->writeAttribute('u', $underlineType);
|
||||
// Strikethrough
|
||||
$objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike'));
|
||||
$objWriter->writeAttribute('strike', ($element->getFont()->getStriketype() ?: 'noStrike'));
|
||||
// Superscript/subscript
|
||||
if ($element->getFont()->getBaseLine()) {
|
||||
$objWriter->writeAttribute('baseline', (string) $element->getFont()->getBaseLine());
|
||||
}
|
||||
|
||||
// Color
|
||||
$objWriter->startElement($prefix . 'solidFill');
|
||||
|
|
@ -250,10 +255,33 @@ class StringTable extends WriterPart
|
|||
$objWriter->endElement(); // srgbClr
|
||||
$objWriter->endElement(); // solidFill
|
||||
|
||||
// Underscore Color
|
||||
if ($element->getFont()->getUSchemeClr()) {
|
||||
$objWriter->startElement($prefix . 'uFill');
|
||||
$objWriter->startElement($prefix . 'solidFill');
|
||||
$objWriter->startElement($prefix . 'schemeClr');
|
||||
$objWriter->writeAttribute('val', $element->getFont()->getUSchemeClr());
|
||||
$objWriter->endElement(); // schemeClr
|
||||
$objWriter->endElement(); // solidFill
|
||||
$objWriter->endElement(); // uFill
|
||||
}
|
||||
|
||||
// fontName
|
||||
$objWriter->startElement($prefix . 'latin');
|
||||
$objWriter->writeAttribute('typeface', $element->getFont()->getName());
|
||||
$objWriter->endElement();
|
||||
if ($element->getFont()->getLatin()) {
|
||||
$objWriter->startElement($prefix . 'latin');
|
||||
$objWriter->writeAttribute('typeface', $element->getFont()->getLatin());
|
||||
$objWriter->endElement();
|
||||
}
|
||||
if ($element->getFont()->getEastAsian()) {
|
||||
$objWriter->startElement($prefix . 'ea');
|
||||
$objWriter->writeAttribute('typeface', $element->getFont()->getEastAsian());
|
||||
$objWriter->endElement();
|
||||
}
|
||||
if ($element->getFont()->getComplexScript()) {
|
||||
$objWriter->startElement($prefix . 'cs');
|
||||
$objWriter->writeAttribute('typeface', $element->getFont()->getComplexScript());
|
||||
$objWriter->endElement();
|
||||
}
|
||||
|
||||
$objWriter->endElement();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
<?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 Charts32ColoredAxisLabelTest 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 testStock5(): void
|
||||
{
|
||||
$file = self::DIRECTORY . '32readwriteStockChart5.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);
|
||||
|
||||
$xAxisLabel = $chart->getXAxisLabel();
|
||||
$captionArray = $xAxisLabel->getCaption();
|
||||
self::assertIsArray($captionArray);
|
||||
self::assertCount(1, $captionArray);
|
||||
$caption = $captionArray[0];
|
||||
self::assertInstanceOf(RichText::class, $caption);
|
||||
self::assertSame('X-Axis Title in Green', $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('00B050', $font->getColor()->getRGB());
|
||||
|
||||
$yAxisLabel = $chart->getYAxisLabel();
|
||||
$captionArray = $yAxisLabel->getCaption();
|
||||
self::assertIsArray($captionArray);
|
||||
self::assertCount(1, $captionArray);
|
||||
$caption = $captionArray[0];
|
||||
self::assertInstanceOf(RichText::class, $caption);
|
||||
self::assertSame('Y-Axis Title in Red', $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('FF0000', $font->getColor()->getRGB());
|
||||
|
||||
$reloadedSpreadsheet->disconnectWorksheets();
|
||||
}
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ class Charts32ScatterTest extends AbstractFunctional
|
|||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Calibri', $font->getName());
|
||||
self::assertSame('Calibri', $font->getLatin());
|
||||
self::assertEquals(12, $font->getSize());
|
||||
self::assertTrue($font->getBold());
|
||||
self::assertFalse($font->getItalic());
|
||||
|
|
@ -127,7 +127,7 @@ class Charts32ScatterTest extends AbstractFunctional
|
|||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Calibri', $font->getName());
|
||||
self::assertSame('Calibri', $font->getLatin());
|
||||
self::assertEquals(12, $font->getSize());
|
||||
self::assertTrue($font->getBold());
|
||||
self::assertFalse($font->getItalic());
|
||||
|
|
@ -141,7 +141,7 @@ class Charts32ScatterTest extends AbstractFunctional
|
|||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Courier New', $font->getName());
|
||||
self::assertSame('Courier New', $font->getLatin());
|
||||
self::assertEquals(10, $font->getSize());
|
||||
self::assertFalse($font->getBold());
|
||||
self::assertFalse($font->getItalic());
|
||||
|
|
@ -155,7 +155,7 @@ class Charts32ScatterTest extends AbstractFunctional
|
|||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Calibri', $font->getName());
|
||||
self::assertSame('Calibri', $font->getLatin());
|
||||
self::assertEquals(12, $font->getSize());
|
||||
self::assertTrue($font->getBold());
|
||||
self::assertFalse($font->getItalic());
|
||||
|
|
@ -224,7 +224,7 @@ class Charts32ScatterTest extends AbstractFunctional
|
|||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Calibri', $font->getName());
|
||||
self::assertSame('Calibri', $font->getLatin());
|
||||
self::assertEquals(12, $font->getSize());
|
||||
self::assertTrue($font->getBold());
|
||||
self::assertFalse($font->getItalic());
|
||||
|
|
@ -258,4 +258,76 @@ class Charts32ScatterTest extends AbstractFunctional
|
|||
|
||||
$reloadedSpreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
public function testScatter7(): void
|
||||
{
|
||||
$file = self::DIRECTORY . '32readwriteScatterChart7.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('Latin/EA/CS Title ABCאבגDEFァ', $caption->getPlainText());
|
||||
$elements = $caption->getRichTextElements();
|
||||
self::assertGreaterThan(0, count($elements));
|
||||
foreach ($elements as $run) {
|
||||
self::assertInstanceOf(Run::class, $run);
|
||||
$font = $run->getFont();
|
||||
self::assertInstanceOf(Font::class, $font);
|
||||
self::assertSame('Times New Roman', $font->getLatin());
|
||||
self::assertSame('Malgun Gothic', $font->getEastAsian());
|
||||
self::assertSame('Courier New', $font->getComplexScript());
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue