1<?php
2
3namespace PhpOffice\PhpSpreadsheet\Chart;
4
5use PhpOffice\PhpSpreadsheet\Settings;
6use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
7
8class Chart
9{
10    /**
11     * Chart Name.
12     *
13     * @var string
14     */
15    private $name = '';
16
17    /**
18     * Worksheet.
19     *
20     * @var Worksheet
21     */
22    private $worksheet;
23
24    /**
25     * Chart Title.
26     *
27     * @var Title
28     */
29    private $title;
30
31    /**
32     * Chart Legend.
33     *
34     * @var Legend
35     */
36    private $legend;
37
38    /**
39     * X-Axis Label.
40     *
41     * @var Title
42     */
43    private $xAxisLabel;
44
45    /**
46     * Y-Axis Label.
47     *
48     * @var Title
49     */
50    private $yAxisLabel;
51
52    /**
53     * Chart Plot Area.
54     *
55     * @var PlotArea
56     */
57    private $plotArea;
58
59    /**
60     * Plot Visible Only.
61     *
62     * @var bool
63     */
64    private $plotVisibleOnly = true;
65
66    /**
67     * Display Blanks as.
68     *
69     * @var string
70     */
71    private $displayBlanksAs = '0';
72
73    /**
74     * Chart Asix Y as.
75     *
76     * @var Axis
77     */
78    private $yAxis;
79
80    /**
81     * Chart Asix X as.
82     *
83     * @var Axis
84     */
85    private $xAxis;
86
87    /**
88     * Chart Major Gridlines as.
89     *
90     * @var GridLines
91     */
92    private $majorGridlines;
93
94    /**
95     * Chart Minor Gridlines as.
96     *
97     * @var GridLines
98     */
99    private $minorGridlines;
100
101    /**
102     * Top-Left Cell Position.
103     *
104     * @var string
105     */
106    private $topLeftCellRef = 'A1';
107
108    /**
109     * Top-Left X-Offset.
110     *
111     * @var int
112     */
113    private $topLeftXOffset = 0;
114
115    /**
116     * Top-Left Y-Offset.
117     *
118     * @var int
119     */
120    private $topLeftYOffset = 0;
121
122    /**
123     * Bottom-Right Cell Position.
124     *
125     * @var string
126     */
127    private $bottomRightCellRef = 'A1';
128
129    /**
130     * Bottom-Right X-Offset.
131     *
132     * @var int
133     */
134    private $bottomRightXOffset = 10;
135
136    /**
137     * Bottom-Right Y-Offset.
138     *
139     * @var int
140     */
141    private $bottomRightYOffset = 10;
142
143    /**
144     * Create a new Chart.
145     *
146     * @param mixed $name
147     * @param null|Title $title
148     * @param null|Legend $legend
149     * @param null|PlotArea $plotArea
150     * @param mixed $plotVisibleOnly
151     * @param mixed $displayBlanksAs
152     * @param null|Title $xAxisLabel
153     * @param null|Title $yAxisLabel
154     * @param null|Axis $xAxis
155     * @param null|Axis $yAxis
156     * @param null|GridLines $majorGridlines
157     * @param null|GridLines $minorGridlines
158     */
159    public function __construct($name, Title $title = null, Legend $legend = null, PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = '0', Title $xAxisLabel = null, Title $yAxisLabel = null, Axis $xAxis = null, Axis $yAxis = null, GridLines $majorGridlines = null, GridLines $minorGridlines = null)
160    {
161        $this->name = $name;
162        $this->title = $title;
163        $this->legend = $legend;
164        $this->xAxisLabel = $xAxisLabel;
165        $this->yAxisLabel = $yAxisLabel;
166        $this->plotArea = $plotArea;
167        $this->plotVisibleOnly = $plotVisibleOnly;
168        $this->displayBlanksAs = $displayBlanksAs;
169        $this->xAxis = $xAxis;
170        $this->yAxis = $yAxis;
171        $this->majorGridlines = $majorGridlines;
172        $this->minorGridlines = $minorGridlines;
173    }
174
175    /**
176     * Get Name.
177     *
178     * @return string
179     */
180    public function getName()
181    {
182        return $this->name;
183    }
184
185    /**
186     * Get Worksheet.
187     *
188     * @return Worksheet
189     */
190    public function getWorksheet()
191    {
192        return $this->worksheet;
193    }
194
195    /**
196     * Set Worksheet.
197     *
198     * @param Worksheet $pValue
199     *
200     * @return Chart
201     */
202    public function setWorksheet(Worksheet $pValue = null)
203    {
204        $this->worksheet = $pValue;
205
206        return $this;
207    }
208
209    /**
210     * Get Title.
211     *
212     * @return Title
213     */
214    public function getTitle()
215    {
216        return $this->title;
217    }
218
219    /**
220     * Set Title.
221     *
222     * @param Title $title
223     *
224     * @return Chart
225     */
226    public function setTitle(Title $title)
227    {
228        $this->title = $title;
229
230        return $this;
231    }
232
233    /**
234     * Get Legend.
235     *
236     * @return Legend
237     */
238    public function getLegend()
239    {
240        return $this->legend;
241    }
242
243    /**
244     * Set Legend.
245     *
246     * @param Legend $legend
247     *
248     * @return Chart
249     */
250    public function setLegend(Legend $legend)
251    {
252        $this->legend = $legend;
253
254        return $this;
255    }
256
257    /**
258     * Get X-Axis Label.
259     *
260     * @return Title
261     */
262    public function getXAxisLabel()
263    {
264        return $this->xAxisLabel;
265    }
266
267    /**
268     * Set X-Axis Label.
269     *
270     * @param Title $label
271     *
272     * @return Chart
273     */
274    public function setXAxisLabel(Title $label)
275    {
276        $this->xAxisLabel = $label;
277
278        return $this;
279    }
280
281    /**
282     * Get Y-Axis Label.
283     *
284     * @return Title
285     */
286    public function getYAxisLabel()
287    {
288        return $this->yAxisLabel;
289    }
290
291    /**
292     * Set Y-Axis Label.
293     *
294     * @param Title $label
295     *
296     * @return Chart
297     */
298    public function setYAxisLabel(Title $label)
299    {
300        $this->yAxisLabel = $label;
301
302        return $this;
303    }
304
305    /**
306     * Get Plot Area.
307     *
308     * @return PlotArea
309     */
310    public function getPlotArea()
311    {
312        return $this->plotArea;
313    }
314
315    /**
316     * Get Plot Visible Only.
317     *
318     * @return bool
319     */
320    public function getPlotVisibleOnly()
321    {
322        return $this->plotVisibleOnly;
323    }
324
325    /**
326     * Set Plot Visible Only.
327     *
328     * @param bool $plotVisibleOnly
329     *
330     * @return Chart
331     */
332    public function setPlotVisibleOnly($plotVisibleOnly)
333    {
334        $this->plotVisibleOnly = $plotVisibleOnly;
335
336        return $this;
337    }
338
339    /**
340     * Get Display Blanks as.
341     *
342     * @return string
343     */
344    public function getDisplayBlanksAs()
345    {
346        return $this->displayBlanksAs;
347    }
348
349    /**
350     * Set Display Blanks as.
351     *
352     * @param string $displayBlanksAs
353     *
354     * @return Chart
355     */
356    public function setDisplayBlanksAs($displayBlanksAs)
357    {
358        $this->displayBlanksAs = $displayBlanksAs;
359
360        return $this;
361    }
362
363    /**
364     * Get yAxis.
365     *
366     * @return Axis
367     */
368    public function getChartAxisY()
369    {
370        if ($this->yAxis !== null) {
371            return $this->yAxis;
372        }
373
374        return new Axis();
375    }
376
377    /**
378     * Get xAxis.
379     *
380     * @return Axis
381     */
382    public function getChartAxisX()
383    {
384        if ($this->xAxis !== null) {
385            return $this->xAxis;
386        }
387
388        return new Axis();
389    }
390
391    /**
392     * Get Major Gridlines.
393     *
394     * @return GridLines
395     */
396    public function getMajorGridlines()
397    {
398        if ($this->majorGridlines !== null) {
399            return $this->majorGridlines;
400        }
401
402        return new GridLines();
403    }
404
405    /**
406     * Get Minor Gridlines.
407     *
408     * @return GridLines
409     */
410    public function getMinorGridlines()
411    {
412        if ($this->minorGridlines !== null) {
413            return $this->minorGridlines;
414        }
415
416        return new GridLines();
417    }
418
419    /**
420     * Set the Top Left position for the chart.
421     *
422     * @param string $cell
423     * @param int $xOffset
424     * @param int $yOffset
425     *
426     * @return Chart
427     */
428    public function setTopLeftPosition($cell, $xOffset = null, $yOffset = null)
429    {
430        $this->topLeftCellRef = $cell;
431        if ($xOffset !== null) {
432            $this->setTopLeftXOffset($xOffset);
433        }
434        if ($yOffset !== null) {
435            $this->setTopLeftYOffset($yOffset);
436        }
437
438        return $this;
439    }
440
441    /**
442     * Get the top left position of the chart.
443     *
444     * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
445     */
446    public function getTopLeftPosition()
447    {
448        return [
449            'cell' => $this->topLeftCellRef,
450            'xOffset' => $this->topLeftXOffset,
451            'yOffset' => $this->topLeftYOffset,
452        ];
453    }
454
455    /**
456     * Get the cell address where the top left of the chart is fixed.
457     *
458     * @return string
459     */
460    public function getTopLeftCell()
461    {
462        return $this->topLeftCellRef;
463    }
464
465    /**
466     * Set the Top Left cell position for the chart.
467     *
468     * @param string $cell
469     *
470     * @return Chart
471     */
472    public function setTopLeftCell($cell)
473    {
474        $this->topLeftCellRef = $cell;
475
476        return $this;
477    }
478
479    /**
480     * Set the offset position within the Top Left cell for the chart.
481     *
482     * @param int $xOffset
483     * @param int $yOffset
484     *
485     * @return Chart
486     */
487    public function setTopLeftOffset($xOffset, $yOffset)
488    {
489        if ($xOffset !== null) {
490            $this->setTopLeftXOffset($xOffset);
491        }
492
493        if ($yOffset !== null) {
494            $this->setTopLeftYOffset($yOffset);
495        }
496
497        return $this;
498    }
499
500    /**
501     * Get the offset position within the Top Left cell for the chart.
502     *
503     * @return int[]
504     */
505    public function getTopLeftOffset()
506    {
507        return [
508            'X' => $this->topLeftXOffset,
509            'Y' => $this->topLeftYOffset,
510        ];
511    }
512
513    public function setTopLeftXOffset($xOffset)
514    {
515        $this->topLeftXOffset = $xOffset;
516
517        return $this;
518    }
519
520    public function getTopLeftXOffset()
521    {
522        return $this->topLeftXOffset;
523    }
524
525    public function setTopLeftYOffset($yOffset)
526    {
527        $this->topLeftYOffset = $yOffset;
528
529        return $this;
530    }
531
532    public function getTopLeftYOffset()
533    {
534        return $this->topLeftYOffset;
535    }
536
537    /**
538     * Set the Bottom Right position of the chart.
539     *
540     * @param string $cell
541     * @param int $xOffset
542     * @param int $yOffset
543     *
544     * @return Chart
545     */
546    public function setBottomRightPosition($cell, $xOffset = null, $yOffset = null)
547    {
548        $this->bottomRightCellRef = $cell;
549        if ($xOffset !== null) {
550            $this->setBottomRightXOffset($xOffset);
551        }
552        if ($yOffset !== null) {
553            $this->setBottomRightYOffset($yOffset);
554        }
555
556        return $this;
557    }
558
559    /**
560     * Get the bottom right position of the chart.
561     *
562     * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
563     */
564    public function getBottomRightPosition()
565    {
566        return [
567            'cell' => $this->bottomRightCellRef,
568            'xOffset' => $this->bottomRightXOffset,
569            'yOffset' => $this->bottomRightYOffset,
570        ];
571    }
572
573    public function setBottomRightCell($cell)
574    {
575        $this->bottomRightCellRef = $cell;
576
577        return $this;
578    }
579
580    /**
581     * Get the cell address where the bottom right of the chart is fixed.
582     *
583     * @return string
584     */
585    public function getBottomRightCell()
586    {
587        return $this->bottomRightCellRef;
588    }
589
590    /**
591     * Set the offset position within the Bottom Right cell for the chart.
592     *
593     * @param int $xOffset
594     * @param int $yOffset
595     *
596     * @return Chart
597     */
598    public function setBottomRightOffset($xOffset, $yOffset)
599    {
600        if ($xOffset !== null) {
601            $this->setBottomRightXOffset($xOffset);
602        }
603
604        if ($yOffset !== null) {
605            $this->setBottomRightYOffset($yOffset);
606        }
607
608        return $this;
609    }
610
611    /**
612     * Get the offset position within the Bottom Right cell for the chart.
613     *
614     * @return int[]
615     */
616    public function getBottomRightOffset()
617    {
618        return [
619            'X' => $this->bottomRightXOffset,
620            'Y' => $this->bottomRightYOffset,
621        ];
622    }
623
624    public function setBottomRightXOffset($xOffset)
625    {
626        $this->bottomRightXOffset = $xOffset;
627
628        return $this;
629    }
630
631    public function getBottomRightXOffset()
632    {
633        return $this->bottomRightXOffset;
634    }
635
636    public function setBottomRightYOffset($yOffset)
637    {
638        $this->bottomRightYOffset = $yOffset;
639
640        return $this;
641    }
642
643    public function getBottomRightYOffset()
644    {
645        return $this->bottomRightYOffset;
646    }
647
648    public function refresh()
649    {
650        if ($this->worksheet !== null) {
651            $this->plotArea->refresh($this->worksheet);
652        }
653    }
654
655    /**
656     * Render the chart to given file (or stream).
657     *
658     * @param string $outputDestination Name of the file render to
659     *
660     * @return bool true on success
661     */
662    public function render($outputDestination = null)
663    {
664        if ($outputDestination == 'php://output') {
665            $outputDestination = null;
666        }
667
668        $libraryName = Settings::getChartRenderer();
669        if ($libraryName === null) {
670            return false;
671        }
672
673        // Ensure that data series values are up-to-date before we render
674        $this->refresh();
675
676        $renderer = new $libraryName($this);
677
678        return $renderer->render($outputDestination);
679    }
680}
681