PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.7.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.7.1
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / vendor / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Writer / Xlsx / Chart.php

Chart.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.7.1, at vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Chart.php

1,542 lines 61.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
4
5 use PhpOffice\PhpSpreadsheet\Chart\Axis;
6 use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
7 use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
8 use PhpOffice\PhpSpreadsheet\Chart\GridLines;
9 use PhpOffice\PhpSpreadsheet\Chart\Layout;
10 use PhpOffice\PhpSpreadsheet\Chart\Legend;
11 use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
12 use PhpOffice\PhpSpreadsheet\Chart\Title;
13 use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
14 use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
15 use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
16
17 class Chart extends WriterPart
18 {
19 protected $calculateCellValues;
20
21 /**
22 * @var int
23 */
24 private $seriesIndex;
25
26 /**
27 * Write charts to XML format.
28 *
29 * @param \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart
30 * @param mixed $calculateCellValues
31 *
32 * @throws WriterException
33 *
34 * @return string XML Output
35 */
36 public function writeChart(\PhpOffice\PhpSpreadsheet\Chart\Chart $pChart, $calculateCellValues = true)
37 {
38 $this->calculateCellValues = $calculateCellValues;
39
40 // Create XML writer
41 $objWriter = null;
42 if ($this->getParentWriter()->getUseDiskCaching()) {
43 $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
44 } else {
45 $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
46 }
47 // Ensure that data series values are up-to-date before we save
48 if ($this->calculateCellValues) {
49 $pChart->refresh();
50 }
51
52 // XML header
53 $objWriter->startDocument('1.0', 'UTF-8', 'yes');
54
55 // c:chartSpace
56 $objWriter->startElement('c:chartSpace');
57 $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
58 $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
59 $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
60
61 $objWriter->startElement('c:date1904');
62 $objWriter->writeAttribute('val', 0);
63 $objWriter->endElement();
64 $objWriter->startElement('c:lang');
65 $objWriter->writeAttribute('val', 'en-GB');
66 $objWriter->endElement();
67 $objWriter->startElement('c:roundedCorners');
68 $objWriter->writeAttribute('val', 0);
69 $objWriter->endElement();
70
71 $this->writeAlternateContent($objWriter);
72
73 $objWriter->startElement('c:chart');
74
75 $this->writeTitle($objWriter, $pChart->getTitle());
76
77 $objWriter->startElement('c:autoTitleDeleted');
78 $objWriter->writeAttribute('val', 0);
79 $objWriter->endElement();
80
81 $this->writePlotArea($objWriter, $pChart->getWorksheet(), $pChart->getPlotArea(), $pChart->getXAxisLabel(), $pChart->getYAxisLabel(), $pChart->getChartAxisX(), $pChart->getChartAxisY(), $pChart->getMajorGridlines(), $pChart->getMinorGridlines());
82
83 $this->writeLegend($objWriter, $pChart->getLegend());
84
85 $objWriter->startElement('c:plotVisOnly');
86 $objWriter->writeAttribute('val', 1);
87 $objWriter->endElement();
88
89 $objWriter->startElement('c:dispBlanksAs');
90 $objWriter->writeAttribute('val', 'gap');
91 $objWriter->endElement();
92
93 $objWriter->startElement('c:showDLblsOverMax');
94 $objWriter->writeAttribute('val', 0);
95 $objWriter->endElement();
96
97 $objWriter->endElement();
98
99 $this->writePrintSettings($objWriter);
100
101 $objWriter->endElement();
102
103 // Return
104 return $objWriter->getData();
105 }
106
107 /**
108 * Write Chart Title.
109 *
110 * @param XMLWriter $objWriter XML Writer
111 * @param Title $title
112 *
113 * @throws WriterException
114 */
115 private function writeTitle(XMLWriter $objWriter, Title $title = null)
116 {
117 if ($title === null) {
118 return;
119 }
120
121 $objWriter->startElement('c:title');
122 $objWriter->startElement('c:tx');
123 $objWriter->startElement('c:rich');
124
125 $objWriter->startElement('a:bodyPr');
126 $objWriter->endElement();
127
128 $objWriter->startElement('a:lstStyle');
129 $objWriter->endElement();
130
131 $objWriter->startElement('a:p');
132
133 $caption = $title->getCaption();
134 if ((is_array($caption)) && (count($caption) > 0)) {
135 $caption = $caption[0];
136 }
137 $this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a');
138
139 $objWriter->endElement();
140 $objWriter->endElement();
141 $objWriter->endElement();
142
143 $this->writeLayout($objWriter, $title->getLayout());
144
145 $objWriter->startElement('c:overlay');
146 $objWriter->writeAttribute('val', 0);
147 $objWriter->endElement();
148
149 $objWriter->endElement();
150 }
151
152 /**
153 * Write Chart Legend.
154 *
155 * @param XMLWriter $objWriter XML Writer
156 * @param Legend $legend
157 *
158 * @throws WriterException
159 */
160 private function writeLegend(XMLWriter $objWriter, Legend $legend = null)
161 {
162 if ($legend === null) {
163 return;
164 }
165
166 $objWriter->startElement('c:legend');
167
168 $objWriter->startElement('c:legendPos');
169 $objWriter->writeAttribute('val', $legend->getPosition());
170 $objWriter->endElement();
171
172 $this->writeLayout($objWriter, $legend->getLayout());
173
174 $objWriter->startElement('c:overlay');
175 $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0');
176 $objWriter->endElement();
177
178 $objWriter->startElement('c:txPr');
179 $objWriter->startElement('a:bodyPr');
180 $objWriter->endElement();
181
182 $objWriter->startElement('a:lstStyle');
183 $objWriter->endElement();
184
185 $objWriter->startElement('a:p');
186 $objWriter->startElement('a:pPr');
187 $objWriter->writeAttribute('rtl', 0);
188
189 $objWriter->startElement('a:defRPr');
190 $objWriter->endElement();
191 $objWriter->endElement();
192
193 $objWriter->startElement('a:endParaRPr');
194 $objWriter->writeAttribute('lang', 'en-US');
195 $objWriter->endElement();
196
197 $objWriter->endElement();
198 $objWriter->endElement();
199
200 $objWriter->endElement();
201 }
202
203 /**
204 * Write Chart Plot Area.
205 *
206 * @param XMLWriter $objWriter XML Writer
207 * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pSheet
208 * @param PlotArea $plotArea
209 * @param Title $xAxisLabel
210 * @param Title $yAxisLabel
211 * @param Axis $xAxis
212 * @param Axis $yAxis
213 * @param null|GridLines $majorGridlines
214 * @param null|GridLines $minorGridlines
215 *
216 * @throws WriterException
217 */
218 private function writePlotArea(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pSheet, PlotArea $plotArea, Title $xAxisLabel = null, Title $yAxisLabel = null, Axis $xAxis = null, Axis $yAxis = null, GridLines $majorGridlines = null, GridLines $minorGridlines = null)
219 {
220 if ($plotArea === null) {
221 return;
222 }
223
224 $id1 = $id2 = 0;
225 $this->seriesIndex = 0;
226 $objWriter->startElement('c:plotArea');
227
228 $layout = $plotArea->getLayout();
229
230 $this->writeLayout($objWriter, $layout);
231
232 $chartTypes = self::getChartType($plotArea);
233 $catIsMultiLevelSeries = $valIsMultiLevelSeries = false;
234 $plotGroupingType = '';
235 foreach ($chartTypes as $chartType) {
236 $objWriter->startElement('c:' . $chartType);
237
238 $groupCount = $plotArea->getPlotGroupCount();
239 for ($i = 0; $i < $groupCount; ++$i) {
240 $plotGroup = $plotArea->getPlotGroupByIndex($i);
241 $groupType = $plotGroup->getPlotType();
242 if ($groupType == $chartType) {
243 $plotStyle = $plotGroup->getPlotStyle();
244 if ($groupType === DataSeries::TYPE_RADARCHART) {
245 $objWriter->startElement('c:radarStyle');
246 $objWriter->writeAttribute('val', $plotStyle);
247 $objWriter->endElement();
248 } elseif ($groupType === DataSeries::TYPE_SCATTERCHART) {
249 $objWriter->startElement('c:scatterStyle');
250 $objWriter->writeAttribute('val', $plotStyle);
251 $objWriter->endElement();
252 }
253
254 $this->writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType);
255 }
256 }
257
258 $this->writeDataLabels($objWriter, $layout);
259
260 if ($chartType === DataSeries::TYPE_LINECHART) {
261 // Line only, Line3D can't be smoothed
262 $objWriter->startElement('c:smooth');
263 $objWriter->writeAttribute('val', (int) $plotGroup->getSmoothLine());
264 $objWriter->endElement();
265 } elseif (($chartType === DataSeries::TYPE_BARCHART) || ($chartType === DataSeries::TYPE_BARCHART_3D)) {
266 $objWriter->startElement('c:gapWidth');
267 $objWriter->writeAttribute('val', 150);
268 $objWriter->endElement();
269
270 if ($plotGroupingType == 'percentStacked' || $plotGroupingType == 'stacked') {
271 $objWriter->startElement('c:overlap');
272 $objWriter->writeAttribute('val', 100);
273 $objWriter->endElement();
274 }
275 } elseif ($chartType === DataSeries::TYPE_BUBBLECHART) {
276 $objWriter->startElement('c:bubbleScale');
277 $objWriter->writeAttribute('val', 25);
278 $objWriter->endElement();
279
280 $objWriter->startElement('c:showNegBubbles');
281 $objWriter->writeAttribute('val', 0);
282 $objWriter->endElement();
283 } elseif ($chartType === DataSeries::TYPE_STOCKCHART) {
284 $objWriter->startElement('c:hiLowLines');
285 $objWriter->endElement();
286
287 $objWriter->startElement('c:upDownBars');
288
289 $objWriter->startElement('c:gapWidth');
290 $objWriter->writeAttribute('val', 300);
291 $objWriter->endElement();
292
293 $objWriter->startElement('c:upBars');
294 $objWriter->endElement();
295
296 $objWriter->startElement('c:downBars');
297 $objWriter->endElement();
298
299 $objWriter->endElement();
300 }
301
302 // Generate 2 unique numbers to use for axId values
303 $id1 = '75091328';
304 $id2 = '75089408';
305
306 if (($chartType !== DataSeries::TYPE_PIECHART) && ($chartType !== DataSeries::TYPE_PIECHART_3D) && ($chartType !== DataSeries::TYPE_DONUTCHART)) {
307 $objWriter->startElement('c:axId');
308 $objWriter->writeAttribute('val', $id1);
309 $objWriter->endElement();
310 $objWriter->startElement('c:axId');
311 $objWriter->writeAttribute('val', $id2);
312 $objWriter->endElement();
313 } else {
314 $objWriter->startElement('c:firstSliceAng');
315 $objWriter->writeAttribute('val', 0);
316 $objWriter->endElement();
317
318 if ($chartType === DataSeries::TYPE_DONUTCHART) {
319 $objWriter->startElement('c:holeSize');
320 $objWriter->writeAttribute('val', 50);
321 $objWriter->endElement();
322 }
323 }
324
325 $objWriter->endElement();
326 }
327
328 if (($chartType !== DataSeries::TYPE_PIECHART) && ($chartType !== DataSeries::TYPE_PIECHART_3D) && ($chartType !== DataSeries::TYPE_DONUTCHART)) {
329 if ($chartType === DataSeries::TYPE_BUBBLECHART) {
330 $this->writeValueAxis($objWriter, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $majorGridlines, $minorGridlines);
331 } else {
332 $this->writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $catIsMultiLevelSeries, $yAxis);
333 }
334
335 $this->writeValueAxis($objWriter, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $majorGridlines, $minorGridlines);
336 }
337
338 $objWriter->endElement();
339 }
340
341 /**
342 * Write Data Labels.
343 *
344 * @param XMLWriter $objWriter XML Writer
345 * @param \PhpOffice\PhpSpreadsheet\Chart\Layout $chartLayout Chart layout
346 */
347 private function writeDataLabels(XMLWriter $objWriter, Layout $chartLayout = null)
348 {
349 $objWriter->startElement('c:dLbls');
350
351 $objWriter->startElement('c:showLegendKey');
352 $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey();
353 $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1));
354 $objWriter->endElement();
355
356 $objWriter->startElement('c:showVal');
357 $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal();
358 $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1));
359 $objWriter->endElement();
360
361 $objWriter->startElement('c:showCatName');
362 $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName();
363 $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1));
364 $objWriter->endElement();
365
366 $objWriter->startElement('c:showSerName');
367 $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName();
368 $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1));
369 $objWriter->endElement();
370
371 $objWriter->startElement('c:showPercent');
372 $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent();
373 $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1));
374 $objWriter->endElement();
375
376 $objWriter->startElement('c:showBubbleSize');
377 $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize();
378 $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1));
379 $objWriter->endElement();
380
381 $objWriter->startElement('c:showLeaderLines');
382 $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines();
383 $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1));
384 $objWriter->endElement();
385
386 $objWriter->endElement();
387 }
388
389 /**
390 * Write Category Axis.
391 *
392 * @param XMLWriter $objWriter XML Writer
393 * @param Title $xAxisLabel
394 * @param string $id1
395 * @param string $id2
396 * @param bool $isMultiLevelSeries
397 * @param Axis $yAxis
398 *
399 * @throws WriterException
400 */
401 private function writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $isMultiLevelSeries, Axis $yAxis)
402 {
403 $objWriter->startElement('c:catAx');
404
405 if ($id1 > 0) {
406 $objWriter->startElement('c:axId');
407 $objWriter->writeAttribute('val', $id1);
408 $objWriter->endElement();
409 }
410
411 $objWriter->startElement('c:scaling');
412 $objWriter->startElement('c:orientation');
413 $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('orientation'));
414 $objWriter->endElement();
415 $objWriter->endElement();
416
417 $objWriter->startElement('c:delete');
418 $objWriter->writeAttribute('val', 0);
419 $objWriter->endElement();
420
421 $objWriter->startElement('c:axPos');
422 $objWriter->writeAttribute('val', 'b');
423 $objWriter->endElement();
424
425 if ($xAxisLabel !== null) {
426 $objWriter->startElement('c:title');
427 $objWriter->startElement('c:tx');
428 $objWriter->startElement('c:rich');
429
430 $objWriter->startElement('a:bodyPr');
431 $objWriter->endElement();
432
433 $objWriter->startElement('a:lstStyle');
434 $objWriter->endElement();
435
436 $objWriter->startElement('a:p');
437 $objWriter->startElement('a:r');
438
439 $caption = $xAxisLabel->getCaption();
440 if (is_array($caption)) {
441 $caption = $caption[0];
442 }
443 $objWriter->startElement('a:t');
444 $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($caption));
445 $objWriter->endElement();
446
447 $objWriter->endElement();
448 $objWriter->endElement();
449 $objWriter->endElement();
450 $objWriter->endElement();
451
452 $layout = $xAxisLabel->getLayout();
453 $this->writeLayout($objWriter, $layout);
454
455 $objWriter->startElement('c:overlay');
456 $objWriter->writeAttribute('val', 0);
457 $objWriter->endElement();
458
459 $objWriter->endElement();
460 }
461
462 $objWriter->startElement('c:numFmt');
463 $objWriter->writeAttribute('formatCode', $yAxis->getAxisNumberFormat());
464 $objWriter->writeAttribute('sourceLinked', $yAxis->getAxisNumberSourceLinked());
465 $objWriter->endElement();
466
467 $objWriter->startElement('c:majorTickMark');
468 $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('major_tick_mark'));
469 $objWriter->endElement();
470
471 $objWriter->startElement('c:minorTickMark');
472 $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minor_tick_mark'));
473 $objWriter->endElement();
474
475 $objWriter->startElement('c:tickLblPos');
476 $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('axis_labels'));
477 $objWriter->endElement();
478
479 if ($id2 > 0) {
480 $objWriter->startElement('c:crossAx');
481 $objWriter->writeAttribute('val', $id2);
482 $objWriter->endElement();
483
484 $objWriter->startElement('c:crosses');
485 $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('horizontal_crosses'));
486 $objWriter->endElement();
487 }
488
489 $objWriter->startElement('c:auto');
490 $objWriter->writeAttribute('val', 1);
491 $objWriter->endElement();
492
493 $objWriter->startElement('c:lblAlgn');
494 $objWriter->writeAttribute('val', 'ctr');
495 $objWriter->endElement();
496
497 $objWriter->startElement('c:lblOffset');
498 $objWriter->writeAttribute('val', 100);
499 $objWriter->endElement();
500
501 if ($isMultiLevelSeries) {
502 $objWriter->startElement('c:noMultiLvlLbl');
503 $objWriter->writeAttribute('val', 0);
504 $objWriter->endElement();
505 }
506 $objWriter->endElement();
507 }
508
509 /**
510 * Write Value Axis.
511 *
512 * @param XMLWriter $objWriter XML Writer
513 * @param Title $yAxisLabel
514 * @param string $groupType Chart type
515 * @param string $id1
516 * @param string $id2
517 * @param bool $isMultiLevelSeries
518 * @param Axis $xAxis
519 * @param GridLines $majorGridlines
520 * @param GridLines $minorGridlines
521 *
522 * @throws WriterException
523 */
524 private function writeValueAxis($objWriter, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, Axis $xAxis, GridLines $majorGridlines, GridLines $minorGridlines)
525 {
526 $objWriter->startElement('c:valAx');
527
528 if ($id2 > 0) {
529 $objWriter->startElement('c:axId');
530 $objWriter->writeAttribute('val', $id2);
531 $objWriter->endElement();
532 }
533
534 $objWriter->startElement('c:scaling');
535
536 if ($xAxis->getAxisOptionsProperty('maximum') !== null) {
537 $objWriter->startElement('c:max');
538 $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('maximum'));
539 $objWriter->endElement();
540 }
541
542 if ($xAxis->getAxisOptionsProperty('minimum') !== null) {
543 $objWriter->startElement('c:min');
544 $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minimum'));
545 $objWriter->endElement();
546 }
547
548 $objWriter->startElement('c:orientation');
549 $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation'));
550
551 $objWriter->endElement();
552 $objWriter->endElement();
553
554 $objWriter->startElement('c:delete');
555 $objWriter->writeAttribute('val', 0);
556 $objWriter->endElement();
557
558 $objWriter->startElement('c:axPos');
559 $objWriter->writeAttribute('val', 'l');
560 $objWriter->endElement();
561
562 $objWriter->startElement('c:majorGridlines');
563 $objWriter->startElement('c:spPr');
564
565 if ($majorGridlines->getLineColorProperty('value') !== null) {
566 $objWriter->startElement('a:ln');
567 $objWriter->writeAttribute('w', $majorGridlines->getLineStyleProperty('width'));
568 $objWriter->startElement('a:solidFill');
569 $objWriter->startElement("a:{$majorGridlines->getLineColorProperty('type')}");
570 $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('value'));
571 $objWriter->startElement('a:alpha');
572 $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('alpha'));
573 $objWriter->endElement(); //end alpha
574 $objWriter->endElement(); //end srgbClr
575 $objWriter->endElement(); //end solidFill
576
577 $objWriter->startElement('a:prstDash');
578 $objWriter->writeAttribute('val', $majorGridlines->getLineStyleProperty('dash'));
579 $objWriter->endElement();
580
581 if ($majorGridlines->getLineStyleProperty('join') == 'miter') {
582 $objWriter->startElement('a:miter');
583 $objWriter->writeAttribute('lim', '800000');
584 $objWriter->endElement();
585 } else {
586 $objWriter->startElement('a:bevel');
587 $objWriter->endElement();
588 }
589
590 if ($majorGridlines->getLineStyleProperty(['arrow', 'head', 'type']) !== null) {
591 $objWriter->startElement('a:headEnd');
592 $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(['arrow', 'head', 'type']));
593 $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('head', 'w'));
594 $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('head', 'len'));
595 $objWriter->endElement();
596 }
597
598 if ($majorGridlines->getLineStyleProperty(['arrow', 'end', 'type']) !== null) {
599 $objWriter->startElement('a:tailEnd');
600 $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(['arrow', 'end', 'type']));
601 $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('end', 'w'));
602 $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('end', 'len'));
603 $objWriter->endElement();
604 }
605 $objWriter->endElement(); //end ln
606 }
607 $objWriter->startElement('a:effectLst');
608
609 if ($majorGridlines->getGlowSize() !== null) {
610 $objWriter->startElement('a:glow');
611 $objWriter->writeAttribute('rad', $majorGridlines->getGlowSize());
612 $objWriter->startElement("a:{$majorGridlines->getGlowColor('type')}");
613 $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('value'));
614 $objWriter->startElement('a:alpha');
615 $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('alpha'));
616 $objWriter->endElement(); //end alpha
617 $objWriter->endElement(); //end schemeClr
618 $objWriter->endElement(); //end glow
619 }
620
621 if ($majorGridlines->getShadowProperty('presets') !== null) {
622 $objWriter->startElement("a:{$majorGridlines->getShadowProperty('effect')}");
623 if ($majorGridlines->getShadowProperty('blur') !== null) {
624 $objWriter->writeAttribute('blurRad', $majorGridlines->getShadowProperty('blur'));
625 }
626 if ($majorGridlines->getShadowProperty('distance') !== null) {
627 $objWriter->writeAttribute('dist', $majorGridlines->getShadowProperty('distance'));
628 }
629 if ($majorGridlines->getShadowProperty('direction') !== null) {
630 $objWriter->writeAttribute('dir', $majorGridlines->getShadowProperty('direction'));
631 }
632 if ($majorGridlines->getShadowProperty('algn') !== null) {
633 $objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn'));
634 }
635 if ($majorGridlines->getShadowProperty(['size', 'sx']) !== null) {
636 $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(['size', 'sx']));
637 }
638 if ($majorGridlines->getShadowProperty(['size', 'sy']) !== null) {
639 $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(['size', 'sy']));
640 }
641 if ($majorGridlines->getShadowProperty(['size', 'kx']) !== null) {
642 $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(['size', 'kx']));
643 }
644 if ($majorGridlines->getShadowProperty('rotWithShape') !== null) {
645 $objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape'));
646 }
647 $objWriter->startElement("a:{$majorGridlines->getShadowProperty(['color', 'type'])}");
648 $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'value']));
649
650 $objWriter->startElement('a:alpha');
651 $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'alpha']));
652 $objWriter->endElement(); //end alpha
653
654 $objWriter->endElement(); //end color:type
655 $objWriter->endElement(); //end shadow
656 }
657
658 if ($majorGridlines->getSoftEdgesSize() !== null) {
659 $objWriter->startElement('a:softEdge');
660 $objWriter->writeAttribute('rad', $majorGridlines->getSoftEdgesSize());
661 $objWriter->endElement(); //end softEdge
662 }
663
664 $objWriter->endElement(); //end effectLst
665 $objWriter->endElement(); //end spPr
666 $objWriter->endElement(); //end majorGridLines
667
668 if ($minorGridlines->getObjectState()) {
669 $objWriter->startElement('c:minorGridlines');
670 $objWriter->startElement('c:spPr');
671
672 if ($minorGridlines->getLineColorProperty('value') !== null) {
673 $objWriter->startElement('a:ln');
674 $objWriter->writeAttribute('w', $minorGridlines->getLineStyleProperty('width'));
675 $objWriter->startElement('a:solidFill');
676 $objWriter->startElement("a:{$minorGridlines->getLineColorProperty('type')}");
677 $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('value'));
678 $objWriter->startElement('a:alpha');
679 $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('alpha'));
680 $objWriter->endElement(); //end alpha
681 $objWriter->endElement(); //end srgbClr
682 $objWriter->endElement(); //end solidFill
683
684 $objWriter->startElement('a:prstDash');
685 $objWriter->writeAttribute('val', $minorGridlines->getLineStyleProperty('dash'));
686 $objWriter->endElement();
687
688 if ($minorGridlines->getLineStyleProperty('join') == 'miter') {
689 $objWriter->startElement('a:miter');
690 $objWriter->writeAttribute('lim', '800000');
691 $objWriter->endElement();
692 } else {
693 $objWriter->startElement('a:bevel');
694 $objWriter->endElement();
695 }
696
697 if ($minorGridlines->getLineStyleProperty(['arrow', 'head', 'type']) !== null) {
698 $objWriter->startElement('a:headEnd');
699 $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(['arrow', 'head', 'type']));
700 $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('head', 'w'));
701 $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('head', 'len'));
702 $objWriter->endElement();
703 }
704
705 if ($minorGridlines->getLineStyleProperty(['arrow', 'end', 'type']) !== null) {
706 $objWriter->startElement('a:tailEnd');
707 $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(['arrow', 'end', 'type']));
708 $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('end', 'w'));
709 $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('end', 'len'));
710 $objWriter->endElement();
711 }
712 $objWriter->endElement(); //end ln
713 }
714
715 $objWriter->startElement('a:effectLst');
716
717 if ($minorGridlines->getGlowSize() !== null) {
718 $objWriter->startElement('a:glow');
719 $objWriter->writeAttribute('rad', $minorGridlines->getGlowSize());
720 $objWriter->startElement("a:{$minorGridlines->getGlowColor('type')}");
721 $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('value'));
722 $objWriter->startElement('a:alpha');
723 $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('alpha'));
724 $objWriter->endElement(); //end alpha
725 $objWriter->endElement(); //end schemeClr
726 $objWriter->endElement(); //end glow
727 }
728
729 if ($minorGridlines->getShadowProperty('presets') !== null) {
730 $objWriter->startElement("a:{$minorGridlines->getShadowProperty('effect')}");
731 if ($minorGridlines->getShadowProperty('blur') !== null) {
732 $objWriter->writeAttribute('blurRad', $minorGridlines->getShadowProperty('blur'));
733 }
734 if ($minorGridlines->getShadowProperty('distance') !== null) {
735 $objWriter->writeAttribute('dist', $minorGridlines->getShadowProperty('distance'));
736 }
737 if ($minorGridlines->getShadowProperty('direction') !== null) {
738 $objWriter->writeAttribute('dir', $minorGridlines->getShadowProperty('direction'));
739 }
740 if ($minorGridlines->getShadowProperty('algn') !== null) {
741 $objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn'));
742 }
743 if ($minorGridlines->getShadowProperty(['size', 'sx']) !== null) {
744 $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(['size', 'sx']));
745 }
746 if ($minorGridlines->getShadowProperty(['size', 'sy']) !== null) {
747 $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(['size', 'sy']));
748 }
749 if ($minorGridlines->getShadowProperty(['size', 'kx']) !== null) {
750 $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(['size', 'kx']));
751 }
752 if ($minorGridlines->getShadowProperty('rotWithShape') !== null) {
753 $objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape'));
754 }
755 $objWriter->startElement("a:{$minorGridlines->getShadowProperty(['color', 'type'])}");
756 $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'value']));
757 $objWriter->startElement('a:alpha');
758 $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'alpha']));
759 $objWriter->endElement(); //end alpha
760 $objWriter->endElement(); //end color:type
761 $objWriter->endElement(); //end shadow
762 }
763
764 if ($minorGridlines->getSoftEdgesSize() !== null) {
765 $objWriter->startElement('a:softEdge');
766 $objWriter->writeAttribute('rad', $minorGridlines->getSoftEdgesSize());
767 $objWriter->endElement(); //end softEdge
768 }
769
770 $objWriter->endElement(); //end effectLst
771 $objWriter->endElement(); //end spPr
772 $objWriter->endElement(); //end minorGridLines
773 }
774
775 if ($yAxisLabel !== null) {
776 $objWriter->startElement('c:title');
777 $objWriter->startElement('c:tx');
778 $objWriter->startElement('c:rich');
779
780 $objWriter->startElement('a:bodyPr');
781 $objWriter->endElement();
782
783 $objWriter->startElement('a:lstStyle');
784 $objWriter->endElement();
785
786 $objWriter->startElement('a:p');
787 $objWriter->startElement('a:r');
788
789 $caption = $yAxisLabel->getCaption();
790 if (is_array($caption)) {
791 $caption = $caption[0];
792 }
793
794 $objWriter->startElement('a:t');
795 $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($caption));
796 $objWriter->endElement();
797
798 $objWriter->endElement();
799 $objWriter->endElement();
800 $objWriter->endElement();
801 $objWriter->endElement();
802
803 if ($groupType !== DataSeries::TYPE_BUBBLECHART) {
804 $layout = $yAxisLabel->getLayout();
805 $this->writeLayout($objWriter, $layout);
806 }
807
808 $objWriter->startElement('c:overlay');
809 $objWriter->writeAttribute('val', 0);
810 $objWriter->endElement();
811
812 $objWriter->endElement();
813 }
814
815 $objWriter->startElement('c:numFmt');
816 $objWriter->writeAttribute('formatCode', $xAxis->getAxisNumberFormat());
817 $objWriter->writeAttribute('sourceLinked', $xAxis->getAxisNumberSourceLinked());
818 $objWriter->endElement();
819
820 $objWriter->startElement('c:majorTickMark');
821 $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_tick_mark'));
822 $objWriter->endElement();
823
824 $objWriter->startElement('c:minorTickMark');
825 $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_tick_mark'));
826 $objWriter->endElement();
827
828 $objWriter->startElement('c:tickLblPos');
829 $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('axis_labels'));
830 $objWriter->endElement();
831
832 $objWriter->startElement('c:spPr');
833
834 if ($xAxis->getFillProperty('value') !== null) {
835 $objWriter->startElement('a:solidFill');
836 $objWriter->startElement('a:' . $xAxis->getFillProperty('type'));
837 $objWriter->writeAttribute('val', $xAxis->getFillProperty('value'));
838 $objWriter->startElement('a:alpha');
839 $objWriter->writeAttribute('val', $xAxis->getFillProperty('alpha'));
840 $objWriter->endElement();
841 $objWriter->endElement();
842 $objWriter->endElement();
843 }
844
845 $objWriter->startElement('a:ln');
846
847 $objWriter->writeAttribute('w', $xAxis->getLineStyleProperty('width'));
848 $objWriter->writeAttribute('cap', $xAxis->getLineStyleProperty('cap'));
849 $objWriter->writeAttribute('cmpd', $xAxis->getLineStyleProperty('compound'));
850
851 if ($xAxis->getLineProperty('value') !== null) {
852 $objWriter->startElement('a:solidFill');
853 $objWriter->startElement('a:' . $xAxis->getLineProperty('type'));
854 $objWriter->writeAttribute('val', $xAxis->getLineProperty('value'));
855 $objWriter->startElement('a:alpha');
856 $objWriter->writeAttribute('val', $xAxis->getLineProperty('alpha'));
857 $objWriter->endElement();
858 $objWriter->endElement();
859 $objWriter->endElement();
860 }
861
862 $objWriter->startElement('a:prstDash');
863 $objWriter->writeAttribute('val', $xAxis->getLineStyleProperty('dash'));
864 $objWriter->endElement();
865
866 if ($xAxis->getLineStyleProperty('join') == 'miter') {
867 $objWriter->startElement('a:miter');
868 $objWriter->writeAttribute('lim', '800000');
869 $objWriter->endElement();
870 } else {
871 $objWriter->startElement('a:bevel');
872 $objWriter->endElement();
873 }
874
875 if ($xAxis->getLineStyleProperty(['arrow', 'head', 'type']) !== null) {
876 $objWriter->startElement('a:headEnd');
877 $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(['arrow', 'head', 'type']));
878 $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('head'));
879 $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('head'));
880 $objWriter->endElement();
881 }
882
883 if ($xAxis->getLineStyleProperty(['arrow', 'end', 'type']) !== null) {
884 $objWriter->startElement('a:tailEnd');
885 $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(['arrow', 'end', 'type']));
886 $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('end'));
887 $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('end'));
888 $objWriter->endElement();
889 }
890
891 $objWriter->endElement();
892
893 $objWriter->startElement('a:effectLst');
894
895 if ($xAxis->getGlowProperty('size') !== null) {
896 $objWriter->startElement('a:glow');
897 $objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size'));
898 $objWriter->startElement("a:{$xAxis->getGlowProperty(['color', 'type'])}");
899 $objWriter->writeAttribute('val', $xAxis->getGlowProperty(['color', 'value']));
900 $objWriter->startElement('a:alpha');
901 $objWriter->writeAttribute('val', $xAxis->getGlowProperty(['color', 'alpha']));
902 $objWriter->endElement();
903 $objWriter->endElement();
904 $objWriter->endElement();
905 }
906
907 if ($xAxis->getShadowProperty('presets') !== null) {
908 $objWriter->startElement("a:{$xAxis->getShadowProperty('effect')}");
909
910 if ($xAxis->getShadowProperty('blur') !== null) {
911 $objWriter->writeAttribute('blurRad', $xAxis->getShadowProperty('blur'));
912 }
913 if ($xAxis->getShadowProperty('distance') !== null) {
914 $objWriter->writeAttribute('dist', $xAxis->getShadowProperty('distance'));
915 }
916 if ($xAxis->getShadowProperty('direction') !== null) {
917 $objWriter->writeAttribute('dir', $xAxis->getShadowProperty('direction'));
918 }
919 if ($xAxis->getShadowProperty('algn') !== null) {
920 $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn'));
921 }
922 if ($xAxis->getShadowProperty(['size', 'sx']) !== null) {
923 $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(['size', 'sx']));
924 }
925 if ($xAxis->getShadowProperty(['size', 'sy']) !== null) {
926 $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(['size', 'sy']));
927 }
928 if ($xAxis->getShadowProperty(['size', 'kx']) !== null) {
929 $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(['size', 'kx']));
930 }
931 if ($xAxis->getShadowProperty('rotWithShape') !== null) {
932 $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape'));
933 }
934
935 $objWriter->startElement("a:{$xAxis->getShadowProperty(['color', 'type'])}");
936 $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color', 'value']));
937 $objWriter->startElement('a:alpha');
938 $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color', 'alpha']));
939 $objWriter->endElement();
940 $objWriter->endElement();
941
942 $objWriter->endElement();
943 }
944
945 if ($xAxis->getSoftEdgesSize() !== null) {
946 $objWriter->startElement('a:softEdge');
947 $objWriter->writeAttribute('rad', $xAxis->getSoftEdgesSize());
948 $objWriter->endElement();
949 }
950
951 $objWriter->endElement(); //effectList
952 $objWriter->endElement(); //end spPr
953
954 if ($id1 > 0) {
955 $objWriter->startElement('c:crossAx');
956 $objWriter->writeAttribute('val', $id2);
957 $objWriter->endElement();
958
959 if ($xAxis->getAxisOptionsProperty('horizontal_crosses_value') !== null) {
960 $objWriter->startElement('c:crossesAt');
961 $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses_value'));
962 $objWriter->endElement();
963 } else {
964 $objWriter->startElement('c:crosses');
965 $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses'));
966 $objWriter->endElement();
967 }
968
969 $objWriter->startElement('c:crossBetween');
970 $objWriter->writeAttribute('val', 'midCat');
971 $objWriter->endElement();
972
973 if ($xAxis->getAxisOptionsProperty('major_unit') !== null) {
974 $objWriter->startElement('c:majorUnit');
975 $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_unit'));
976 $objWriter->endElement();
977 }
978
979 if ($xAxis->getAxisOptionsProperty('minor_unit') !== null) {
980 $objWriter->startElement('c:minorUnit');
981 $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_unit'));
982 $objWriter->endElement();
983 }
984 }
985
986 if ($isMultiLevelSeries) {
987 if ($groupType !== DataSeries::TYPE_BUBBLECHART) {
988 $objWriter->startElement('c:noMultiLvlLbl');
989 $objWriter->writeAttribute('val', 0);
990 $objWriter->endElement();
991 }
992 }
993
994 $objWriter->endElement();
995 }
996
997 /**
998 * Get the data series type(s) for a chart plot series.
999 *
1000 * @param PlotArea $plotArea
1001 *
1002 * @throws WriterException
1003 *
1004 * @return array|string
1005 */
1006 private static function getChartType($plotArea)
1007 {
1008 $groupCount = $plotArea->getPlotGroupCount();
1009
1010 if ($groupCount == 1) {
1011 $chartType = [$plotArea->getPlotGroupByIndex(0)->getPlotType()];
1012 } else {
1013 $chartTypes = [];
1014 for ($i = 0; $i < $groupCount; ++$i) {
1015 $chartTypes[] = $plotArea->getPlotGroupByIndex($i)->getPlotType();
1016 }
1017 $chartType = array_unique($chartTypes);
1018 if (count($chartTypes) == 0) {
1019 throw new WriterException('Chart is not yet implemented');
1020 }
1021 }
1022
1023 return $chartType;
1024 }
1025
1026 /**
1027 * Method writing plot series values.
1028 *
1029 * @param XMLWriter $objWriter XML Writer
1030 * @param int $val value for idx (default: 3)
1031 * @param string $fillColor hex color (default: FF9900)
1032 *
1033 * @return XMLWriter XML Writer
1034 */
1035 private function writePlotSeriesValuesElement($objWriter, $val = 3, $fillColor = 'FF9900')
1036 {
1037 $objWriter->startElement('c:dPt');
1038 $objWriter->startElement('c:idx');
1039 $objWriter->writeAttribute('val', $val);
1040 $objWriter->endElement();
1041
1042 $objWriter->startElement('c:bubble3D');
1043 $objWriter->writeAttribute('val', 0);
1044 $objWriter->endElement();
1045
1046 $objWriter->startElement('c:spPr');
1047 $objWriter->startElement('a:solidFill');
1048 $objWriter->startElement('a:srgbClr');
1049 $objWriter->writeAttribute('val', $fillColor);
1050 $objWriter->endElement();
1051 $objWriter->endElement();
1052 $objWriter->endElement();
1053 $objWriter->endElement();
1054
1055 return $objWriter;
1056 }
1057
1058 /**
1059 * Write Plot Group (series of related plots).
1060 *
1061 * @param DataSeries $plotGroup
1062 * @param string $groupType Type of plot for dataseries
1063 * @param XMLWriter $objWriter XML Writer
1064 * @param bool &$catIsMultiLevelSeries Is category a multi-series category
1065 * @param bool &$valIsMultiLevelSeries Is value set a multi-series set
1066 * @param string &$plotGroupingType Type of grouping for multi-series values
1067 *
1068 * @throws WriterException
1069 */
1070 private function writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType)
1071 {
1072 if ($plotGroup === null) {
1073 return;
1074 }
1075
1076 if (($groupType == DataSeries::TYPE_BARCHART) || ($groupType == DataSeries::TYPE_BARCHART_3D)) {
1077 $objWriter->startElement('c:barDir');
1078 $objWriter->writeAttribute('val', $plotGroup->getPlotDirection());
1079 $objWriter->endElement();
1080 }
1081
1082 if ($plotGroup->getPlotGrouping() !== null) {
1083 $plotGroupingType = $plotGroup->getPlotGrouping();
1084 $objWriter->startElement('c:grouping');
1085 $objWriter->writeAttribute('val', $plotGroupingType);
1086 $objWriter->endElement();
1087 }
1088
1089 // Get these details before the loop, because we can use the count to check for varyColors
1090 $plotSeriesOrder = $plotGroup->getPlotOrder();
1091 $plotSeriesCount = count($plotSeriesOrder);
1092
1093 if (($groupType !== DataSeries::TYPE_RADARCHART) && ($groupType !== DataSeries::TYPE_STOCKCHART)) {
1094 if ($groupType !== DataSeries::TYPE_LINECHART) {
1095 if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART) || ($plotSeriesCount > 1)) {
1096 $objWriter->startElement('c:varyColors');
1097 $objWriter->writeAttribute('val', 1);
1098 $objWriter->endElement();
1099 } else {
1100 $objWriter->startElement('c:varyColors');
1101 $objWriter->writeAttribute('val', 0);
1102 $objWriter->endElement();
1103 }
1104 }
1105 }
1106
1107 foreach ($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) {
1108 $objWriter->startElement('c:ser');
1109
1110 $plotLabel = $plotGroup->getPlotLabelByIndex($plotSeriesIdx);
1111 if ($plotLabel) {
1112 $fillColor = $plotLabel->getFillColor();
1113 if ($fillColor !== null && !is_array($fillColor)) {
1114 $objWriter->startElement('c:spPr');
1115 $objWriter->startElement('a:solidFill');
1116 $objWriter->startElement('a:srgbClr');
1117 $objWriter->writeAttribute('val', $fillColor);
1118 $objWriter->endElement();
1119 $objWriter->endElement();
1120 $objWriter->endElement();
1121 }
1122 }
1123
1124 $objWriter->startElement('c:idx');
1125 $objWriter->writeAttribute('val', $this->seriesIndex + $plotSeriesIdx);
1126 $objWriter->endElement();
1127
1128 $objWriter->startElement('c:order');
1129 $objWriter->writeAttribute('val', $this->seriesIndex + $plotSeriesRef);
1130 $objWriter->endElement();
1131
1132 // Values
1133 $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef);
1134
1135 if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART)) {
1136 $fillColorValues = $plotSeriesValues->getFillColor();
1137 if ($fillColorValues !== null && is_array($fillColorValues)) {
1138 foreach ($plotSeriesValues->getDataValues() as $dataKey => $dataValue) {
1139 $this->writePlotSeriesValuesElement($objWriter, $dataKey, (isset($fillColorValues[$dataKey]) ? $fillColorValues[$dataKey] : 'FF9900'));
1140 }
1141 } else {
1142 $this->writePlotSeriesValuesElement($objWriter);
1143 }
1144 }
1145
1146 // Labels
1147 $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef);
1148 if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) {
1149 $objWriter->startElement('c:tx');
1150 $objWriter->startElement('c:strRef');
1151 $this->writePlotSeriesLabel($plotSeriesLabel, $objWriter);
1152 $objWriter->endElement();
1153 $objWriter->endElement();
1154 }
1155
1156 // Formatting for the points
1157 if (($groupType == DataSeries::TYPE_LINECHART) || ($groupType == DataSeries::TYPE_STOCKCHART)) {
1158 $plotLineWidth = 12700;
1159 if ($plotSeriesValues) {
1160 $plotLineWidth = $plotSeriesValues->getLineWidth();
1161 }
1162
1163 $objWriter->startElement('c:spPr');
1164 $objWriter->startElement('a:ln');
1165 $objWriter->writeAttribute('w', $plotLineWidth);
1166 if ($groupType == DataSeries::TYPE_STOCKCHART) {
1167 $objWriter->startElement('a:noFill');
1168 $objWriter->endElement();
1169 }
1170 $objWriter->endElement();
1171 $objWriter->endElement();
1172 }
1173
1174 if ($plotSeriesValues) {
1175 $plotSeriesMarker = $plotSeriesValues->getPointMarker();
1176 if ($plotSeriesMarker) {
1177 $objWriter->startElement('c:marker');
1178 $objWriter->startElement('c:symbol');
1179 $objWriter->writeAttribute('val', $plotSeriesMarker);
1180 $objWriter->endElement();
1181
1182 if ($plotSeriesMarker !== 'none') {
1183 $objWriter->startElement('c:size');
1184 $objWriter->writeAttribute('val', 3);
1185 $objWriter->endElement();
1186 }
1187
1188 $objWriter->endElement();
1189 }
1190 }
1191
1192 if (($groupType === DataSeries::TYPE_BARCHART) || ($groupType === DataSeries::TYPE_BARCHART_3D) || ($groupType === DataSeries::TYPE_BUBBLECHART)) {
1193 $objWriter->startElement('c:invertIfNegative');
1194 $objWriter->writeAttribute('val', 0);
1195 $objWriter->endElement();
1196 }
1197
1198 // Category Labels
1199 $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef);
1200 if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) {
1201 $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries();
1202
1203 if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART)) {
1204 if ($plotGroup->getPlotStyle() !== null) {
1205 $plotStyle = $plotGroup->getPlotStyle();
1206 if ($plotStyle) {
1207 $objWriter->startElement('c:explosion');
1208 $objWriter->writeAttribute('val', 25);
1209 $objWriter->endElement();
1210 }
1211 }
1212 }
1213
1214 if (($groupType === DataSeries::TYPE_BUBBLECHART) || ($groupType === DataSeries::TYPE_SCATTERCHART)) {
1215 $objWriter->startElement('c:xVal');
1216 } else {
1217 $objWriter->startElement('c:cat');
1218 }
1219
1220 $this->writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str');
1221 $objWriter->endElement();
1222 }
1223
1224 // Values
1225 if ($plotSeriesValues) {
1226 $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries();
1227
1228 if (($groupType === DataSeries::TYPE_BUBBLECHART) || ($groupType === DataSeries::TYPE_SCATTERCHART)) {
1229 $objWriter->startElement('c:yVal');
1230 } else {
1231 $objWriter->startElement('c:val');
1232 }
1233
1234 $this->writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num');
1235 $objWriter->endElement();
1236 }
1237
1238 if ($groupType === DataSeries::TYPE_BUBBLECHART) {
1239 $this->writeBubbles($plotSeriesValues, $objWriter);
1240 }
1241
1242 $objWriter->endElement();
1243 }
1244
1245 $this->seriesIndex += $plotSeriesIdx + 1;
1246 }
1247
1248 /**
1249 * Write Plot Series Label.
1250 *
1251 * @param DataSeriesValues $plotSeriesLabel
1252 * @param XMLWriter $objWriter XML Writer
1253 */
1254 private function writePlotSeriesLabel($plotSeriesLabel, $objWriter)
1255 {
1256 if ($plotSeriesLabel === null) {
1257 return;
1258 }
1259
1260 $objWriter->startElement('c:f');
1261 $objWriter->writeRawData($plotSeriesLabel->getDataSource());
1262 $objWriter->endElement();
1263
1264 $objWriter->startElement('c:strCache');
1265 $objWriter->startElement('c:ptCount');
1266 $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount());
1267 $objWriter->endElement();
1268
1269 foreach ($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) {
1270 $objWriter->startElement('c:pt');
1271 $objWriter->writeAttribute('idx', $plotLabelKey);
1272
1273 $objWriter->startElement('c:v');
1274 $objWriter->writeRawData($plotLabelValue);
1275 $objWriter->endElement();
1276 $objWriter->endElement();
1277 }
1278 $objWriter->endElement();
1279 }
1280
1281 /**
1282 * Write Plot Series Values.
1283 *
1284 * @param DataSeriesValues $plotSeriesValues
1285 * @param XMLWriter $objWriter XML Writer
1286 * @param string $groupType Type of plot for dataseries
1287 * @param string $dataType Datatype of series values
1288 */
1289 private function writePlotSeriesValues($plotSeriesValues, XMLWriter $objWriter, $groupType, $dataType = 'str')
1290 {
1291 if ($plotSeriesValues === null) {
1292 return;
1293 }
1294
1295 if ($plotSeriesValues->isMultiLevelSeries()) {
1296 $levelCount = $plotSeriesValues->multiLevelCount();
1297
1298 $objWriter->startElement('c:multiLvlStrRef');
1299
1300 $objWriter->startElement('c:f');
1301 $objWriter->writeRawData($plotSeriesValues->getDataSource());
1302 $objWriter->endElement();
1303
1304 $objWriter->startElement('c:multiLvlStrCache');
1305
1306 $objWriter->startElement('c:ptCount');
1307 $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
1308 $objWriter->endElement();
1309
1310 for ($level = 0; $level < $levelCount; ++$level) {
1311 $objWriter->startElement('c:lvl');
1312
1313 foreach ($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) {
1314 if (isset($plotSeriesValue[$level])) {
1315 $objWriter->startElement('c:pt');
1316 $objWriter->writeAttribute('idx', $plotSeriesKey);
1317
1318 $objWriter->startElement('c:v');
1319 $objWriter->writeRawData($plotSeriesValue[$level]);
1320 $objWriter->endElement();
1321 $objWriter->endElement();
1322 }
1323 }
1324
1325 $objWriter->endElement();
1326 }
1327
1328 $objWriter->endElement();
1329
1330 $objWriter->endElement();
1331 } else {
1332 $objWriter->startElement('c:' . $dataType . 'Ref');
1333
1334 $objWriter->startElement('c:f');
1335 $objWriter->writeRawData($plotSeriesValues->getDataSource());
1336 $objWriter->endElement();
1337
1338 $objWriter->startElement('c:' . $dataType . 'Cache');
1339
1340 if (($groupType != DataSeries::TYPE_PIECHART) && ($groupType != DataSeries::TYPE_PIECHART_3D) && ($groupType != DataSeries::TYPE_DONUTCHART)) {
1341 if (($plotSeriesValues->getFormatCode() !== null) && ($plotSeriesValues->getFormatCode() !== '')) {
1342 $objWriter->startElement('c:formatCode');
1343 $objWriter->writeRawData($plotSeriesValues->getFormatCode());
1344 $objWriter->endElement();
1345 }
1346 }
1347
1348 $objWriter->startElement('c:ptCount');
1349 $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
1350 $objWriter->endElement();
1351
1352 $dataValues = $plotSeriesValues->getDataValues();
1353 if (!empty($dataValues)) {
1354 if (is_array($dataValues)) {
1355 foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) {
1356 $objWriter->startElement('c:pt');
1357 $objWriter->writeAttribute('idx', $plotSeriesKey);
1358
1359 $objWriter->startElement('c:v');
1360 $objWriter->writeRawData($plotSeriesValue);
1361 $objWriter->endElement();
1362 $objWriter->endElement();
1363 }
1364 }
1365 }
1366
1367 $objWriter->endElement();
1368
1369 $objWriter->endElement();
1370 }
1371 }
1372
1373 /**
1374 * Write Bubble Chart Details.
1375 *
1376 * @param DataSeriesValues $plotSeriesValues
1377 * @param XMLWriter $objWriter XML Writer
1378 */
1379 private function writeBubbles($plotSeriesValues, $objWriter)
1380 {
1381 if ($plotSeriesValues === null) {
1382 return;
1383 }
1384
1385 $objWriter->startElement('c:bubbleSize');
1386 $objWriter->startElement('c:numLit');
1387
1388 $objWriter->startElement('c:formatCode');
1389 $objWriter->writeRawData('General');
1390 $objWriter->endElement();
1391
1392 $objWriter->startElement('c:ptCount');
1393 $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
1394 $objWriter->endElement();
1395
1396 $dataValues = $plotSeriesValues->getDataValues();
1397 if (!empty($dataValues)) {
1398 if (is_array($dataValues)) {
1399 foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) {
1400 $objWriter->startElement('c:pt');
1401 $objWriter->writeAttribute('idx', $plotSeriesKey);
1402 $objWriter->startElement('c:v');
1403 $objWriter->writeRawData(1);
1404 $objWriter->endElement();
1405 $objWriter->endElement();
1406 }
1407 }
1408 }
1409
1410 $objWriter->endElement();
1411 $objWriter->endElement();
1412
1413 $objWriter->startElement('c:bubble3D');
1414 $objWriter->writeAttribute('val', 0);
1415 $objWriter->endElement();
1416 }
1417
1418 /**
1419 * Write Layout.
1420 *
1421 * @param XMLWriter $objWriter XML Writer
1422 * @param Layout $layout
1423 */
1424 private function writeLayout(XMLWriter $objWriter, Layout $layout = null)
1425 {
1426 $objWriter->startElement('c:layout');
1427
1428 if ($layout !== null) {
1429 $objWriter->startElement('c:manualLayout');
1430
1431 $layoutTarget = $layout->getLayoutTarget();
1432 if ($layoutTarget !== null) {
1433 $objWriter->startElement('c:layoutTarget');
1434 $objWriter->writeAttribute('val', $layoutTarget);
1435 $objWriter->endElement();
1436 }
1437
1438 $xMode = $layout->getXMode();
1439 if ($xMode !== null) {
1440 $objWriter->startElement('c:xMode');
1441 $objWriter->writeAttribute('val', $xMode);
1442 $objWriter->endElement();
1443 }
1444
1445 $yMode = $layout->getYMode();
1446 if ($yMode !== null) {
1447 $objWriter->startElement('c:yMode');
1448 $objWriter->writeAttribute('val', $yMode);
1449 $objWriter->endElement();
1450 }
1451
1452 $x = $layout->getXPosition();
1453 if ($x !== null) {
1454 $objWriter->startElement('c:x');
1455 $objWriter->writeAttribute('val', $x);
1456 $objWriter->endElement();
1457 }
1458
1459 $y = $layout->getYPosition();
1460 if ($y !== null) {
1461 $objWriter->startElement('c:y');
1462 $objWriter->writeAttribute('val', $y);
1463 $objWriter->endElement();
1464 }
1465
1466 $w = $layout->getWidth();
1467 if ($w !== null) {
1468 $objWriter->startElement('c:w');
1469 $objWriter->writeAttribute('val', $w);
1470 $objWriter->endElement();
1471 }
1472
1473 $h = $layout->getHeight();
1474 if ($h !== null) {
1475 $objWriter->startElement('c:h');
1476 $objWriter->writeAttribute('val', $h);
1477 $objWriter->endElement();
1478 }
1479
1480 $objWriter->endElement();
1481 }
1482
1483 $objWriter->endElement();
1484 }
1485
1486 /**
1487 * Write Alternate Content block.
1488 *
1489 * @param XMLWriter $objWriter XML Writer
1490 */
1491 private function writeAlternateContent($objWriter)
1492 {
1493 $objWriter->startElement('mc:AlternateContent');
1494 $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
1495
1496 $objWriter->startElement('mc:Choice');
1497 $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart');
1498 $objWriter->writeAttribute('Requires', 'c14');
1499
1500 $objWriter->startElement('c14:style');
1501 $objWriter->writeAttribute('val', '102');
1502 $objWriter->endElement();
1503 $objWriter->endElement();
1504
1505 $objWriter->startElement('mc:Fallback');
1506 $objWriter->startElement('c:style');
1507 $objWriter->writeAttribute('val', '2');
1508 $objWriter->endElement();
1509 $objWriter->endElement();
1510
1511 $objWriter->endElement();
1512 }
1513
1514 /**
1515 * Write Printer Settings.
1516 *
1517 * @param XMLWriter $objWriter XML Writer
1518 */
1519 private function writePrintSettings($objWriter)
1520 {
1521 $objWriter->startElement('c:printSettings');
1522
1523 $objWriter->startElement('c:headerFooter');
1524 $objWriter->endElement();
1525
1526 $objWriter->startElement('c:pageMargins');
1527 $objWriter->writeAttribute('footer', 0.3);
1528 $objWriter->writeAttribute('header', 0.3);
1529 $objWriter->writeAttribute('r', 0.7);
1530 $objWriter->writeAttribute('l', 0.7);
1531 $objWriter->writeAttribute('t', 0.75);
1532 $objWriter->writeAttribute('b', 0.75);
1533 $objWriter->endElement();
1534
1535 $objWriter->startElement('c:pageSetup');
1536 $objWriter->writeAttribute('orientation', 'portrait');
1537 $objWriter->endElement();
1538
1539 $objWriter->endElement();
1540 }
1541 }
1542