mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-08-25 07:38:17 +00:00
d2938477d9
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.
164 lines
4.8 KiB
PHP
164 lines
4.8 KiB
PHP
<?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);
|