-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Xlsx Reader/Writer Composite Charts (#3265)
Fix #2333. Thanks to @SSI-johnnypops for discovering the problem and formulating most of the solution. The classes involved in setting up composite charts made it relatively easy to code them; however, there can be problems when reading a spreadsheet with such a chart and then saving a copy of it. In particular, the ordering conventions when reading the chart may not match the expectations when writing. The original attempt to resolve this worked for read/write but broke one of our samples (33_Chart_create_composite), which probably means that it would break other code which is now working in the wild. It has now been refined so that it (hopefully) makes adjustments to the ordering if and only if they are required. The new code works with the failing spreadsheet reported in the issue, with the unchanged sample code, and with an alternate version of the sample which contains what is probably a better model for people to use when coding such a chart.
- Loading branch information
Showing
3 changed files
with
166 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
<?php | ||
|
||
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\Title; | ||
use PhpOffice\PhpSpreadsheet\IOFactory; | ||
use PhpOffice\PhpSpreadsheet\Spreadsheet; | ||
|
||
require __DIR__ . '/../Header.php'; | ||
|
||
$spreadsheet = new Spreadsheet(); | ||
$worksheet = $spreadsheet->getActiveSheet(); | ||
$worksheet->fromArray( | ||
[ | ||
['', 'Rainfall (mm)', 'Temperature (°F)', 'Humidity (%)'], | ||
['Jan', 78, 52, 61], | ||
['Feb', 64, 54, 62], | ||
['Mar', 62, 57, 63], | ||
['Apr', 21, 62, 59], | ||
['May', 11, 75, 60], | ||
['Jun', 1, 75, 57], | ||
['Jul', 1, 79, 56], | ||
['Aug', 1, 79, 59], | ||
['Sep', 10, 75, 60], | ||
['Oct', 40, 68, 63], | ||
['Nov', 69, 62, 64], | ||
['Dec', 89, 57, 66], | ||
] | ||
); | ||
|
||
// 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 | ||
$dataSeriesLabels1 = [ | ||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // Temperature | ||
]; | ||
$dataSeriesLabels2 = [ | ||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // Rainfall | ||
]; | ||
$dataSeriesLabels3 = [ | ||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // Humidity | ||
]; | ||
|
||
// 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$13', null, 12), // Jan to Dec | ||
]; | ||
|
||
$order = 0; | ||
// 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 | ||
$dataSeriesValues1 = [ | ||
$order => new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$13', null, 12), | ||
]; | ||
|
||
// Build the dataseries | ||
$series1 = new DataSeries( | ||
DataSeries::TYPE_BARCHART, // plotType | ||
DataSeries::GROUPING_CLUSTERED, // plotGrouping | ||
[$order => $order], // plotOrder | ||
$dataSeriesLabels1, // plotLabel | ||
$xAxisTickValues, // plotCategory | ||
$dataSeriesValues1 // plotValues | ||
); | ||
// Set additional dataseries parameters | ||
// Make it a vertical column rather than a horizontal bar graph | ||
$series1->setPlotDirection(DataSeries::DIRECTION_COL); | ||
|
||
$order = 1; | ||
// 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 | ||
$dataSeriesValues2 = [ | ||
$order => new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$13', null, 12), | ||
]; | ||
|
||
// Build the dataseries | ||
$series2 = new DataSeries( | ||
DataSeries::TYPE_LINECHART, // plotType | ||
DataSeries::GROUPING_STANDARD, // plotGrouping | ||
[$order => $order], // plotOrder | ||
$dataSeriesLabels2, // plotLabel | ||
[], // plotCategory | ||
$dataSeriesValues2 // plotValues | ||
); | ||
|
||
$order = 2; | ||
// 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 | ||
$dataSeriesValues3 = [ | ||
$order => new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$13', null, 12), | ||
]; | ||
|
||
// Build the dataseries | ||
$series3 = new DataSeries( | ||
DataSeries::TYPE_AREACHART, // plotType | ||
DataSeries::GROUPING_STANDARD, // plotGrouping | ||
[$order => $order], // plotOrder | ||
$dataSeriesLabels3, // plotLabel | ||
[], // plotCategory | ||
$dataSeriesValues3 // plotValues | ||
); | ||
|
||
// Set the series in the plot area | ||
$plotArea = new PlotArea(null, [$series1, $series2, $series3]); | ||
// Set the chart legend | ||
$legend = new ChartLegend(ChartLegend::POSITION_RIGHT, null, false); | ||
|
||
$title = new Title('Average Weather Chart for Crete'); | ||
|
||
// Create the chart | ||
$chart = new Chart( | ||
'chart1', // name | ||
$title, // title | ||
$legend, // legend | ||
$plotArea, // plotArea | ||
true, // plotVisibleOnly | ||
DataSeries::EMPTY_AS_GAP, // displayBlanksAs | ||
null, // xAxisLabel | ||
null // yAxisLabel | ||
); | ||
|
||
// Set the position where the chart should appear in the worksheet | ||
$chart->setTopLeftPosition('F2'); | ||
$chart->setBottomRightPosition('O16'); | ||
|
||
// 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); | ||
$helper->logWrite($writer, $filename, $callStartTime); |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters