Skip to content

Commit 70c1fa1

Browse files
committed
Charts - Gradients, Transparency, Hidden Axes
Fix PHPOffice#2257. Fix PHPOffice#2929. Fix PHPOffice#2935 (probably in a way that will not satisfy the requester). 2257 and 2929 requested changes that ultimately affect the same section of code, so it's appropriate to deal with them together. 2257 requests the ability to make the chart background transparent (so that the Excel gridlines are visible beneath the chart), and the ability to hide an Axis. 2929 requests the ability to set a gradient background on the chart.
1 parent 051598e commit 70c1fa1

File tree

13 files changed

+619
-13
lines changed

13 files changed

+619
-13
lines changed
+192
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
<?php
2+
3+
use PhpOffice\PhpSpreadsheet\Chart\Axis;
4+
use PhpOffice\PhpSpreadsheet\Chart\Chart;
5+
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
6+
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
7+
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
8+
use PhpOffice\PhpSpreadsheet\Chart\Legend as ChartLegend;
9+
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
10+
use PhpOffice\PhpSpreadsheet\Chart\Properties;
11+
use PhpOffice\PhpSpreadsheet\Chart\Title;
12+
use PhpOffice\PhpSpreadsheet\IOFactory;
13+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
14+
15+
require __DIR__ . '/../Header.php';
16+
17+
$spreadsheet = new Spreadsheet();
18+
$worksheet = $spreadsheet->getActiveSheet();
19+
// changed data to simulate a trend chart - Xaxis are dates; Yaxis are 3 meausurements from each date
20+
$worksheet->fromArray(
21+
[
22+
['', 'metric1', 'metric2', 'metric3'],
23+
['=DATEVALUE("2021-01-01")', 12.1, 15.1, 21.1],
24+
['=DATEVALUE("2021-01-04")', 56.2, 73.2, 86.2],
25+
['=DATEVALUE("2021-01-07")', 52.2, 61.2, 69.2],
26+
['=DATEVALUE("2021-01-10")', 30.2, 32.2, 0.2],
27+
]
28+
);
29+
$worksheet->getStyle('A2:A5')->getNumberFormat()->setFormatCode(Properties::FORMAT_CODE_DATE_ISO8601);
30+
$worksheet->getColumnDimension('A')->setAutoSize(true);
31+
$worksheet->setSelectedCells('A1');
32+
33+
// Set the Labels for each data series we want to plot
34+
// Datatype
35+
// Cell reference for data
36+
// Format Code
37+
// Number of datapoints in series
38+
// Data values
39+
// Data Marker
40+
$dataSeriesLabels = [
41+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // was 2010
42+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // was 2011
43+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // was 2012
44+
];
45+
// Set the X-Axis Labels
46+
// changed from STRING to NUMBER
47+
// added 2 additional x-axis values associated with each of the 3 metrics
48+
// added FORMATE_CODE_NUMBER
49+
$xAxisTickValues = [
50+
//new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
51+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$A$2:$A$5', Properties::FORMAT_CODE_DATE, 4),
52+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$A$2:$A$5', Properties::FORMAT_CODE_DATE, 4),
53+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$A$2:$A$5', Properties::FORMAT_CODE_DATE, 4),
54+
];
55+
// Set the Data values for each data series we want to plot
56+
// Datatype
57+
// Cell reference for data
58+
// Format Code
59+
// Number of datapoints in series
60+
// Data values
61+
// Data Marker
62+
// added FORMAT_CODE_NUMBER
63+
$dataSeriesValues = [
64+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', Properties::FORMAT_CODE_NUMBER, 4),
65+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', Properties::FORMAT_CODE_NUMBER, 4),
66+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', Properties::FORMAT_CODE_NUMBER, 4),
67+
];
68+
69+
// series 1
70+
// marker details
71+
$dataSeriesValues[0]
72+
->setPointMarker('diamond')
73+
->setPointSize(5)
74+
->getMarkerFillColor()
75+
->setColorProperties('0070C0', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
76+
$dataSeriesValues[0]
77+
->getMarkerBorderColor()
78+
->setColorProperties('002060', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
79+
80+
// line details - smooth line, connected
81+
$dataSeriesValues[0]
82+
->setScatterLines(true)
83+
->setSmoothLine(true)
84+
->setLineColorProperties('accent1', 40, ChartColor::EXCEL_COLOR_TYPE_SCHEME); // value, alpha, type
85+
$dataSeriesValues[0]->setLineStyleProperties(
86+
2.5, // width in points
87+
Properties::LINE_STYLE_COMPOUND_TRIPLE, // compound
88+
Properties::LINE_STYLE_DASH_SQUARE_DOT, // dash
89+
Properties::LINE_STYLE_CAP_SQUARE, // cap
90+
Properties::LINE_STYLE_JOIN_MITER, // join
91+
Properties::LINE_STYLE_ARROW_TYPE_OPEN, // head type
92+
Properties::LINE_STYLE_ARROW_SIZE_4, // head size preset index
93+
Properties::LINE_STYLE_ARROW_TYPE_ARROW, // end type
94+
Properties::LINE_STYLE_ARROW_SIZE_6 // end size preset index
95+
);
96+
97+
// series 2 - straight line - no special effects, connected, straight line
98+
$dataSeriesValues[1] // square fill
99+
->setPointMarker('square')
100+
->setPointSize(6)
101+
->getMarkerBorderColor()
102+
->setColorProperties('accent6', 3, ChartColor::EXCEL_COLOR_TYPE_SCHEME);
103+
$dataSeriesValues[1] // square border
104+
->getMarkerFillColor()
105+
->setColorProperties('0FFF00', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
106+
$dataSeriesValues[1]
107+
->setScatterLines(true)
108+
->setSmoothLine(false)
109+
->setLineColorProperties('FF0000', 80, ChartColor::EXCEL_COLOR_TYPE_RGB);
110+
$dataSeriesValues[1]->setLineWidth(2.0);
111+
112+
// series 3 - markers, no line
113+
$dataSeriesValues[2] // triangle fill
114+
//->setPointMarker('triangle') // let Excel choose shape
115+
->setPointSize(7)
116+
->getMarkerFillColor()
117+
->setColorProperties('FFFF00', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
118+
$dataSeriesValues[2] // triangle border
119+
->getMarkerBorderColor()
120+
->setColorProperties('accent4', null, ChartColor::EXCEL_COLOR_TYPE_SCHEME);
121+
$dataSeriesValues[2]->setScatterLines(false); // points not connected
122+
123+
// Added so that Xaxis shows dates instead of Excel-equivalent-year1900-numbers
124+
$xAxis = new Axis();
125+
//$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE );
126+
$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE_ISO8601, true);
127+
$xAxis->setAxisOption('textRotation', '45');
128+
$xAxis->setAxisOption('hidden', '1');
129+
130+
$yAxis = new Axis();
131+
$yAxis->setLineStyleProperties(
132+
2.5, // width in points
133+
Properties::LINE_STYLE_COMPOUND_SIMPLE,
134+
Properties::LINE_STYLE_DASH_DASH_DOT,
135+
Properties::LINE_STYLE_CAP_FLAT,
136+
Properties::LINE_STYLE_JOIN_BEVEL
137+
);
138+
$yAxis->setLineColorProperties('ffc000', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
139+
$yAxis->setAxisOption('hidden', '1');
140+
141+
// Build the dataseries
142+
$series = new DataSeries(
143+
DataSeries::TYPE_SCATTERCHART, // plotType
144+
null, // plotGrouping (Scatter charts don't have any grouping)
145+
range(0, count($dataSeriesValues) - 1), // plotOrder
146+
$dataSeriesLabels, // plotLabel
147+
$xAxisTickValues, // plotCategory
148+
$dataSeriesValues, // plotValues
149+
null, // plotDirection
150+
false, // smooth line
151+
DataSeries::STYLE_SMOOTHMARKER // plotStyle
152+
);
153+
154+
// Set the series in the plot area
155+
$plotArea = new PlotArea(null, [$series]);
156+
$plotArea->setNoFill(true);
157+
// Set the chart legend
158+
$legend = new ChartLegend(ChartLegend::POSITION_TOPRIGHT, null, false);
159+
160+
$title = new Title('Test Scatter Trend Chart');
161+
//$yAxisLabel = new Title('Value ($k)');
162+
163+
// Create the chart
164+
$chart = new Chart(
165+
'chart1', // name
166+
$title, // title
167+
$legend, // legend
168+
$plotArea, // plotArea
169+
true, // plotVisibleOnly
170+
DataSeries::EMPTY_AS_GAP, // displayBlanksAs
171+
null, // xAxisLabel
172+
null, //$yAxisLabel, // yAxisLabel
173+
// added xAxis for correct date display
174+
$xAxis, // xAxis
175+
$yAxis, // yAxis
176+
);
177+
$chart->setNoFill(true);
178+
179+
// Set the position where the chart should appear in the worksheet
180+
$chart->setTopLeftPosition('A7');
181+
$chart->setBottomRightPosition('P20');
182+
// Add the chart to the worksheet
183+
$worksheet->addChart($chart);
184+
185+
// Save Excel 2007 file
186+
$filename = $helper->getFilename(__FILE__);
187+
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
188+
$writer->setIncludeCharts(true);
189+
$callStartTime = microtime(true);
190+
$writer->save($filename);
191+
$spreadsheet->disconnectWorksheets();
192+
$helper->logWrite($writer, $filename, $callStartTime);
+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
3+
use PhpOffice\PhpSpreadsheet\Chart\Chart;
4+
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
5+
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
6+
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
7+
use PhpOffice\PhpSpreadsheet\Chart\Legend as ChartLegend;
8+
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
9+
use PhpOffice\PhpSpreadsheet\Chart\Title;
10+
use PhpOffice\PhpSpreadsheet\IOFactory;
11+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
12+
13+
require __DIR__ . '/../Header.php';
14+
15+
$spreadsheet = new Spreadsheet();
16+
$worksheet = $spreadsheet->getActiveSheet();
17+
$worksheet->fromArray(
18+
[
19+
['', 2010, 2011, 2012],
20+
['Q1', 12, 15, 21],
21+
['Q2', 56, 73, 86],
22+
['Q3', 52, 61, 69],
23+
['Q4', 30, 32, 0],
24+
]
25+
);
26+
27+
// Set the Labels for each data series we want to plot
28+
// Datatype
29+
// Cell reference for data
30+
// Format Code
31+
// Number of datapoints in series
32+
// Data values
33+
// Data Marker
34+
$dataSeriesLabels = [
35+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
36+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011
37+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012
38+
];
39+
// Set the X-Axis Labels
40+
$xAxisTickValues = [
41+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
42+
];
43+
// Set the Data values for each data series we want to plot
44+
// Datatype
45+
// Cell reference for data
46+
// Format Code
47+
// Number of datapoints in series
48+
// Data values
49+
// Data Marker
50+
$dataSeriesValues = [
51+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4),
52+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4),
53+
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4),
54+
];
55+
56+
// Build the dataseries
57+
$series = new DataSeries(
58+
DataSeries::TYPE_SCATTERCHART, // plotType
59+
null, // plotGrouping (Scatter charts don't have any grouping)
60+
range(0, count($dataSeriesValues) - 1), // plotOrder
61+
$dataSeriesLabels, // plotLabel
62+
$xAxisTickValues, // plotCategory
63+
$dataSeriesValues, // plotValues
64+
null, // plotDirection
65+
null, // smooth line
66+
DataSeries::STYLE_LINEMARKER // plotStyle
67+
);
68+
69+
// Set the series in the plot area
70+
$plotArea = new PlotArea(null, [$series]);
71+
72+
$pos1 = 0; // pos = 0% (extreme low side or lower left corner)
73+
$brightness1 = 0; // 0%
74+
$gsColor1 = new ChartColor();
75+
$gsColor1->setColorProperties('FF0000', 75, 'srgbClr', $brightness1); // red
76+
$gradientStop1 = [$pos1, $gsColor1];
77+
78+
$pos2 = 0.5; // pos = 50% (middle)
79+
$brightness2 = 0.5; // 50%
80+
$gsColor2 = new ChartColor();
81+
$gsColor2->setColorProperties('FFFF00', 50, 'srgbClr', $brightness2); // yellow
82+
$gradientStop2 = [$pos2, $gsColor2];
83+
84+
$pos3 = 1.0; // pos = 100% (extreme high side or upper right corner)
85+
$brightness3 = 0.5; // 50%
86+
$gsColor3 = new ChartColor();
87+
$gsColor3->setColorProperties('00B050', 50, 'srgbClr', $brightness3); // green
88+
$gradientStop3 = [$pos3, $gsColor3];
89+
90+
$gradientFillStops = [
91+
$gradientStop1,
92+
$gradientStop2,
93+
$gradientStop3,
94+
];
95+
$gradientFillAngle = 315.0; // 45deg above horiz
96+
97+
$plotArea->setGradientFillProperties($gradientFillStops, $gradientFillAngle);
98+
99+
// Set the chart legend
100+
$legend = new ChartLegend(ChartLegend::POSITION_TOPRIGHT, null, false);
101+
102+
$title = new Title('Test Scatter Chart');
103+
$yAxisLabel = new Title('Value ($k)');
104+
105+
// Create the chart
106+
$chart = new Chart(
107+
'chart1', // name
108+
$title, // title
109+
$legend, // legend
110+
$plotArea, // plotArea
111+
true, // plotVisibleOnly
112+
DataSeries::EMPTY_AS_GAP, // displayBlanksAs
113+
null, // xAxisLabel
114+
$yAxisLabel // yAxisLabel
115+
);
116+
117+
// Set the position where the chart should appear in the worksheet
118+
$chart->setTopLeftPosition('A7');
119+
$chart->setBottomRightPosition('H20');
120+
121+
// Add the chart to the worksheet
122+
$worksheet->addChart($chart);
123+
124+
// Save Excel 2007 file
125+
$filename = $helper->getFilename(__FILE__);
126+
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
127+
$writer->setIncludeCharts(true);
128+
$callStartTime = microtime(true);
129+
$writer->save($filename);
130+
$helper->logWrite($writer, $filename, $callStartTime);
12.1 KB
Binary file not shown.
12.3 KB
Binary file not shown.

src/PhpSpreadsheet/Chart/Axis.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public function __construct()
6161
'horizontal_crosses' => self::HORIZONTAL_CROSSES_AUTOZERO,
6262
'horizontal_crosses_value' => null,
6363
'textRotation' => null,
64+
'hidden' => null,
6465
];
6566

6667
/**
@@ -138,7 +139,8 @@ public function setAxisOptionsProperties(
138139
?string $maximum = null,
139140
?string $majorUnit = null,
140141
?string $minorUnit = null,
141-
?string $textRotation = null
142+
?string $textRotation = null,
143+
?string $hidden = null
142144
): void {
143145
$this->axisOptions['axis_labels'] = $axisLabels;
144146
$this->setAxisOption('horizontal_crosses_value', $horizontalCrossesValue);
@@ -151,6 +153,7 @@ public function setAxisOptionsProperties(
151153
$this->setAxisOption('major_unit', $majorUnit);
152154
$this->setAxisOption('minor_unit', $minorUnit);
153155
$this->setAxisOption('textRotation', $textRotation);
156+
$this->setAxisOption('hidden', $hidden);
154157
}
155158

156159
/**

src/PhpSpreadsheet/Chart/Chart.php

+15
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ class Chart
144144
/** @var bool */
145145
private $autoTitleDeleted = false;
146146

147+
/** @var bool */
148+
private $noFill = false;
149+
147150
/**
148151
* Create a new Chart.
149152
* majorGridlines and minorGridlines are deprecated, moved to Axis.
@@ -747,4 +750,16 @@ public function setAutoTitleDeleted(bool $autoTitleDeleted): self
747750

748751
return $this;
749752
}
753+
754+
public function getNoFill(): bool
755+
{
756+
return $this->noFill;
757+
}
758+
759+
public function setNoFill(bool $noFill): self
760+
{
761+
$this->noFill = $noFill;
762+
763+
return $this;
764+
}
750765
}

0 commit comments

Comments
 (0)