Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Chart;
   4  
   5  use PhpOffice\PhpSpreadsheet\Settings;
   6  use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
   7  
   8  class 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 = DataSeries::EMPTY_AS_GAP;
  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       * Top-Left Cell Position.
  89       *
  90       * @var string
  91       */
  92      private $topLeftCellRef = 'A1';
  93  
  94      /**
  95       * Top-Left X-Offset.
  96       *
  97       * @var int
  98       */
  99      private $topLeftXOffset = 0;
 100  
 101      /**
 102       * Top-Left Y-Offset.
 103       *
 104       * @var int
 105       */
 106      private $topLeftYOffset = 0;
 107  
 108      /**
 109       * Bottom-Right Cell Position.
 110       *
 111       * @var string
 112       */
 113      private $bottomRightCellRef = '';
 114  
 115      /**
 116       * Bottom-Right X-Offset.
 117       *
 118       * @var int
 119       */
 120      private $bottomRightXOffset = 10;
 121  
 122      /**
 123       * Bottom-Right Y-Offset.
 124       *
 125       * @var int
 126       */
 127      private $bottomRightYOffset = 10;
 128  
 129      /** @var ?int */
 130      private $rotX;
 131  
 132      /** @var ?int */
 133      private $rotY;
 134  
 135      /** @var ?int */
 136      private $rAngAx;
 137  
 138      /** @var ?int */
 139      private $perspective;
 140  
 141      /** @var bool */
 142      private $oneCellAnchor = false;
 143  
 144      /** @var bool */
 145      private $autoTitleDeleted = false;
 146  
 147      /** @var bool */
 148      private $noFill = false;
 149  
 150      /** @var bool */
 151      private $roundedCorners = false;
 152  
 153      /**
 154       * Create a new Chart.
 155       * majorGridlines and minorGridlines are deprecated, moved to Axis.
 156       *
 157       * @param mixed $name
 158       * @param mixed $plotVisibleOnly
 159       * @param string $displayBlanksAs
 160       */
 161      public function __construct($name, ?Title $title = null, ?Legend $legend = null, ?PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = DataSeries::EMPTY_AS_GAP, ?Title $xAxisLabel = null, ?Title $yAxisLabel = null, ?Axis $xAxis = null, ?Axis $yAxis = null, ?GridLines $majorGridlines = null, ?GridLines $minorGridlines = null)
 162      {
 163          $this->name = $name;
 164          $this->title = $title;
 165          $this->legend = $legend;
 166          $this->xAxisLabel = $xAxisLabel;
 167          $this->yAxisLabel = $yAxisLabel;
 168          $this->plotArea = $plotArea;
 169          $this->plotVisibleOnly = $plotVisibleOnly;
 170          $this->displayBlanksAs = $displayBlanksAs;
 171          $this->xAxis = $xAxis ?? new Axis();
 172          $this->yAxis = $yAxis ?? new Axis();
 173          if ($majorGridlines !== null) {
 174              $this->yAxis->setMajorGridlines($majorGridlines);
 175          }
 176          if ($minorGridlines !== null) {
 177              $this->yAxis->setMinorGridlines($minorGridlines);
 178          }
 179      }
 180  
 181      /**
 182       * Get Name.
 183       *
 184       * @return string
 185       */
 186      public function getName()
 187      {
 188          return $this->name;
 189      }
 190  
 191      public function setName(string $name): self
 192      {
 193          $this->name = $name;
 194  
 195          return $this;
 196      }
 197  
 198      /**
 199       * Get Worksheet.
 200       */
 201      public function getWorksheet(): ?Worksheet
 202      {
 203          return $this->worksheet;
 204      }
 205  
 206      /**
 207       * Set Worksheet.
 208       *
 209       * @return $this
 210       */
 211      public function setWorksheet(?Worksheet $worksheet = null)
 212      {
 213          $this->worksheet = $worksheet;
 214  
 215          return $this;
 216      }
 217  
 218      public function getTitle(): ?Title
 219      {
 220          return $this->title;
 221      }
 222  
 223      /**
 224       * Set Title.
 225       *
 226       * @return $this
 227       */
 228      public function setTitle(Title $title)
 229      {
 230          $this->title = $title;
 231  
 232          return $this;
 233      }
 234  
 235      public function getLegend(): ?Legend
 236      {
 237          return $this->legend;
 238      }
 239  
 240      /**
 241       * Set Legend.
 242       *
 243       * @return $this
 244       */
 245      public function setLegend(Legend $legend)
 246      {
 247          $this->legend = $legend;
 248  
 249          return $this;
 250      }
 251  
 252      public function getXAxisLabel(): ?Title
 253      {
 254          return $this->xAxisLabel;
 255      }
 256  
 257      /**
 258       * Set X-Axis Label.
 259       *
 260       * @return $this
 261       */
 262      public function setXAxisLabel(Title $label)
 263      {
 264          $this->xAxisLabel = $label;
 265  
 266          return $this;
 267      }
 268  
 269      public function getYAxisLabel(): ?Title
 270      {
 271          return $this->yAxisLabel;
 272      }
 273  
 274      /**
 275       * Set Y-Axis Label.
 276       *
 277       * @return $this
 278       */
 279      public function setYAxisLabel(Title $label)
 280      {
 281          $this->yAxisLabel = $label;
 282  
 283          return $this;
 284      }
 285  
 286      public function getPlotArea(): ?PlotArea
 287      {
 288          return $this->plotArea;
 289      }
 290  
 291      /**
 292       * Set Plot Area.
 293       */
 294      public function setPlotArea(PlotArea $plotArea): self
 295      {
 296          $this->plotArea = $plotArea;
 297  
 298          return $this;
 299      }
 300  
 301      /**
 302       * Get Plot Visible Only.
 303       *
 304       * @return bool
 305       */
 306      public function getPlotVisibleOnly()
 307      {
 308          return $this->plotVisibleOnly;
 309      }
 310  
 311      /**
 312       * Set Plot Visible Only.
 313       *
 314       * @param bool $plotVisibleOnly
 315       *
 316       * @return $this
 317       */
 318      public function setPlotVisibleOnly($plotVisibleOnly)
 319      {
 320          $this->plotVisibleOnly = $plotVisibleOnly;
 321  
 322          return $this;
 323      }
 324  
 325      /**
 326       * Get Display Blanks as.
 327       *
 328       * @return string
 329       */
 330      public function getDisplayBlanksAs()
 331      {
 332          return $this->displayBlanksAs;
 333      }
 334  
 335      /**
 336       * Set Display Blanks as.
 337       *
 338       * @param string $displayBlanksAs
 339       *
 340       * @return $this
 341       */
 342      public function setDisplayBlanksAs($displayBlanksAs)
 343      {
 344          $this->displayBlanksAs = $displayBlanksAs;
 345  
 346          return $this;
 347      }
 348  
 349      public function getChartAxisY(): Axis
 350      {
 351          return $this->yAxis;
 352      }
 353  
 354      /**
 355       * Set yAxis.
 356       */
 357      public function setChartAxisY(?Axis $axis): self
 358      {
 359          $this->yAxis = $axis ?? new Axis();
 360  
 361          return $this;
 362      }
 363  
 364      public function getChartAxisX(): Axis
 365      {
 366          return $this->xAxis;
 367      }
 368  
 369      /**
 370       * Set xAxis.
 371       */
 372      public function setChartAxisX(?Axis $axis): self
 373      {
 374          $this->xAxis = $axis ?? new Axis();
 375  
 376          return $this;
 377      }
 378  
 379      /**
 380       * Get Major Gridlines.
 381       *
 382       * @Deprecated 1.24.0 Use Axis->getMajorGridlines
 383       *
 384       * @codeCoverageIgnore
 385       */
 386      public function getMajorGridlines(): ?GridLines
 387      {
 388          return $this->yAxis->getMajorGridLines();
 389      }
 390  
 391      /**
 392       * Get Minor Gridlines.
 393       *
 394       * @Deprecated 1.24.0 Use Axis->getMinorGridlines
 395       *
 396       * @codeCoverageIgnore
 397       */
 398      public function getMinorGridlines(): ?GridLines
 399      {
 400          return $this->yAxis->getMinorGridLines();
 401      }
 402  
 403      /**
 404       * Set the Top Left position for the chart.
 405       *
 406       * @param string $cellAddress
 407       * @param int $xOffset
 408       * @param int $yOffset
 409       *
 410       * @return $this
 411       */
 412      public function setTopLeftPosition($cellAddress, $xOffset = null, $yOffset = null)
 413      {
 414          $this->topLeftCellRef = $cellAddress;
 415          if ($xOffset !== null) {
 416              $this->setTopLeftXOffset($xOffset);
 417          }
 418          if ($yOffset !== null) {
 419              $this->setTopLeftYOffset($yOffset);
 420          }
 421  
 422          return $this;
 423      }
 424  
 425      /**
 426       * Get the top left position of the chart.
 427       *
 428       * @return array{cell: string, xOffset: int, yOffset: int} an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
 429       */
 430      public function getTopLeftPosition()
 431      {
 432          return [
 433              'cell' => $this->topLeftCellRef,
 434              'xOffset' => $this->topLeftXOffset,
 435              'yOffset' => $this->topLeftYOffset,
 436          ];
 437      }
 438  
 439      /**
 440       * Get the cell address where the top left of the chart is fixed.
 441       *
 442       * @return string
 443       */
 444      public function getTopLeftCell()
 445      {
 446          return $this->topLeftCellRef;
 447      }
 448  
 449      /**
 450       * Set the Top Left cell position for the chart.
 451       *
 452       * @param string $cellAddress
 453       *
 454       * @return $this
 455       */
 456      public function setTopLeftCell($cellAddress)
 457      {
 458          $this->topLeftCellRef = $cellAddress;
 459  
 460          return $this;
 461      }
 462  
 463      /**
 464       * Set the offset position within the Top Left cell for the chart.
 465       *
 466       * @param int $xOffset
 467       * @param int $yOffset
 468       *
 469       * @return $this
 470       */
 471      public function setTopLeftOffset($xOffset, $yOffset)
 472      {
 473          if ($xOffset !== null) {
 474              $this->setTopLeftXOffset($xOffset);
 475          }
 476  
 477          if ($yOffset !== null) {
 478              $this->setTopLeftYOffset($yOffset);
 479          }
 480  
 481          return $this;
 482      }
 483  
 484      /**
 485       * Get the offset position within the Top Left cell for the chart.
 486       *
 487       * @return int[]
 488       */
 489      public function getTopLeftOffset()
 490      {
 491          return [
 492              'X' => $this->topLeftXOffset,
 493              'Y' => $this->topLeftYOffset,
 494          ];
 495      }
 496  
 497      /**
 498       * @param int $xOffset
 499       *
 500       * @return $this
 501       */
 502      public function setTopLeftXOffset($xOffset)
 503      {
 504          $this->topLeftXOffset = $xOffset;
 505  
 506          return $this;
 507      }
 508  
 509      public function getTopLeftXOffset(): int
 510      {
 511          return $this->topLeftXOffset;
 512      }
 513  
 514      /**
 515       * @param int $yOffset
 516       *
 517       * @return $this
 518       */
 519      public function setTopLeftYOffset($yOffset)
 520      {
 521          $this->topLeftYOffset = $yOffset;
 522  
 523          return $this;
 524      }
 525  
 526      public function getTopLeftYOffset(): int
 527      {
 528          return $this->topLeftYOffset;
 529      }
 530  
 531      /**
 532       * Set the Bottom Right position of the chart.
 533       *
 534       * @param string $cellAddress
 535       * @param int $xOffset
 536       * @param int $yOffset
 537       *
 538       * @return $this
 539       */
 540      public function setBottomRightPosition($cellAddress = '', $xOffset = null, $yOffset = null)
 541      {
 542          $this->bottomRightCellRef = $cellAddress;
 543          if ($xOffset !== null) {
 544              $this->setBottomRightXOffset($xOffset);
 545          }
 546          if ($yOffset !== null) {
 547              $this->setBottomRightYOffset($yOffset);
 548          }
 549  
 550          return $this;
 551      }
 552  
 553      /**
 554       * Get the bottom right position of the chart.
 555       *
 556       * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
 557       */
 558      public function getBottomRightPosition()
 559      {
 560          return [
 561              'cell' => $this->bottomRightCellRef,
 562              'xOffset' => $this->bottomRightXOffset,
 563              'yOffset' => $this->bottomRightYOffset,
 564          ];
 565      }
 566  
 567      /**
 568       * Set the Bottom Right cell for the chart.
 569       *
 570       * @return $this
 571       */
 572      public function setBottomRightCell(string $cellAddress = '')
 573      {
 574          $this->bottomRightCellRef = $cellAddress;
 575  
 576          return $this;
 577      }
 578  
 579      /**
 580       * Get the cell address where the bottom right of the chart is fixed.
 581       */
 582      public function getBottomRightCell(): string
 583      {
 584          return $this->bottomRightCellRef;
 585      }
 586  
 587      /**
 588       * Set the offset position within the Bottom Right cell for the chart.
 589       *
 590       * @param int $xOffset
 591       * @param int $yOffset
 592       *
 593       * @return $this
 594       */
 595      public function setBottomRightOffset($xOffset, $yOffset)
 596      {
 597          if ($xOffset !== null) {
 598              $this->setBottomRightXOffset($xOffset);
 599          }
 600  
 601          if ($yOffset !== null) {
 602              $this->setBottomRightYOffset($yOffset);
 603          }
 604  
 605          return $this;
 606      }
 607  
 608      /**
 609       * Get the offset position within the Bottom Right cell for the chart.
 610       *
 611       * @return int[]
 612       */
 613      public function getBottomRightOffset()
 614      {
 615          return [
 616              'X' => $this->bottomRightXOffset,
 617              'Y' => $this->bottomRightYOffset,
 618          ];
 619      }
 620  
 621      /**
 622       * @param int $xOffset
 623       *
 624       * @return $this
 625       */
 626      public function setBottomRightXOffset($xOffset)
 627      {
 628          $this->bottomRightXOffset = $xOffset;
 629  
 630          return $this;
 631      }
 632  
 633      public function getBottomRightXOffset(): int
 634      {
 635          return $this->bottomRightXOffset;
 636      }
 637  
 638      /**
 639       * @param int $yOffset
 640       *
 641       * @return $this
 642       */
 643      public function setBottomRightYOffset($yOffset)
 644      {
 645          $this->bottomRightYOffset = $yOffset;
 646  
 647          return $this;
 648      }
 649  
 650      public function getBottomRightYOffset(): int
 651      {
 652          return $this->bottomRightYOffset;
 653      }
 654  
 655      public function refresh(): void
 656      {
 657          if ($this->worksheet !== null && $this->plotArea !== null) {
 658              $this->plotArea->refresh($this->worksheet);
 659          }
 660      }
 661  
 662      /**
 663       * Render the chart to given file (or stream).
 664       *
 665       * @param string $outputDestination Name of the file render to
 666       *
 667       * @return bool true on success
 668       */
 669      public function render($outputDestination = null)
 670      {
 671          if ($outputDestination == 'php://output') {
 672              $outputDestination = null;
 673          }
 674  
 675          $libraryName = Settings::getChartRenderer();
 676          if ($libraryName === null) {
 677              return false;
 678          }
 679  
 680          // Ensure that data series values are up-to-date before we render
 681          $this->refresh();
 682  
 683          $renderer = new $libraryName($this);
 684  
 685          return $renderer->render($outputDestination); // @phpstan-ignore-line
 686      }
 687  
 688      public function getRotX(): ?int
 689      {
 690          return $this->rotX;
 691      }
 692  
 693      public function setRotX(?int $rotX): self
 694      {
 695          $this->rotX = $rotX;
 696  
 697          return $this;
 698      }
 699  
 700      public function getRotY(): ?int
 701      {
 702          return $this->rotY;
 703      }
 704  
 705      public function setRotY(?int $rotY): self
 706      {
 707          $this->rotY = $rotY;
 708  
 709          return $this;
 710      }
 711  
 712      public function getRAngAx(): ?int
 713      {
 714          return $this->rAngAx;
 715      }
 716  
 717      public function setRAngAx(?int $rAngAx): self
 718      {
 719          $this->rAngAx = $rAngAx;
 720  
 721          return $this;
 722      }
 723  
 724      public function getPerspective(): ?int
 725      {
 726          return $this->perspective;
 727      }
 728  
 729      public function setPerspective(?int $perspective): self
 730      {
 731          $this->perspective = $perspective;
 732  
 733          return $this;
 734      }
 735  
 736      public function getOneCellAnchor(): bool
 737      {
 738          return $this->oneCellAnchor;
 739      }
 740  
 741      public function setOneCellAnchor(bool $oneCellAnchor): self
 742      {
 743          $this->oneCellAnchor = $oneCellAnchor;
 744  
 745          return $this;
 746      }
 747  
 748      public function getAutoTitleDeleted(): bool
 749      {
 750          return $this->autoTitleDeleted;
 751      }
 752  
 753      public function setAutoTitleDeleted(bool $autoTitleDeleted): self
 754      {
 755          $this->autoTitleDeleted = $autoTitleDeleted;
 756  
 757          return $this;
 758      }
 759  
 760      public function getNoFill(): bool
 761      {
 762          return $this->noFill;
 763      }
 764  
 765      public function setNoFill(bool $noFill): self
 766      {
 767          $this->noFill = $noFill;
 768  
 769          return $this;
 770      }
 771  
 772      public function getRoundedCorners(): bool
 773      {
 774          return $this->roundedCorners;
 775      }
 776  
 777      public function setRoundedCorners(?bool $roundedCorners): self
 778      {
 779          if ($roundedCorners !== null) {
 780              $this->roundedCorners = $roundedCorners;
 781          }
 782  
 783          return $this;
 784      }
 785  }