#278: 3D charts and ability to set width and height
This commit is contained in:
parent
0f085f71e0
commit
a13e5b20f9
|
|
@ -15,7 +15,8 @@ This release added drawing shapes (arc, curve, line, polyline, rect, oval) and b
|
|||
- Section: Ability to set paper size, e.g. A4, A3, and Legal - @ivanlanin GH-249
|
||||
- General: New `PhpWord::save()` method to encapsulate `IOFactory` - @ivanlanin
|
||||
- General: New `Shared\Converter` static class - @ivanlanin
|
||||
- Element: Basic 2D chart (pie, doughnut, bar, line, area, scatter, radar) - @ivanlanin GH-278
|
||||
- Chart: Basic 2D chart (pie, doughnut, bar, line, area, scatter, radar) - @ivanlanin GH-278
|
||||
- Chart: 3D charts and ability to set width and height - @ivanlanin
|
||||
|
||||
### Bugfixes
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
<?php
|
||||
include_once 'Sample_Header.php';
|
||||
|
||||
use PhpOffice\PhpWord\Shared\Converter;
|
||||
|
||||
// New Word document
|
||||
echo date('H:i:s'), " Create new PhpWord object", EOL;
|
||||
|
||||
$phpWord = new \PhpOffice\PhpWord\PhpWord();
|
||||
|
||||
$section = $phpWord->addSection(array('colsNum' => 2));
|
||||
$phpWord->addTitleStyle(1, array('size' => 14, 'bold' => true), array('keepNext' => true, 'spaceBefore' => 240));
|
||||
$phpWord->addTitleStyle(2, array('size' => 14, 'bold' => true), array('keepNext' => true, 'spaceBefore' => 240));
|
||||
|
||||
$chartTypes = array('pie', 'doughnut', 'bar', 'line', 'area', 'scatter', 'radar');
|
||||
$twoSeries = array('bar', 'line', 'area', 'scatter', 'radar');
|
||||
// 2D charts
|
||||
$section = $phpWord->addSection();
|
||||
$section->addTitle('2D charts', 1);
|
||||
$section = $phpWord->addSection(array('colsNum' => 2, 'breakType' => 'continuous'));
|
||||
|
||||
$chartTypes = array('pie', 'doughnut', 'bar', 'column', 'line', 'area', 'scatter', 'radar');
|
||||
$twoSeries = array('bar', 'column', 'line', 'area', 'scatter', 'radar');
|
||||
$threeSeries = array('bar', 'line');
|
||||
$categories = array('A', 'B', 'C', 'D', 'E');
|
||||
$series1 = array(1, 3, 2, 5, 4);
|
||||
|
|
@ -18,8 +24,11 @@ $series2 = array(3, 1, 7, 2, 6);
|
|||
$series3 = array(8, 3, 2, 5, 4);
|
||||
|
||||
foreach ($chartTypes as $chartType) {
|
||||
$section->addTitle(ucfirst($chartType), 1);
|
||||
$section->addTitle(ucfirst($chartType), 2);
|
||||
$chart = $section->addChart($chartType, $categories, $series1);
|
||||
$chart->getStyle()
|
||||
->setWidth(Converter::inchToEmu(2.5))
|
||||
->setHeight(Converter::inchToEmu(2));
|
||||
if (in_array($chartType, $twoSeries)) {
|
||||
$chart->addSeries($categories, $series2);
|
||||
}
|
||||
|
|
@ -29,6 +38,24 @@ foreach ($chartTypes as $chartType) {
|
|||
$section->addTextBreak();
|
||||
}
|
||||
|
||||
// 3D charts
|
||||
$section = $phpWord->addSection(array('breakType' => 'continuous'));
|
||||
$section->addTitle('3D charts', 1);
|
||||
$section = $phpWord->addSection(array('colsNum' => 2, 'breakType' => 'continuous'));
|
||||
|
||||
$chartTypes = array('pie', 'bar', 'column', 'line', 'area');
|
||||
$multiSeries = array('bar', 'column', 'line', 'area');
|
||||
$style = array('width' => Converter::cmToEmu(5), 'height' => Converter::cmToEmu(4), '3d' => true);
|
||||
foreach ($chartTypes as $chartType) {
|
||||
$section->addTitle(ucfirst($chartType), 2);
|
||||
$chart = $section->addChart($chartType, $categories, $series1, $style);
|
||||
if (in_array($chartType, $multiSeries)) {
|
||||
$chart->addSeries($categories, $series2);
|
||||
$chart->addSeries($categories, $series3);
|
||||
}
|
||||
$section->addTextBreak();
|
||||
}
|
||||
|
||||
// Save file
|
||||
echo write($phpWord, basename(__FILE__, '.php'), $writers);
|
||||
if (!CLI) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
namespace PhpOffice\PhpWord\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Style\Chart as ChartStyle;
|
||||
|
||||
|
||||
/**
|
||||
* Chart element
|
||||
*
|
||||
|
|
@ -45,6 +48,13 @@ class Chart extends AbstractElement
|
|||
*/
|
||||
private $series = array();
|
||||
|
||||
/**
|
||||
* Chart style
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Style\Chart
|
||||
*/
|
||||
private $style;
|
||||
|
||||
/**
|
||||
* Create new instance
|
||||
*
|
||||
|
|
@ -52,10 +62,11 @@ class Chart extends AbstractElement
|
|||
* @param array $categories
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct($type, $categories, $values)
|
||||
public function __construct($type, $categories, $values, $style = null)
|
||||
{
|
||||
$this->setType($type);
|
||||
$this->addSeries($categories, $values);
|
||||
$this->style = $this->setNewStyle(new ChartStyle(), $style, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -75,7 +86,7 @@ class Chart extends AbstractElement
|
|||
*/
|
||||
public function setType($value)
|
||||
{
|
||||
$enum = array('pie', 'doughnut', 'line', 'bar', 'area', 'radar', 'scatter');
|
||||
$enum = array('pie', 'doughnut', 'line', 'bar', 'column', 'area', 'radar', 'scatter');
|
||||
$this->type = $this->setEnumVal($value, $enum, 'pie');
|
||||
}
|
||||
|
||||
|
|
@ -99,4 +110,14 @@ class Chart extends AbstractElement
|
|||
{
|
||||
return $this->series;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get chart style
|
||||
*
|
||||
* @return \PhpOffice\PhpWord\Style\Chart
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
return $this->style;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,28 @@ class Converter
|
|||
return $centimeter / self::INCH_TO_CM * self::INCH_TO_PIXEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert centimeter to point
|
||||
*
|
||||
* @param int $centimeter
|
||||
* @return float
|
||||
*/
|
||||
public static function cmToPoint($centimeter = 1)
|
||||
{
|
||||
return $centimeter / self::INCH_TO_CM * self::INCH_TO_POINT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert centimeter to EMU
|
||||
*
|
||||
* @param int $centimeter
|
||||
* @return int
|
||||
*/
|
||||
public static function cmToEmu($centimeter = 1)
|
||||
{
|
||||
return round($centimeter / self::INCH_TO_CM * self::INCH_TO_PIXEL * self::PIXEL_TO_EMU);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert inch to twip
|
||||
*
|
||||
|
|
@ -106,6 +128,17 @@ class Converter
|
|||
return $inch * self::INCH_TO_POINT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert inch to EMU
|
||||
*
|
||||
* @param int $inch
|
||||
* @return int
|
||||
*/
|
||||
public static function inchToEmu($inch = 1)
|
||||
{
|
||||
return round($inch * self::INCH_TO_PIXEL * self::PIXEL_TO_EMU);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert pixel to twip
|
||||
*
|
||||
|
|
|
|||
|
|
@ -244,8 +244,10 @@ abstract class AbstractStyle
|
|||
if (is_string($value) && (preg_match('/[^\d]/', $value) == 0)) {
|
||||
$value = intval($value);
|
||||
}
|
||||
if (!is_int($value)) {
|
||||
if (!is_numeric($value)) {
|
||||
$value = $default;
|
||||
} else {
|
||||
$value = intval($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of PHPWord - A pure PHP library for reading and writing
|
||||
* word processing documents.
|
||||
*
|
||||
* PHPWord is free software distributed under the terms of the GNU Lesser
|
||||
* General Public License version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please read the LICENSE
|
||||
* file that was distributed with this source code. For the full list of
|
||||
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
|
||||
*
|
||||
* @link https://github.com/PHPOffice/PHPWord
|
||||
* @copyright 2010-2014 PHPWord contributors
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
||||
*/
|
||||
|
||||
namespace PhpOffice\PhpWord\Style;
|
||||
|
||||
/**
|
||||
* Chart style
|
||||
*
|
||||
* @since 0.12.0
|
||||
*/
|
||||
class Chart extends AbstractStyle
|
||||
{
|
||||
|
||||
/**
|
||||
* Width (in EMU)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $width = 1000000;
|
||||
|
||||
/**
|
||||
* Height (in EMU)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $height = 1000000;
|
||||
|
||||
/**
|
||||
* Is 3D; applies to pie, bar, line, area
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is3d = false;
|
||||
|
||||
/**
|
||||
* Create a new instance
|
||||
*
|
||||
* @param array $style
|
||||
*/
|
||||
public function __construct($style = array())
|
||||
{
|
||||
$this->setStyleByArray($style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get width
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set width
|
||||
*
|
||||
* @param int $value
|
||||
* @return self
|
||||
*/
|
||||
public function setWidth($value = null)
|
||||
{
|
||||
$this->width = $this->setIntVal($value, $this->width);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get height
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set height
|
||||
*
|
||||
* @param int $value
|
||||
* @return self
|
||||
*/
|
||||
public function setHeight($value = null)
|
||||
{
|
||||
$this->height = $this->setIntVal($value, $this->height);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is 3D
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is3d()
|
||||
{
|
||||
return $this->is3d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set 3D
|
||||
*
|
||||
* @param bool $value
|
||||
* @return self
|
||||
*/
|
||||
public function set3d($value = true)
|
||||
{
|
||||
$this->is3d = $this->setBoolVal($value, $this->is3d);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
@ -38,6 +38,7 @@ class Chart extends AbstractElement
|
|||
}
|
||||
|
||||
$rId = $element->getRelationId();
|
||||
$style = $element->getStyle();
|
||||
|
||||
if (!$this->withoutP) {
|
||||
$xmlWriter->startElement('w:p');
|
||||
|
|
@ -48,7 +49,7 @@ class Chart extends AbstractElement
|
|||
$xmlWriter->startElement('wp:inline');
|
||||
|
||||
// EMU
|
||||
$xmlWriter->writeElementBlock('wp:extent', array('cx' => '2000000', 'cy' => '2000000'));
|
||||
$xmlWriter->writeElementBlock('wp:extent', array('cx' => $style->getWidth(), 'cy' => $style->getHeight()));
|
||||
$xmlWriter->writeElementBlock('wp:docPr', array('id' => $rId, 'name' => "Chart{$rId}"));
|
||||
|
||||
$xmlWriter->startElement('a:graphic');
|
||||
|
|
|
|||
|
|
@ -41,13 +41,14 @@ class Chart extends AbstractPart
|
|||
* @var array
|
||||
*/
|
||||
private $types = array(
|
||||
'pie' => array('type' => 'pieChart', 'colors' => 1),
|
||||
'doughnut' => array('type' => 'doughnutChart', 'colors' => 1, 'hole' => 75),
|
||||
'bar' => array('type' => 'barChart', 'colors' => 0, 'axes' => true, 'bar' => 'col'),
|
||||
'line' => array('type' => 'lineChart', 'colors' => 0, 'axes' => true),
|
||||
'area' => array('type' => 'areaChart', 'colors' => 0, 'axes' => true),
|
||||
'radar' => array('type' => 'radarChart', 'colors' => 0, 'axes' => true, 'radar' => 'standard'),
|
||||
'scatter' => array('type' => 'scatterChart', 'colors' => 0, 'axes' => true, 'scatter' => 'marker'),
|
||||
'pie' => array('type' => 'pie', 'colors' => 1),
|
||||
'doughnut' => array('type' => 'doughnut', 'colors' => 1, 'hole' => 75, 'no3d' => true),
|
||||
'bar' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'bar'),
|
||||
'column' => array('type' => 'bar', 'colors' => 0, 'axes' => true, 'bar' => 'col'),
|
||||
'line' => array('type' => 'line', 'colors' => 0, 'axes' => true),
|
||||
'area' => array('type' => 'area', 'colors' => 0, 'axes' => true),
|
||||
'radar' => array('type' => 'radar', 'colors' => 0, 'axes' => true, 'radar' => 'standard', 'no3d' => true),
|
||||
'scatter' => array('type' => 'scatter', 'colors' => 0, 'axes' => true, 'scatter' => 'marker', 'no3d' => true),
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -119,13 +120,17 @@ class Chart extends AbstractPart
|
|||
private function writePlotArea(XMLWriter $xmlWriter)
|
||||
{
|
||||
$type = $this->element->getType();
|
||||
$style = $this->element->getStyle();
|
||||
$this->options = $this->types[$type];
|
||||
|
||||
$xmlWriter->startElement('c:plotArea');
|
||||
$xmlWriter->writeElement('c:layout');
|
||||
|
||||
// Chart
|
||||
$xmlWriter->startElement('c:' . $this->options['type']);
|
||||
$chartType = $this->options['type'];
|
||||
$chartType .= $style->is3d() && !isset($this->options['no3d'])? '3D' : '';
|
||||
$chartType .= 'Chart';
|
||||
$xmlWriter->startElement("c:{$chartType}");
|
||||
|
||||
$xmlWriter->writeElementBlock('c:varyColors', 'val', $this->options['colors']);
|
||||
if ($type == 'area') {
|
||||
|
|
@ -136,7 +141,7 @@ class Chart extends AbstractPart
|
|||
}
|
||||
if (isset($this->options['bar'])) {
|
||||
$xmlWriter->writeElementBlock('c:barDir', 'val', $this->options['bar']); // bar|col
|
||||
$xmlWriter->writeElementBlock('c:grouping', 'val', 'clustered');
|
||||
$xmlWriter->writeElementBlock('c:grouping', 'val', 'clustered'); // 3d; standard = percentStacked
|
||||
}
|
||||
if (isset($this->options['radar'])) {
|
||||
$xmlWriter->writeElementBlock('c:radarStyle', 'val', $this->options['radar']);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,12 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
|
|||
$result = Converter::cmToPixel($value);
|
||||
$this->assertEquals($value / 2.54 * 96, $result);
|
||||
|
||||
$result = Converter::cmToPoint($value);
|
||||
$this->assertEquals($value / 2.54 * 72, $result);
|
||||
|
||||
$result = Converter::cmToEmu($value);
|
||||
$this->assertEquals(round($value / 2.54 * 96 * 9525), $result);
|
||||
|
||||
$result = Converter::inchToTwip($value);
|
||||
$this->assertEquals($value * 1440, $result);
|
||||
|
||||
|
|
@ -57,6 +63,9 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
|
|||
$result = Converter::inchToPoint($value);
|
||||
$this->assertEquals($value * 72, $result);
|
||||
|
||||
$result = Converter::inchToEmu($value);
|
||||
$this->assertEquals(round($value * 96 * 9525), $result);
|
||||
|
||||
$result = Converter::pixelToTwip($value);
|
||||
$this->assertEquals($value / 96 * 1440, $result);
|
||||
|
||||
|
|
|
|||
|
|
@ -156,12 +156,13 @@ class ElementTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
$phpWord = new PhpWord();
|
||||
$section = $phpWord->addSection();
|
||||
$style = array('width' => 1000000, 'height' => 1000000, '3d' => true);
|
||||
|
||||
$chartTypes = array('pie', 'doughnut', 'bar', 'line', 'area', 'scatter', 'radar');
|
||||
$categories = array('A', 'B', 'C', 'D', 'E');
|
||||
$series1 = array(1, 3, 2, 5, 4);
|
||||
foreach ($chartTypes as $chartType) {
|
||||
$section->addChart($chartType, $categories, $series1);
|
||||
$section->addChart($chartType, $categories, $series1, $style);
|
||||
}
|
||||
|
||||
$doc = TestHelperDOCX::getDocument($phpWord);
|
||||
|
|
|
|||
Loading…
Reference in New Issue