Upgrade chart rendering support to be composer based

This allow to get rid of manual class loading and have simpler
usage of the library.
This commit is contained in:
Adrien Crivelli 2017-10-29 01:58:42 +09:00
parent dc9f4327b6
commit 782b4e4fae
No known key found for this signature in database
GPG Key ID: B182FD79DC6DE92E
14 changed files with 246 additions and 218 deletions

View File

@ -54,7 +54,8 @@
"phpunit/phpunit": "^5.7", "phpunit/phpunit": "^5.7",
"dompdf/dompdf": "^0.8.0", "dompdf/dompdf": "^0.8.0",
"mpdf/mpdf": "^7.0.0", "mpdf/mpdf": "^7.0.0",
"friendsofphp/php-cs-fixer": "^2.7" "friendsofphp/php-cs-fixer": "^2.7",
"jpgraph/jpgraph": "^4.0"
}, },
"suggest": { "suggest": {
"ext-gd": "Required for exact column width autocalculation", "ext-gd": "Required for exact column width autocalculation",

42
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "eb3d1cabb8bf94da9858c9fb0c24ed6a", "content-hash": "804bbe054403d6532308f8a65f19adc2",
"packages": [ "packages": [
{ {
"name": "psr/simple-cache", "name": "psr/simple-cache",
@ -527,6 +527,46 @@
], ],
"time": "2014-11-20T16:49:30+00:00" "time": "2014-11-20T16:49:30+00:00"
}, },
{
"name": "jpgraph/jpgraph",
"version": "4.0.2",
"source": {
"type": "git",
"url": "https://github.com/ztec/JpGraph.git",
"reference": "e82db7da6a546d3926c24c9a346226da7aa49094"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ztec/JpGraph/zipball/e82db7da6a546d3926c24c9a346226da7aa49094",
"reference": "e82db7da6a546d3926c24c9a346226da7aa49094",
"shasum": ""
},
"type": "library",
"autoload": {
"classmap": [
"lib/JpGraph.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"QPL 1.0"
],
"authors": [
{
"name": "JpGraph team"
}
],
"description": "jpGraph, library to make graphs and charts",
"homepage": "http://jpgraph.net/",
"keywords": [
"chart",
"data",
"graph",
"jpgraph",
"pie"
],
"time": "2017-02-23T09:44:15+00:00"
},
{ {
"name": "mpdf/mpdf", "name": "mpdf/mpdf",
"version": "v7.0.0", "version": "v7.0.0",

View File

@ -199,6 +199,40 @@ $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Pdf')
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet); $writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
``` ```
### Rendering charts
When rendering charts for HTML or PDF outputs, the process was also simplified. And while
JpGraph support is still available, it is unfortunately not up to date for latest PHP versions
and it will generate various warnings.
If you rely on this feature, please consider
contributing either patches to JpGraph or another `IRenderer` implementation (a good
candidate might be [CpChart](https://github.com/szymach/c-pchart)).
Before:
```php
$rendererName = \PHPExcel_Settings::CHART_RENDERER_JPGRAPH;
$rendererLibrary = 'jpgraph3.5.0b1/src/';
$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;
\PHPExcel_Settings::setChartRenderer($rendererName, $rendererLibraryPath);
```
After:
Require the dependency via composer:
```sh
composer require jpgraph/jpgraph
```
And then:
```php
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class);
```
### PclZip and ZipArchive ### PclZip and ZipArchive
Support for PclZip were dropped in favor of the more complete and modern Support for PclZip were dropped in favor of the more complete and modern

View File

@ -6,16 +6,7 @@ use PhpOffice\PhpSpreadsheet\Settings;
require __DIR__ . '/../Header.php'; require __DIR__ . '/../Header.php';
// Change these values to select the Rendering library that you wish to use // Change these values to select the Rendering library that you wish to use
// and its directory location on your server Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class);
$rendererName = Settings::CHART_RENDERER_JPGRAPH;
$rendererLibrary = 'jpgraph3.5.0b1/src/';
$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;
if (!Settings::setChartRenderer($rendererName, $rendererLibraryPath)) {
$helper->log('NOTICE: Please set the $rendererName and $rendererLibraryPath values at the top of this script as appropriate for your directory structure');
return;
}
$inputFileType = 'Xlsx'; $inputFileType = 'Xlsx';
$inputFileNames = __DIR__ . '/../templates/36write*.xlsx'; $inputFileNames = __DIR__ . '/../templates/36write*.xlsx';
@ -86,7 +77,7 @@ foreach ($inputFileNames as $inputFileName) {
} }
// Save // Save
$filename = $helper->getFilename($inputFileName); $filename = $helper->getFilename($inputFileName, 'html');
$writer = IOFactory::createWriter($spreadsheet, 'Html'); $writer = IOFactory::createWriter($spreadsheet, 'Html');
$writer->setIncludeCharts(true); $writer->setIncludeCharts(true);
$callStartTime = microtime(true); $callStartTime = microtime(true);

View File

@ -8,16 +8,7 @@ require __DIR__ . '/../Header.php';
IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class); IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class);
// Change these values to select the Rendering library that you wish to use // Change these values to select the Rendering library that you wish to use
// for Chart images, and its directory location on your server Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class);
$rendererName = Settings::CHART_RENDERER_JPGRAPH;
$rendererLibrary = 'jpgraph3.5.0b1/src/';
$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;
if (!Settings::setChartRenderer($rendererName, $rendererLibraryPath)) {
$helper->log('NOTICE: Please set the $rendererName and $rendererLibraryPath values at the top of this script as appropriate for your directory structure');
return;
}
$inputFileType = 'Xlsx'; $inputFileType = 'Xlsx';
$inputFileNames = __DIR__ . '/../templates/36write*.xlsx'; $inputFileNames = __DIR__ . '/../templates/36write*.xlsx';
@ -88,7 +79,7 @@ foreach ($inputFileNames as $inputFileName) {
} }
// Save // Save
$filename = $helper->getFilename($inputFileName); $filename = $helper->getFilename($inputFileName, 'pdf');
$writer = IOFactory::createWriter($spreadsheet, 'Pdf'); $writer = IOFactory::createWriter($spreadsheet, 'Pdf');
$writer->setIncludeCharts(true); $writer->setIncludeCharts(true);
$callStartTime = microtime(true); $callStartTime = microtime(true);

View File

@ -6,16 +6,7 @@ use PhpOffice\PhpSpreadsheet\Settings;
require __DIR__ . '/../Header.php'; require __DIR__ . '/../Header.php';
// Change these values to select the Rendering library that you wish to use // Change these values to select the Rendering library that you wish to use
// and its directory location on your server Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class);
$rendererName = Settings::CHART_RENDERER_JPGRAPH;
$rendererLibrary = 'jpgraph3.5.0b1/src/';
$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;
if (!Settings::setChartRenderer($rendererName, $rendererLibraryPath)) {
$helper->log('NOTICE: Please set the $rendererName and $rendererLibraryPath values at the top of this script as appropriate for your directory structure');
return;
}
$inputFileType = 'Xlsx'; $inputFileType = 'Xlsx';
$inputFileNames = __DIR__ . '/../templates/32readwrite*[0-9].xlsx'; $inputFileNames = __DIR__ . '/../templates/32readwrite*[0-9].xlsx';
@ -62,13 +53,14 @@ foreach ($inputFileNames as $inputFileName) {
} }
$helper->log(' ' . $chartName . ' - ' . $caption); $helper->log(' ' . $chartName . ' - ' . $caption);
$jpegFile = $helper->getFilename('35-' . $inputFileNameShort, 'jpg'); $jpegFile = $helper->getFilename('35-' . $inputFileNameShort, 'png');
if (file_exists($jpegFile)) { if (file_exists($jpegFile)) {
unlink($jpegFile); unlink($jpegFile);
} }
try { try {
$chart->render($jpegFile); $chart->render($jpegFile);
$helper->log('Rendered image: ' . $jpegFile);
} catch (Exception $e) { } catch (Exception $e) {
$helper->log('Error rendering chart: ' . $e->getMessage()); $helper->log('Error rendering chart: ' . $e->getMessage());
} }

View File

@ -640,29 +640,29 @@ class Chart
} }
} }
/**
* Render the chart to given file (or stream).
*
* @param string $outputDestination Name of the file render to
*
* @return bool true on success
*/
public function render($outputDestination = null) public function render($outputDestination = null)
{ {
$libraryName = Settings::getChartRendererName();
if ($libraryName === null) {
return false;
}
// Ensure that data series values are up-to-date before we render
$this->refresh();
$libraryPath = Settings::getChartRendererPath();
$includePath = str_replace('\\', '/', get_include_path());
$rendererPath = str_replace('\\', '/', $libraryPath);
if (strpos($rendererPath, $includePath) === false) {
set_include_path(get_include_path() . PATH_SEPARATOR . $libraryPath);
}
$rendererName = '\\PhpOffice\\PhpSpreadsheet\\Chart\\Renderer\\' . $libraryName;
$renderer = new $rendererName($this);
if ($outputDestination == 'php://output') { if ($outputDestination == 'php://output') {
$outputDestination = null; $outputDestination = null;
} }
$libraryName = Settings::getChartRenderer();
if ($libraryName === null) {
return false;
}
// Ensure that data series values are up-to-date before we render
$this->refresh();
$renderer = new $libraryName($this);
return $renderer->render($outputDestination); return $renderer->render($outputDestination);
} }
} }

View File

@ -0,0 +1,24 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Chart\Renderer;
use PhpOffice\PhpSpreadsheet\Chart;
interface IRenderer
{
/**
* IRenderer constructor.
*
* @param Chart $chart
*/
public function __construct(Chart $chart);
/**
* Render the chart to given file (or stream).
*
* @param string $filename Name of the file render to
*
* @return bool true on success
*/
public function render($filename);
}

View File

@ -3,10 +3,11 @@
namespace PhpOffice\PhpSpreadsheet\Chart\Renderer; namespace PhpOffice\PhpSpreadsheet\Chart\Renderer;
use PhpOffice\PhpSpreadsheet\Chart; use PhpOffice\PhpSpreadsheet\Chart;
use PhpOffice\PhpSpreadsheet\Settings;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class JpGraph require_once __DIR__ . '/Polyfill.php';
class JpGraph implements IRenderer
{ {
private static $width = 640; private static $width = 640;
@ -20,7 +21,47 @@ class JpGraph
'goldenrod2', 'goldenrod2',
]; ];
private static $markSet = [ private static $markSet;
private $chart;
private $graph;
private static $plotColour = 0;
private static $plotMark = 0;
/**
* Create a new jpgraph.
*
* @param Chart $chart
*/
public function __construct(Chart $chart)
{
self::init();
$this->graph = null;
$this->chart = $chart;
}
private static function init()
{
static $loaded = false;
if ($loaded) {
return;
}
\JpGraph\JpGraph::load();
\JpGraph\JpGraph::module('bar');
\JpGraph\JpGraph::module('contour');
\JpGraph\JpGraph::module('line');
\JpGraph\JpGraph::module('pie');
\JpGraph\JpGraph::module('pie3d');
\JpGraph\JpGraph::module('radar');
\JpGraph\JpGraph::module('regstat');
\JpGraph\JpGraph::module('scatter');
\JpGraph\JpGraph::module('stock');
self::$markSet = [
'diamond' => MARK_DIAMOND, 'diamond' => MARK_DIAMOND,
'square' => MARK_SQUARE, 'square' => MARK_SQUARE,
'triangle' => MARK_UTRIANGLE, 'triangle' => MARK_UTRIANGLE,
@ -32,13 +73,8 @@ class JpGraph
'plus' => MARK_CROSS, 'plus' => MARK_CROSS,
]; ];
private $chart; $loaded = true;
}
private $graph;
private static $plotColour = 0;
private static $plotMark = 0;
private function formatPointMarker($seriesPlot, $markerID) private function formatPointMarker($seriesPlot, $markerID)
{ {
@ -186,7 +222,7 @@ class JpGraph
private function renderCartesianPlotArea($type = 'textlin') private function renderCartesianPlotArea($type = 'textlin')
{ {
$this->graph = new Graph(self::$width, self::$height); $this->graph = new \Graph(self::$width, self::$height);
$this->graph->SetScale($type); $this->graph->SetScale($type);
$this->renderTitle(); $this->renderTitle();
@ -223,14 +259,14 @@ class JpGraph
private function renderPiePlotArea($doughnut = false) private function renderPiePlotArea($doughnut = false)
{ {
$this->graph = new PieGraph(self::$width, self::$height); $this->graph = new \PieGraph(self::$width, self::$height);
$this->renderTitle(); $this->renderTitle();
} }
private function renderRadarPlotArea() private function renderRadarPlotArea()
{ {
$this->graph = new RadarGraph(self::$width, self::$height); $this->graph = new \RadarGraph(self::$width, self::$height);
$this->graph->SetScale('lin'); $this->graph->SetScale('lin');
$this->renderTitle(); $this->renderTitle();
@ -272,7 +308,7 @@ class JpGraph
++$testCurrentIndex; ++$testCurrentIndex;
} }
$seriesPlot = new LinePlot($dataValues); $seriesPlot = new \LinePlot($dataValues);
if ($combination) { if ($combination) {
$seriesPlot->SetBarCenter(); $seriesPlot->SetBarCenter();
} }
@ -294,7 +330,7 @@ class JpGraph
if ($grouping == 'standard') { if ($grouping == 'standard') {
$groupPlot = $seriesPlots; $groupPlot = $seriesPlots;
} else { } else {
$groupPlot = new AccLinePlot($seriesPlots); $groupPlot = new \AccLinePlot($seriesPlots);
} }
$this->graph->Add($groupPlot); $this->graph->Add($groupPlot);
} }
@ -349,7 +385,7 @@ class JpGraph
if ($rotation == 'bar') { if ($rotation == 'bar') {
$dataValues = array_reverse($dataValues); $dataValues = array_reverse($dataValues);
} }
$seriesPlot = new BarPlot($dataValues); $seriesPlot = new \BarPlot($dataValues);
$seriesPlot->SetColor('black'); $seriesPlot->SetColor('black');
$seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]);
if ($dimensions == '3d') { if ($dimensions == '3d') {
@ -370,11 +406,11 @@ class JpGraph
} }
if ($grouping == 'clustered') { if ($grouping == 'clustered') {
$groupPlot = new GroupBarPlot($seriesPlots); $groupPlot = new \GroupBarPlot($seriesPlots);
} elseif ($grouping == 'standard') { } elseif ($grouping == 'standard') {
$groupPlot = new GroupBarPlot($seriesPlots); $groupPlot = new \GroupBarPlot($seriesPlots);
} else { } else {
$groupPlot = new AccBarPlot($seriesPlots); $groupPlot = new \AccBarPlot($seriesPlots);
if ($dimensions == '3d') { if ($dimensions == '3d') {
$groupPlot->SetShadow(); $groupPlot->SetShadow();
} }
@ -400,14 +436,14 @@ class JpGraph
$dataValuesY[$k] = $k; $dataValuesY[$k] = $k;
} }
$seriesPlot = new ScatterPlot($dataValuesX, $dataValuesY); $seriesPlot = new \ScatterPlot($dataValuesX, $dataValuesY);
if ($scatterStyle == 'lineMarker') { if ($scatterStyle == 'lineMarker') {
$seriesPlot->SetLinkPoints(); $seriesPlot->SetLinkPoints();
$seriesPlot->link->SetColor(self::$colourSet[self::$plotColour]); $seriesPlot->link->SetColor(self::$colourSet[self::$plotColour]);
} elseif ($scatterStyle == 'smoothMarker') { } elseif ($scatterStyle == 'smoothMarker') {
$spline = new Spline($dataValuesY, $dataValuesX); $spline = new \Spline($dataValuesY, $dataValuesX);
list($splineDataY, $splineDataX) = $spline->Get(count($dataValuesX) * self::$width / 20); list($splineDataY, $splineDataX) = $spline->Get(count($dataValuesX) * self::$width / 20);
$lplot = new LinePlot($splineDataX, $splineDataY); $lplot = new \LinePlot($splineDataX, $splineDataY);
$lplot->SetColor(self::$colourSet[self::$plotColour]); $lplot->SetColor(self::$colourSet[self::$plotColour]);
$this->graph->Add($lplot); $this->graph->Add($lplot);
@ -452,7 +488,7 @@ class JpGraph
$this->graph->SetTitles(array_reverse($dataValues)); $this->graph->SetTitles(array_reverse($dataValues));
$seriesPlot = new RadarPlot(array_reverse($dataValuesX)); $seriesPlot = new \RadarPlot(array_reverse($dataValuesX));
$dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue();
$seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]);
@ -481,7 +517,7 @@ class JpGraph
$dataValues[$i] = $dataValuesX; $dataValues[$i] = $dataValuesX;
} }
$seriesPlot = new ContourPlot($dataValues); $seriesPlot = new \ContourPlot($dataValues);
$this->graph->Add($seriesPlot); $this->graph->Add($seriesPlot);
} }
@ -519,7 +555,7 @@ class JpGraph
$this->graph->xaxis->SetTickLabels($datasetLabels); $this->graph->xaxis->SetTickLabels($datasetLabels);
} }
$seriesPlot = new StockPlot($dataValuesPlot); $seriesPlot = new \StockPlot($dataValuesPlot);
$seriesPlot->SetWidth(20); $seriesPlot->SetWidth(20);
$this->graph->Add($seriesPlot); $this->graph->Add($seriesPlot);
@ -527,8 +563,6 @@ class JpGraph
private function renderAreaChart($groupCount, $dimensions = '2d') private function renderAreaChart($groupCount, $dimensions = '2d')
{ {
require_once Settings::getChartRendererPath() . 'jpgraph_line.php';
$this->renderCartesianPlotArea(); $this->renderCartesianPlotArea();
for ($i = 0; $i < $groupCount; ++$i) { for ($i = 0; $i < $groupCount; ++$i) {
@ -538,8 +572,6 @@ class JpGraph
private function renderLineChart($groupCount, $dimensions = '2d') private function renderLineChart($groupCount, $dimensions = '2d')
{ {
require_once Settings::getChartRendererPath() . 'jpgraph_line.php';
$this->renderCartesianPlotArea(); $this->renderCartesianPlotArea();
for ($i = 0; $i < $groupCount; ++$i) { for ($i = 0; $i < $groupCount; ++$i) {
@ -549,8 +581,6 @@ class JpGraph
private function renderBarChart($groupCount, $dimensions = '2d') private function renderBarChart($groupCount, $dimensions = '2d')
{ {
require_once Settings::getChartRendererPath() . 'jpgraph_bar.php';
$this->renderCartesianPlotArea(); $this->renderCartesianPlotArea();
for ($i = 0; $i < $groupCount; ++$i) { for ($i = 0; $i < $groupCount; ++$i) {
@ -560,10 +590,6 @@ class JpGraph
private function renderScatterChart($groupCount) private function renderScatterChart($groupCount)
{ {
require_once Settings::getChartRendererPath() . 'jpgraph_scatter.php';
require_once Settings::getChartRendererPath() . 'jpgraph_regstat.php';
require_once Settings::getChartRendererPath() . 'jpgraph_line.php';
$this->renderCartesianPlotArea('linlin'); $this->renderCartesianPlotArea('linlin');
for ($i = 0; $i < $groupCount; ++$i) { for ($i = 0; $i < $groupCount; ++$i) {
@ -573,8 +599,6 @@ class JpGraph
private function renderBubbleChart($groupCount) private function renderBubbleChart($groupCount)
{ {
require_once Settings::getChartRendererPath() . 'jpgraph_scatter.php';
$this->renderCartesianPlotArea('linlin'); $this->renderCartesianPlotArea('linlin');
for ($i = 0; $i < $groupCount; ++$i) { for ($i = 0; $i < $groupCount; ++$i) {
@ -584,11 +608,6 @@ class JpGraph
private function renderPieChart($groupCount, $dimensions = '2d', $doughnut = false, $multiplePlots = false) private function renderPieChart($groupCount, $dimensions = '2d', $doughnut = false, $multiplePlots = false)
{ {
require_once Settings::getChartRendererPath() . 'jpgraph_pie.php';
if ($dimensions == '3d') {
require_once Settings::getChartRendererPath() . 'jpgraph_pie3d.php';
}
$this->renderPiePlotArea($doughnut); $this->renderPiePlotArea($doughnut);
$iLimit = ($multiplePlots) ? $groupCount : 1; $iLimit = ($multiplePlots) ? $groupCount : 1;
@ -622,12 +641,12 @@ class JpGraph
} }
if ($dimensions == '3d') { if ($dimensions == '3d') {
$seriesPlot = new PiePlot3D($dataValues); $seriesPlot = new \PiePlot3D($dataValues);
} else { } else {
if ($doughnut) { if ($doughnut) {
$seriesPlot = new PiePlotC($dataValues); $seriesPlot = new \PiePlotC($dataValues);
} else { } else {
$seriesPlot = new PiePlot($dataValues); $seriesPlot = new \PiePlot($dataValues);
} }
} }
@ -660,8 +679,6 @@ class JpGraph
private function renderRadarChart($groupCount) private function renderRadarChart($groupCount)
{ {
require_once Settings::getChartRendererPath() . 'jpgraph_radar.php';
$this->renderRadarPlotArea(); $this->renderRadarPlotArea();
for ($groupID = 0; $groupID < $groupCount; ++$groupID) { for ($groupID = 0; $groupID < $groupCount; ++$groupID) {
@ -671,8 +688,6 @@ class JpGraph
private function renderStockChart($groupCount) private function renderStockChart($groupCount)
{ {
require_once Settings::getChartRendererPath() . 'jpgraph_stock.php';
$this->renderCartesianPlotArea('intint'); $this->renderCartesianPlotArea('intint');
for ($groupID = 0; $groupID < $groupCount; ++$groupID) { for ($groupID = 0; $groupID < $groupCount; ++$groupID) {
@ -682,8 +697,6 @@ class JpGraph
private function renderContourChart($groupCount, $dimensions) private function renderContourChart($groupCount, $dimensions)
{ {
require_once Settings::getChartRendererPath() . 'jpgraph_contour.php';
$this->renderCartesianPlotArea('intint'); $this->renderCartesianPlotArea('intint');
for ($i = 0; $i < $groupCount; ++$i) { for ($i = 0; $i < $groupCount; ++$i) {
@ -693,12 +706,6 @@ class JpGraph
private function renderCombinationChart($groupCount, $dimensions, $outputDestination) private function renderCombinationChart($groupCount, $dimensions, $outputDestination)
{ {
require_once Settings::getChartRendererPath() . 'jpgraph_line.php';
require_once Settings::getChartRendererPath() . 'jpgraph_bar.php';
require_once Settings::getChartRendererPath() . 'jpgraph_scatter.php';
require_once Settings::getChartRendererPath() . 'jpgraph_regstat.php';
require_once Settings::getChartRendererPath() . 'jpgraph_line.php';
$this->renderCartesianPlotArea(); $this->renderCartesianPlotArea();
for ($i = 0; $i < $groupCount; ++$i) { for ($i = 0; $i < $groupCount; ++$i) {
@ -844,17 +851,4 @@ class JpGraph
return true; return true;
} }
/**
* Create a new jpgraph.
*
* @param Chart $chart
*/
public function __construct(Chart $chart)
{
$this->graph = null;
$this->chart = $chart;
require_once Settings::getChartRendererPath() . '/jpgraph.php';
}
} }

View File

@ -0,0 +1,9 @@
<?php
// This is a dirty workaround to output JpGraph charts even when antialiasing is not available
if (!function_exists('imageantialias')) {
function imageantialias(...$args)
{
// Do nothing
}
}

View File

@ -157,7 +157,9 @@ class Sample
*/ */
public function getFilename($filename, $extension = 'xlsx') public function getFilename($filename, $extension = 'xlsx')
{ {
return $this->getTemporaryFolder() . '/' . str_replace('.php', '.' . $extension, basename($filename)); $originalExtension = pathinfo($filename, PATHINFO_EXTENSION);
return $this->getTemporaryFolder() . '/' . str_replace('.' . $originalExtension, '.' . $extension, basename($filename));
} }
/** /**

View File

@ -2,33 +2,19 @@
namespace PhpOffice\PhpSpreadsheet; namespace PhpOffice\PhpSpreadsheet;
use PhpOffice\PhpSpreadsheet\Chart\Renderer\IRenderer;
use PhpOffice\PhpSpreadsheet\Collection\Memory; use PhpOffice\PhpSpreadsheet\Collection\Memory;
use Psr\SimpleCache\CacheInterface; use Psr\SimpleCache\CacheInterface;
class Settings class Settings
{ {
/** Optional Chart Rendering libraries */
const CHART_RENDERER_JPGRAPH = 'JpGraph';
private static $chartRenderers = [
self::CHART_RENDERER_JPGRAPH,
];
/** /**
* Name of the external Library used for rendering charts * Class name of the chart renderer used for rendering charts
* e.g. * eg: PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph.
* jpgraph.
* *
* @var string * @var string
*/ */
private static $chartRendererName; private static $chartRenderer;
/**
* Directory Path to the external Library used for rendering charts.
*
* @var string
*/
private static $chartRendererPath;
/** /**
* Default options for libxml loader. * Default options for libxml loader.
@ -56,80 +42,32 @@ class Settings
return Calculation::getInstance()->setLocale($locale); return Calculation::getInstance()->setLocale($locale);
} }
/**
* Set details of the external library that PhpSpreadsheet should use for rendering charts.
*
* @param string $libraryName Internal reference name of the library
* e.g. \PhpOffice\PhpSpreadsheet\Settings::CHART_RENDERER_JPGRAPH
* @param string $libraryBaseDir Directory path to the library's base folder
*
* @return bool Success or failure
*/
public static function setChartRenderer($libraryName, $libraryBaseDir)
{
if (!self::setChartRendererName($libraryName)) {
return false;
}
return self::setChartRendererPath($libraryBaseDir);
}
/** /**
* Identify to PhpSpreadsheet the external library to use for rendering charts. * Identify to PhpSpreadsheet the external library to use for rendering charts.
* *
* @param string $libraryName Internal reference name of the library * @param string $rendererClass Class name of the chart renderer
* e.g. \PhpOffice\PhpSpreadsheet\Settings::CHART_RENDERER_JPGRAPH * eg: PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph
* *
* @return bool Success or failure * @throws Exception
*/ */
public static function setChartRendererName($libraryName) public static function setChartRenderer($rendererClass)
{ {
if (!in_array($libraryName, self::$chartRenderers)) { if (!is_a($rendererClass, IRenderer::class, true)) {
return false; throw new Exception('Chart renderer must implement ' . IRenderer::class);
} }
self::$chartRendererName = $libraryName;
return true; self::$chartRenderer = $rendererClass;
} }
/** /**
* Tell PhpSpreadsheet where to find the external library to use for rendering charts. * Return the Chart Rendering Library that PhpSpreadsheet is currently configured to use.
* *
* @param string $libraryBaseDir Directory path to the library's base folder * @return null|string Class name of the chart renderer
* * eg: PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph
* @return bool Success or failure
*/ */
public static function setChartRendererPath($libraryBaseDir) public static function getChartRenderer()
{ {
if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) { return self::$chartRenderer;
return false;
}
self::$chartRendererPath = $libraryBaseDir;
return true;
}
/**
* Return the Chart Rendering Library that PhpSpreadsheet is currently configured to use (e.g. jpgraph).
*
* @return null|string Internal reference name of the Chart Rendering Library that PhpSpreadsheet is
* currently configured to use
* e.g. \PhpOffice\PhpSpreadsheet\Settings::CHART_RENDERER_JPGRAPH
*/
public static function getChartRendererName()
{
return self::$chartRendererName;
}
/**
* Return the directory path to the Chart Rendering Library that PhpSpreadsheet is currently configured to use.
*
* @return null|string Directory Path to the Chart Rendering Library that PhpSpreadsheet is
* currently configured to use
*/
public static function getChartRendererPath()
{
return self::$chartRendererPath;
} }
/** /**

View File

@ -2,8 +2,17 @@
namespace PhpOffice\PhpSpreadsheet\Writer; namespace PhpOffice\PhpSpreadsheet\Writer;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
interface IWriter interface IWriter
{ {
/**
* IWriter constructor.
*
* @param Spreadsheet $spreadsheet
*/
public function __construct(Spreadsheet $spreadsheet);
/** /**
* Save PhpSpreadsheet to file. * Save PhpSpreadsheet to file.
* *

View File

@ -25,15 +25,18 @@ class SampleTest extends PHPUnit_Framework_TestCase
public function providerSample() public function providerSample()
{ {
$skipped = []; $skipped = [
'Chart/32_Chart_read_write_PDF.php', // Unfortunately JpGraph is not up to date for latest PHP and raise many warnings
'Chart/32_Chart_read_write_HTML.php', // idem
];
// Unfortunately some tests are too long be ran with code-coverage // Unfortunately some tests are too long be ran with code-coverage
// analysis on Travis, so we need to exclude them // analysis on Travis, so we need to exclude them
global $argv; global $argv;
if (in_array('--coverage-clover', $argv)) { if (in_array('--coverage-clover', $argv)) {
$tooLongToBeCovered = [ $tooLongToBeCovered = [
'06 Largescale', 'Basic/06_Largescale.php',
'13 CalculationCyclicFormulae', 'Basic/13_CalculationCyclicFormulae.php',
]; ];
$skipped = array_merge($skipped, $tooLongToBeCovered); $skipped = array_merge($skipped, $tooLongToBeCovered);
} }
@ -41,8 +44,8 @@ class SampleTest extends PHPUnit_Framework_TestCase
$helper = new Sample(); $helper = new Sample();
$result = []; $result = [];
foreach ($helper->getSamples() as $samples) { foreach ($helper->getSamples() as $samples) {
foreach ($samples as $name => $sample) { foreach ($samples as $sample) {
if (!in_array($name, $skipped)) { if (!in_array($sample, $skipped)) {
$file = '../samples/' . $sample; $file = '../samples/' . $sample;
$result[] = [$file]; $result[] = [$file];
} }