mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-18 05:57:33 +00:00
More Display Options for Chart Axis and Legend (#3434)
* Allow Color and Effects on Data Points on Chart Axis Fix #3414. There had been no way to do this. It is now supported via a new AxisText class, which derives from Properties, and has FillColor and effects (glow/shadow/softEdges) properties. The code changes in chart sample 33_Chart_create_scatter2 illustrate usage. * Minor Performance Improvement May also get rid of Scrutinizer complaint. * Eliminate New Spacing Patch No need for it. * Add Legend Formatting to Change Much in common with Data Point formatting.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Axis as ChartAxis;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\AxisText;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Chart;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
|
||||
@@ -89,9 +90,9 @@ $dataSeriesValues[0]->setLineStyleProperties(
|
||||
Properties::LINE_STYLE_CAP_SQUARE, // cap
|
||||
Properties::LINE_STYLE_JOIN_MITER, // join
|
||||
Properties::LINE_STYLE_ARROW_TYPE_OPEN, // head type
|
||||
Properties::LINE_STYLE_ARROW_SIZE_4, // head size preset index
|
||||
(string) Properties::LINE_STYLE_ARROW_SIZE_4, // head size preset index
|
||||
Properties::LINE_STYLE_ARROW_TYPE_ARROW, // end type
|
||||
Properties::LINE_STYLE_ARROW_SIZE_6 // end size preset index
|
||||
(string) Properties::LINE_STYLE_ARROW_SIZE_6 // end size preset index
|
||||
);
|
||||
|
||||
// series 2 - straight line - no special effects, connected, straight line
|
||||
@@ -124,7 +125,10 @@ $dataSeriesValues[2]->setScatterLines(false); // points not connected
|
||||
$xAxis = new ChartAxis();
|
||||
//$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE );
|
||||
$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE_ISO8601, true);
|
||||
$xAxis->setAxisOption('textRotation', '45');
|
||||
//$xAxis->setAxisOption('textRotation', '45');
|
||||
$xAxisText = new AxisText();
|
||||
$xAxisText->setRotation(45)->getFillColorObject()->setValue('00FF00')->setType(ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
$xAxis->setAxisText($xAxisText);
|
||||
|
||||
$yAxis = new ChartAxis();
|
||||
$yAxis->setLineStyleProperties(
|
||||
@@ -135,6 +139,9 @@ $yAxis->setLineStyleProperties(
|
||||
Properties::LINE_STYLE_JOIN_BEVEL
|
||||
);
|
||||
$yAxis->setLineColorProperties('ffc000', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
$yAxisText = new AxisText();
|
||||
$yAxisText->setGlowProperties(20.0, 'accent1', 20, ChartColor::EXCEL_COLOR_TYPE_SCHEME);
|
||||
$yAxis->setAxisText($yAxisText);
|
||||
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Chart\AxisText;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Chart;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Legend as ChartLegend;
|
||||
@@ -80,6 +82,12 @@ $series = new DataSeries(
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
// Set the chart legend
|
||||
$legend = new ChartLegend(ChartLegend::POSITION_RIGHT, null, false);
|
||||
$legend->getBorderColor()->setColorProperties('ffc000');
|
||||
$legend->getFillColor()->setColorProperties('cccccc');
|
||||
$legendText = new AxisText();
|
||||
$legendText->getFillColorObject()->setValue('008080')->setType(ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
$legendText->setShadowProperties(1);
|
||||
$legend->setLegendText($legendText);
|
||||
|
||||
$title = new Title('Test Stock Chart');
|
||||
$xAxisLabel = new Title('Counts');
|
||||
@@ -103,6 +111,7 @@ $chart->setBottomRightPosition('H20');
|
||||
|
||||
// Add the chart to the worksheet
|
||||
$worksheet->addChart($chart);
|
||||
$worksheet->setSelectedCells('G2');
|
||||
|
||||
// Save Excel 2007 file
|
||||
$filename = $helper->getFilename(__FILE__);
|
||||
|
||||
@@ -52,6 +52,9 @@ class Axis extends Properties
|
||||
/** @var string */
|
||||
private $axisType = '';
|
||||
|
||||
/** @var ?AxisText */
|
||||
private $axisText;
|
||||
|
||||
/**
|
||||
* Axis Options.
|
||||
*
|
||||
@@ -183,6 +186,14 @@ class Axis extends Properties
|
||||
*/
|
||||
public function getAxisOptionsProperty($property)
|
||||
{
|
||||
if ($property === 'textRotation') {
|
||||
if ($this->axisText !== null) {
|
||||
if ($this->axisText->getRotation() !== null) {
|
||||
return (string) $this->axisText->getRotation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->axisOptions[$property];
|
||||
}
|
||||
|
||||
@@ -295,4 +306,16 @@ class Axis extends Properties
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAxisText(): ?AxisText
|
||||
{
|
||||
return $this->axisText;
|
||||
}
|
||||
|
||||
public function setAxisText(?AxisText $axisText): self
|
||||
{
|
||||
$this->axisText = $axisText;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Chart;
|
||||
|
||||
class AxisText extends Properties
|
||||
{
|
||||
/** @var ?int */
|
||||
private $rotation;
|
||||
|
||||
/** @var ChartColor */
|
||||
private $fillColor;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->fillColor = new ChartColor();
|
||||
}
|
||||
|
||||
public function setRotation(?int $rotation): self
|
||||
{
|
||||
$this->rotation = $rotation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRotation(): ?int
|
||||
{
|
||||
return $this->rotation;
|
||||
}
|
||||
|
||||
public function getFillColorObject(): ChartColor
|
||||
{
|
||||
return $this->fillColor;
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,15 @@ class Legend
|
||||
*/
|
||||
private $layout;
|
||||
|
||||
/** @var ChartColor */
|
||||
private $borderColor;
|
||||
|
||||
/** @var ChartColor */
|
||||
private $fillColor;
|
||||
|
||||
/** @var ?AxisText */
|
||||
private $legendText;
|
||||
|
||||
/**
|
||||
* Create a new Legend.
|
||||
*
|
||||
@@ -60,6 +69,18 @@ class Legend
|
||||
$this->setPosition($position);
|
||||
$this->layout = $layout;
|
||||
$this->setOverlay($overlay);
|
||||
$this->borderColor = new ChartColor();
|
||||
$this->fillColor = new ChartColor();
|
||||
}
|
||||
|
||||
public function getBorderColor(): ChartColor
|
||||
{
|
||||
return $this->borderColor;
|
||||
}
|
||||
|
||||
public function getFillColor(): ChartColor
|
||||
{
|
||||
return $this->fillColor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,4 +169,16 @@ class Legend
|
||||
{
|
||||
return $this->layout;
|
||||
}
|
||||
|
||||
public function getLegendText(): ?AxisText
|
||||
{
|
||||
return $this->legendText;
|
||||
}
|
||||
|
||||
public function setLegendText(?AxisText $legendText): self
|
||||
{
|
||||
$this->legendText = $legendText;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Axis;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\AxisText;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
|
||||
@@ -350,6 +351,10 @@ class Chart
|
||||
$legendPos = 'r';
|
||||
$legendLayout = null;
|
||||
$legendOverlay = false;
|
||||
$legendBorderColor = null;
|
||||
$legendFillColor = null;
|
||||
$legendText = null;
|
||||
$addLegendText = false;
|
||||
foreach ($chartDetails as $chartDetailKey => $chartDetail) {
|
||||
$chartDetail = Xlsx::testSimpleXml($chartDetail);
|
||||
switch ($chartDetailKey) {
|
||||
@@ -364,10 +369,44 @@ class Chart
|
||||
case 'layout':
|
||||
$legendLayout = $this->chartLayoutDetails($chartDetail);
|
||||
|
||||
break;
|
||||
case 'spPr':
|
||||
$children = $chartDetails->spPr->children($this->aNamespace);
|
||||
if (isset($children->solidFill)) {
|
||||
$legendFillColor = $this->readColor($children->solidFill);
|
||||
}
|
||||
if (isset($children->ln->solidFill)) {
|
||||
$legendBorderColor = $this->readColor($children->ln->solidFill);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'txPr':
|
||||
$children = $chartDetails->txPr->children($this->aNamespace);
|
||||
$addLegendText = false;
|
||||
$legendText = new AxisText();
|
||||
if (isset($children->p->pPr->defRPr->solidFill)) {
|
||||
$colorArray = $this->readColor($children->p->pPr->defRPr->solidFill);
|
||||
$legendText->getFillColorObject()->setColorPropertiesArray($colorArray);
|
||||
$addLegendText = true;
|
||||
}
|
||||
if (isset($children->p->pPr->defRPr->effectLst)) {
|
||||
$this->readEffects($children->p->pPr->defRPr, $legendText, false);
|
||||
$addLegendText = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
$legend = new Legend("$legendPos", $legendLayout, (bool) $legendOverlay);
|
||||
if ($legendFillColor !== null) {
|
||||
$legend->getFillColor()->setColorPropertiesArray($legendFillColor);
|
||||
}
|
||||
if ($legendBorderColor !== null) {
|
||||
$legend->getBorderColor()->setColorPropertiesArray($legendBorderColor);
|
||||
}
|
||||
if ($addLegendText) {
|
||||
$legend->setLegendText($legendText);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1176,13 +1215,19 @@ class Chart
|
||||
}
|
||||
}
|
||||
|
||||
private function readEffects(SimpleXMLElement $chartDetail, ?ChartProperties $chartObject): void
|
||||
private function readEffects(SimpleXMLElement $chartDetail, ?ChartProperties $chartObject, bool $getSppr = true): void
|
||||
{
|
||||
if (!isset($chartObject, $chartDetail->spPr)) {
|
||||
if (!isset($chartObject)) {
|
||||
return;
|
||||
}
|
||||
$sppr = $chartDetail->spPr->children($this->aNamespace);
|
||||
|
||||
if ($getSppr) {
|
||||
if (!isset($chartDetail->spPr)) {
|
||||
return;
|
||||
}
|
||||
$sppr = $chartDetail->spPr->children($this->aNamespace);
|
||||
} else {
|
||||
$sppr = $chartDetail;
|
||||
}
|
||||
if (isset($sppr->effectLst->glow)) {
|
||||
$axisGlowSize = (float) self::getAttribute($sppr->effectLst->glow, 'rad', 'integer') / ChartProperties::POINTS_WIDTH_MULTIPLIER;
|
||||
if ($axisGlowSize != 0.0) {
|
||||
@@ -1412,13 +1457,28 @@ class Chart
|
||||
}
|
||||
if (isset($chartDetail->txPr)) {
|
||||
$children = $chartDetail->txPr->children($this->aNamespace);
|
||||
$addAxisText = false;
|
||||
$axisText = new AxisText();
|
||||
if (isset($children->bodyPr)) {
|
||||
/** @var string */
|
||||
$textRotation = self::getAttribute($children->bodyPr, 'rot', 'string');
|
||||
if (is_numeric($textRotation)) {
|
||||
$whichAxis->setAxisOption('textRotation', (string) ChartProperties::xmlToAngle($textRotation));
|
||||
$axisText->setRotation((int) ChartProperties::xmlToAngle($textRotation));
|
||||
$addAxisText = true;
|
||||
}
|
||||
}
|
||||
if (isset($children->p->pPr->defRPr->solidFill)) {
|
||||
$colorArray = $this->readColor($children->p->pPr->defRPr->solidFill);
|
||||
$axisText->getFillColorObject()->setColorPropertiesArray($colorArray);
|
||||
$addAxisText = true;
|
||||
}
|
||||
if (isset($children->p->pPr->defRPr->effectLst)) {
|
||||
$this->readEffects($children->p->pPr->defRPr, $axisText, false);
|
||||
$addAxisText = true;
|
||||
}
|
||||
if ($addAxisText) {
|
||||
$whichAxis->setAxisText($axisText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,6 +201,22 @@ class Chart extends WriterPart
|
||||
$objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0');
|
||||
$objWriter->endElement();
|
||||
|
||||
$fillColor = $legend->getFillColor();
|
||||
$borderColor = $legend->getBorderColor();
|
||||
if ($fillColor->isUsable() || $borderColor->isUsable()) {
|
||||
$objWriter->startElement('c:spPr');
|
||||
if ($fillColor->isUsable()) {
|
||||
$this->writeColor($objWriter, $fillColor);
|
||||
}
|
||||
if ($borderColor->isUsable()) {
|
||||
$objWriter->startElement('a:ln');
|
||||
$this->writeColor($objWriter, $borderColor);
|
||||
$objWriter->endElement(); // a:ln
|
||||
}
|
||||
$objWriter->endElement(); // c:spPr
|
||||
}
|
||||
|
||||
$legendText = $legend->getLegendText();
|
||||
$objWriter->startElement('c:txPr');
|
||||
$objWriter->startElement('a:bodyPr');
|
||||
$objWriter->endElement();
|
||||
@@ -213,17 +229,21 @@ class Chart extends WriterPart
|
||||
$objWriter->writeAttribute('rtl', '0');
|
||||
|
||||
$objWriter->startElement('a:defRPr');
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
if ($legendText !== null) {
|
||||
$this->writeColor($objWriter, $legendText->getFillColorObject());
|
||||
$this->writeEffects($objWriter, $legendText);
|
||||
}
|
||||
$objWriter->endElement(); // a:defRpr
|
||||
$objWriter->endElement(); // a:pPr
|
||||
|
||||
$objWriter->startElement('a:endParaRPr');
|
||||
$objWriter->writeAttribute('lang', 'en-US');
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement(); // a:endParaRPr
|
||||
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement(); // a:p
|
||||
$objWriter->endElement(); // c:txPr
|
||||
|
||||
$objWriter->endElement();
|
||||
$objWriter->endElement(); // c:legend
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -608,16 +628,24 @@ class Chart extends WriterPart
|
||||
}
|
||||
|
||||
$textRotation = $yAxis->getAxisOptionsProperty('textRotation');
|
||||
if (is_numeric($textRotation)) {
|
||||
$axisText = $yAxis->getAxisText();
|
||||
|
||||
if ($axisText !== null || is_numeric($textRotation)) {
|
||||
$objWriter->startElement('c:txPr');
|
||||
$objWriter->startElement('a:bodyPr');
|
||||
$objWriter->writeAttribute('rot', Properties::angleToXml((float) $textRotation));
|
||||
if (is_numeric($textRotation)) {
|
||||
$objWriter->writeAttribute('rot', Properties::angleToXml((float) $textRotation));
|
||||
}
|
||||
$objWriter->endElement(); // a:bodyPr
|
||||
$objWriter->startElement('a:lstStyle');
|
||||
$objWriter->endElement(); // a:lstStyle
|
||||
$objWriter->startElement('a:p');
|
||||
$objWriter->startElement('a:pPr');
|
||||
$objWriter->startElement('a:defRPr');
|
||||
if ($axisText !== null) {
|
||||
$this->writeColor($objWriter, $axisText->getFillColorObject());
|
||||
$this->writeEffects($objWriter, $axisText);
|
||||
}
|
||||
$objWriter->endElement(); // a:defRPr
|
||||
$objWriter->endElement(); // a:pPr
|
||||
$objWriter->endElement(); // a:p
|
||||
@@ -826,16 +854,24 @@ class Chart extends WriterPart
|
||||
}
|
||||
|
||||
$textRotation = $xAxis->getAxisOptionsProperty('textRotation');
|
||||
if (is_numeric($textRotation)) {
|
||||
$axisText = $xAxis->getAxisText();
|
||||
|
||||
if ($axisText !== null || is_numeric($textRotation)) {
|
||||
$objWriter->startElement('c:txPr');
|
||||
$objWriter->startElement('a:bodyPr');
|
||||
$objWriter->writeAttribute('rot', Properties::angleToXml((float) $textRotation));
|
||||
if (is_numeric($textRotation)) {
|
||||
$objWriter->writeAttribute('rot', Properties::angleToXml((float) $textRotation));
|
||||
}
|
||||
$objWriter->endElement(); // a:bodyPr
|
||||
$objWriter->startElement('a:lstStyle');
|
||||
$objWriter->endElement(); // a:lstStyle
|
||||
$objWriter->startElement('a:p');
|
||||
$objWriter->startElement('a:pPr');
|
||||
$objWriter->startElement('a:defRPr');
|
||||
if ($axisText !== null) {
|
||||
$this->writeColor($objWriter, $axisText->getFillColorObject());
|
||||
$this->writeEffects($objWriter, $axisText);
|
||||
}
|
||||
$objWriter->endElement(); // a:defRPr
|
||||
$objWriter->endElement(); // a:pPr
|
||||
$objWriter->endElement(); // a:p
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Chart;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Axis as ChartAxis;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\AxisText;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Chart;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
|
||||
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 DataSeriesColorTest extends AbstractFunctional
|
||||
{
|
||||
// based on 33_Char_create_scatter2
|
||||
public function readCharts(XlsxReader $reader): void
|
||||
{
|
||||
$reader->setIncludeCharts(true);
|
||||
}
|
||||
|
||||
public function writeCharts(XlsxWriter $writer): void
|
||||
{
|
||||
$writer->setIncludeCharts(true);
|
||||
}
|
||||
|
||||
public function testDataSeriesValues(): void
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
// changed data to simulate a trend chart - Xaxis are dates; Yaxis are 3 measurements 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(Properties::FORMAT_CODE_DATE_ISO8601);
|
||||
$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),
|
||||
];
|
||||
|
||||
// series 1
|
||||
// marker details
|
||||
$dataSeriesValues[0]
|
||||
->setPointMarker('diamond')
|
||||
->setPointSize(5)
|
||||
->getMarkerFillColor()
|
||||
->setColorProperties('0070C0', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
$dataSeriesValues[0]
|
||||
->getMarkerBorderColor()
|
||||
->setColorProperties('002060', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
|
||||
// line details - smooth line, connected
|
||||
$dataSeriesValues[0]
|
||||
->setScatterLines(true)
|
||||
->setSmoothLine(true)
|
||||
->setLineColorProperties('accent1', 40, ChartColor::EXCEL_COLOR_TYPE_SCHEME); // value, alpha, type
|
||||
$dataSeriesValues[0]->setLineStyleProperties(
|
||||
2.5, // width in points
|
||||
Properties::LINE_STYLE_COMPOUND_TRIPLE, // compound
|
||||
Properties::LINE_STYLE_DASH_SQUARE_DOT, // dash
|
||||
Properties::LINE_STYLE_CAP_SQUARE, // cap
|
||||
Properties::LINE_STYLE_JOIN_MITER, // join
|
||||
Properties::LINE_STYLE_ARROW_TYPE_OPEN, // head type
|
||||
(string) Properties::LINE_STYLE_ARROW_SIZE_4, // head size preset index
|
||||
Properties::LINE_STYLE_ARROW_TYPE_ARROW, // end type
|
||||
(string) Properties::LINE_STYLE_ARROW_SIZE_6 // end size preset index
|
||||
);
|
||||
|
||||
// series 2 - straight line - no special effects, connected, straight line
|
||||
$dataSeriesValues[1] // square fill
|
||||
->setPointMarker('square')
|
||||
->setPointSize(6)
|
||||
->getMarkerBorderColor()
|
||||
->setColorProperties('accent6', 3, ChartColor::EXCEL_COLOR_TYPE_SCHEME);
|
||||
$dataSeriesValues[1] // square border
|
||||
->getMarkerFillColor()
|
||||
->setColorProperties('0FFF00', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
$dataSeriesValues[1]
|
||||
->setScatterLines(true)
|
||||
->setSmoothLine(false)
|
||||
->setLineColorProperties('FF0000', 80, ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
$dataSeriesValues[1]->setLineWidth(2.0);
|
||||
|
||||
// series 3 - markers, no line
|
||||
$dataSeriesValues[2] // triangle fill
|
||||
//->setPointMarker('triangle') // let Excel choose shape
|
||||
->setPointSize(7)
|
||||
->getMarkerFillColor()
|
||||
->setColorProperties('FFFF00', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
$dataSeriesValues[2] // triangle border
|
||||
->getMarkerBorderColor()
|
||||
->setColorProperties('accent4', null, ChartColor::EXCEL_COLOR_TYPE_SCHEME);
|
||||
$dataSeriesValues[2]->setScatterLines(false); // points not connected
|
||||
|
||||
// Added so that Xaxis shows dates instead of Excel-equivalent-year1900-numbers
|
||||
$xAxis = new ChartAxis();
|
||||
//$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE );
|
||||
$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE_ISO8601, true);
|
||||
//$xAxis->setAxisOption('textRotation', '45');
|
||||
$xAxisText = new AxisText();
|
||||
$xAxisText->setRotation(45)->getFillColorObject()->setValue('00FF00')->setType(ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
$xAxis->setAxisText($xAxisText);
|
||||
|
||||
$yAxis = new ChartAxis();
|
||||
$yAxis->setLineStyleProperties(
|
||||
2.5, // width in points
|
||||
Properties::LINE_STYLE_COMPOUND_SIMPLE,
|
||||
Properties::LINE_STYLE_DASH_DASH_DOT,
|
||||
Properties::LINE_STYLE_CAP_FLAT,
|
||||
Properties::LINE_STYLE_JOIN_BEVEL
|
||||
);
|
||||
$yAxis->setLineColorProperties('ffc000', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
$yAxisText = new AxisText();
|
||||
$yAxisText->setGlowProperties(20.0, 'accent1', 20, ChartColor::EXCEL_COLOR_TYPE_SCHEME);
|
||||
$yAxis->setAxisText($yAxisText);
|
||||
|
||||
// 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
|
||||
false, // smooth line
|
||||
DataSeries::STYLE_SMOOTHMARKER // 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
|
||||
$yAxis, // yAxis
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('A7');
|
||||
$chart->setBottomRightPosition('P20');
|
||||
|
||||
// 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);
|
||||
$xAxisText = $chart2->getChartAxisX()->getAxisText();
|
||||
$yAxisText = $chart2->getChartAxisY()->getAxisText();
|
||||
if ($xAxisText === null || $yAxisText === null) {
|
||||
self::fail('Unexpected null x-axis or y-axis');
|
||||
} else {
|
||||
self::assertSame(45, $xAxisText->getRotation());
|
||||
self::assertSame('00FF00', $xAxisText->getFillColorObject()->getValue());
|
||||
self::assertSame(ChartColor::EXCEL_COLOR_TYPE_RGB, $xAxisText->getFillColorObject()->getType());
|
||||
self::assertSame(20.0, $yAxisText->getGlowProperty('size'));
|
||||
self::assertSame(['value' => 'accent1', 'type' => 'schemeClr', 'alpha' => 20], $yAxisText->getGlowProperty('color'));
|
||||
}
|
||||
|
||||
$reloadedSpreadsheet->disconnectWorksheets();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Chart;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Chart\AxisText;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Chart;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
|
||||
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\Title;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
|
||||
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
||||
|
||||
class LegendColorTest extends AbstractFunctional
|
||||
{
|
||||
// based on 33_Chart_create_stock
|
||||
public function readCharts(XlsxReader $reader): void
|
||||
{
|
||||
$reader->setIncludeCharts(true);
|
||||
}
|
||||
|
||||
public function writeCharts(XlsxWriter $writer): void
|
||||
{
|
||||
$writer->setIncludeCharts(true);
|
||||
}
|
||||
|
||||
public function testLegend(): void
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
$worksheet->fromArray(
|
||||
[
|
||||
['Counts', 'Max', 'Min', 'Min Threshold', 'Max Threshold'],
|
||||
[10, 10, 5, 0, 50],
|
||||
[30, 20, 10, 0, 50],
|
||||
[20, 30, 15, 0, 50],
|
||||
[40, 10, 0, 0, 50],
|
||||
[100, 40, 5, 0, 50],
|
||||
],
|
||||
null,
|
||||
'A1',
|
||||
true
|
||||
);
|
||||
$worksheet->getStyle('B2:E6')->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_NUMBER_00);
|
||||
|
||||
// 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), //Max / Open
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), //Min / Close
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), //Min Threshold / Min
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$E$1', null, 1), //Max Threshold / Max
|
||||
];
|
||||
// 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$6', null, 5), // Counts
|
||||
];
|
||||
// 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$6', null, 5),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$6', null, 5),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$6', null, 5),
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$E$2:$E$6', null, 5),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_STOCKCHART, // plotType
|
||||
null, // plotGrouping - if we set this to not null, then xlsx throws error
|
||||
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_RIGHT, null, false);
|
||||
$legend->getBorderColor()->setColorProperties('ffc000');
|
||||
$legend->getFillColor()->setColorProperties('cccccc');
|
||||
$legendText = new AxisText();
|
||||
$legendText->getFillColorObject()->setValue('008080')->setType(ChartColor::EXCEL_COLOR_TYPE_RGB);
|
||||
$legendText->setShadowProperties(1);
|
||||
$legend->setLegendText($legendText);
|
||||
|
||||
$title = new Title('Test Stock Chart');
|
||||
$xAxisLabel = new Title('Counts');
|
||||
$yAxisLabel = new Title('Values');
|
||||
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'stock-chart', // name
|
||||
$title, // title
|
||||
$legend, // legend
|
||||
$plotArea, // plotArea
|
||||
true, // plotVisibleOnly
|
||||
DataSeries::EMPTY_AS_GAP, // displayBlanksAs
|
||||
$xAxisLabel, // xAxisLabel
|
||||
$yAxisLabel // yAxisLabel
|
||||
);
|
||||
|
||||
// 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);
|
||||
$worksheet->setSelectedCells('G2');
|
||||
|
||||
/** @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);
|
||||
$legend2 = $chart2->getLegend();
|
||||
if ($legend2 === null) {
|
||||
self::fail('Unexpected null legend');
|
||||
} else {
|
||||
self::assertSame('ffc000', $legend2->getBorderColor()->getValue());
|
||||
self::assertSame('cccccc', $legend2->getFillColor()->getValue());
|
||||
$legendText2 = $legend2->getLegendText();
|
||||
if ($legendText2 === null) {
|
||||
self::fail('Unexpected null legendText');
|
||||
} else {
|
||||
self::assertSame('008080', $legendText2->getFillColorObject()->getValue());
|
||||
self::assertSame('outerShdw', $legendText2->getShadowProperty('effect'));
|
||||
self::assertSame(4.0, (float) $legendText2->getShadowProperty('blur'));
|
||||
self::assertSame(45.0, (float) $legendText2->getShadowProperty('direction'));
|
||||
}
|
||||
}
|
||||
|
||||
$reloadedSpreadsheet->disconnectWorksheets();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user