Charts32CatAxValAxTest.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheetTests\Chart;
  3. use PhpOffice\PhpSpreadsheet\Chart\Axis;
  4. use PhpOffice\PhpSpreadsheet\Chart\Chart;
  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\Properties;
  10. use PhpOffice\PhpSpreadsheet\Chart\Title;
  11. use PhpOffice\PhpSpreadsheet\Shared\File;
  12. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  13. use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
  14. use PHPUnit\Framework\TestCase;
  15. class Charts32CatAxValAxTest extends TestCase
  16. {
  17. // These tests can only be performed by examining xml.
  18. // They are based on sample 33_Chart_Create_Scatter2.
  19. /** @var string */
  20. private $outputFileName = '';
  21. private const FORMAT_CODE_DATE_ISO8601_SLASH = 'yyyy/mm/dd'; // not automatically treated as numeric
  22. protected function tearDown(): void
  23. {
  24. if ($this->outputFileName !== '') {
  25. unlink($this->outputFileName);
  26. $this->outputFileName = '';
  27. }
  28. }
  29. /**
  30. * @dataProvider providerCatAxValAx
  31. */
  32. public function test1CatAx1ValAx(?bool $numeric): void
  33. {
  34. $spreadsheet = new Spreadsheet();
  35. $worksheet = $spreadsheet->getActiveSheet();
  36. // changed data to simulate a trend chart - Xaxis are dates; Yaxis are 3 meausurements from each date
  37. $worksheet->fromArray(
  38. [
  39. ['', 'metric1', 'metric2', 'metric3'],
  40. ['=DATEVALUE("2021-01-01")', 12.1, 15.1, 21.1],
  41. ['=DATEVALUE("2021-01-04")', 56.2, 73.2, 86.2],
  42. ['=DATEVALUE("2021-01-07")', 52.2, 61.2, 69.2],
  43. ['=DATEVALUE("2021-01-10")', 30.2, 32.2, 0.2],
  44. ]
  45. );
  46. $worksheet->getStyle('A2:A5')->getNumberFormat()->setFormatCode(self::FORMAT_CODE_DATE_ISO8601_SLASH);
  47. $worksheet->getColumnDimension('A')->setAutoSize(true);
  48. $worksheet->setSelectedCells('A1');
  49. // Set the Labels for each data series we want to plot
  50. // Datatype
  51. // Cell reference for data
  52. // Format Code
  53. // Number of datapoints in series
  54. // Data values
  55. // Data Marker
  56. $dataSeriesLabels = [
  57. new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // was 2010
  58. new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // was 2011
  59. new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // was 2012
  60. ];
  61. // Set the X-Axis Labels
  62. // changed from STRING to NUMBER
  63. // added 2 additional x-axis values associated with each of the 3 metrics
  64. // added FORMATE_CODE_NUMBER
  65. $xAxisTickValues = [
  66. //new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4
  67. new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$A$2:$A$5', Properties::FORMAT_CODE_DATE, 4),
  68. new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$A$2:$A$5', Properties::FORMAT_CODE_DATE, 4),
  69. new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$A$2:$A$5', Properties::FORMAT_CODE_DATE, 4),
  70. ];
  71. // Set the Data values for each data series we want to plot
  72. // Datatype
  73. // Cell reference for data
  74. // Format Code
  75. // Number of datapoints in series
  76. // Data values
  77. // Data Marker
  78. // added FORMAT_CODE_NUMBER
  79. $dataSeriesValues = [
  80. new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', Properties::FORMAT_CODE_NUMBER, 4),
  81. new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', Properties::FORMAT_CODE_NUMBER, 4),
  82. new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', Properties::FORMAT_CODE_NUMBER, 4),
  83. ];
  84. // Added so that Xaxis shows dates instead of Excel-equivalent-year1900-numbers
  85. $xAxis = new Axis();
  86. //$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE );
  87. if (is_bool($numeric)) {
  88. $xAxis->setAxisNumberProperties(self::FORMAT_CODE_DATE_ISO8601_SLASH, $numeric);
  89. } else {
  90. $xAxis->setAxisNumberProperties(self::FORMAT_CODE_DATE_ISO8601_SLASH);
  91. }
  92. // Build the dataseries
  93. $series = new DataSeries(
  94. DataSeries::TYPE_SCATTERCHART, // plotType
  95. null, // plotGrouping (Scatter charts don't have any grouping)
  96. range(0, count($dataSeriesValues) - 1), // plotOrder
  97. $dataSeriesLabels, // plotLabel
  98. $xAxisTickValues, // plotCategory
  99. $dataSeriesValues, // plotValues
  100. null, // plotDirection
  101. false, // smooth line
  102. //DataSeries::STYLE_LINEMARKER // plotStyle
  103. DataSeries::STYLE_MARKER // plotStyle
  104. );
  105. // Set the series in the plot area
  106. $plotArea = new PlotArea(null, [$series]);
  107. // Set the chart legend
  108. $legend = new ChartLegend(ChartLegend::POSITION_TOPRIGHT, null, false);
  109. $title = new Title('Test Scatter Trend Chart');
  110. $yAxisLabel = new Title('Value ($k)');
  111. // Create the chart
  112. $chart = new Chart(
  113. 'chart1', // name
  114. $title, // title
  115. $legend, // legend
  116. $plotArea, // plotArea
  117. true, // plotVisibleOnly
  118. DataSeries::EMPTY_AS_GAP, // displayBlanksAs
  119. null, // xAxisLabel
  120. $yAxisLabel, // yAxisLabel
  121. // added xAxis for correct date display
  122. $xAxis, // xAxis
  123. );
  124. // Set the position where the chart should appear in the worksheet
  125. $chart->setTopLeftPosition('A7');
  126. $chart->setBottomRightPosition('P20');
  127. // Add the chart to the worksheet
  128. $worksheet->addChart($chart);
  129. $writer = new XlsxWriter($spreadsheet);
  130. $writer->setIncludeCharts(true);
  131. $this->outputFileName = File::temporaryFilename();
  132. $writer->save($this->outputFileName);
  133. $spreadsheet->disconnectWorksheets();
  134. $file = 'zip://';
  135. $file .= $this->outputFileName;
  136. $file .= '#xl/charts/chart1.xml';
  137. $data = file_get_contents($file);
  138. // confirm that file contains expected tags
  139. if ($data === false) {
  140. self::fail('Unable to read file');
  141. } elseif ($numeric === true) {
  142. self::assertSame(0, substr_count($data, '<c:catAx'));
  143. self::assertSame(2, substr_count($data, '<c:valAx'));
  144. } else {
  145. self::assertSame(1, substr_count($data, '<c:catAx'));
  146. self::assertSame(1, substr_count($data, '<c:valAx'));
  147. }
  148. }
  149. public function providerCatAxValAx(): array
  150. {
  151. return [
  152. [true],
  153. [false],
  154. [null],
  155. ];
  156. }
  157. }