Merge branch 'chart' into develop
This commit is contained in:
commit
0f085f71e0
|
|
@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers
|
|||
|
||||
## 0.12.0 - Not yet released
|
||||
|
||||
This release added drawing shapes (arc, curve, line, polyline, rect, oval) element and some new styles.
|
||||
This release added drawing shapes (arc, curve, line, polyline, rect, oval) and basic 2D chart (pie, doughnut, bar, line, area, scatter, radar) elements along with some new styles.
|
||||
|
||||
### Features
|
||||
|
||||
|
|
@ -15,6 +15,7 @@ This release added drawing shapes (arc, curve, line, polyline, rect, oval) eleme
|
|||
- 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
|
||||
|
||||
### Bugfixes
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ With PHPWord, you can create DOCX, ODT, or RTF documents dynamically using your
|
|||
- Insert list items as bulleted, numbered, or multilevel
|
||||
- Insert hyperlinks
|
||||
- Insert footnotes and endnotes
|
||||
- Insert drawing shapes (arc, curve, line, polyline, rect, oval)
|
||||
- Insert charts (pie, doughnut, bar, line, area, scatter, radar)
|
||||
- Create document from templates
|
||||
- Use XSL 1.0 style sheets to transform main document part of OOXML template
|
||||
- ... and many more features on progress
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ column shows the containers while the rows lists the elements.
|
|||
+-------+-----------------+-----------+----------+----------+---------+------------+------------+
|
||||
| 20 | Shape | v | v | v | v | v | v |
|
||||
+-------+-----------------+-----------+----------+----------+---------+------------+------------+
|
||||
| 21 | Chart | v | - | - | - | - | - |
|
||||
+-------+-----------------+-----------+----------+----------+---------+------------+------------+
|
||||
|
||||
Legend:
|
||||
|
||||
|
|
@ -399,3 +401,8 @@ Shapes
|
|||
------
|
||||
|
||||
To be completed.
|
||||
|
||||
Charts
|
||||
------
|
||||
|
||||
To be completed.
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ Features
|
|||
- Insert list items as bulleted, numbered, or multilevel
|
||||
- Insert hyperlinks
|
||||
- Insert footnotes and endnotes
|
||||
- Insert drawing shapes (arc, curve, line, polyline, rect, oval)
|
||||
- Insert charts (pie, doughnut, bar, line, area, scatter, radar)
|
||||
- Create document from templates
|
||||
- Use XSL 1.0 style sheets to transform main document part of OOXML
|
||||
template
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ Don't forget to change `code::` directive to `code-block::` in the resulting rst
|
|||
- [Fields](#fields)
|
||||
- [Lines](#lines)
|
||||
- [Shapes](#shapes)
|
||||
- [Charts](#charts)
|
||||
- [Styles](#styles)
|
||||
- [Section](#section)
|
||||
- [Font](#font)
|
||||
|
|
@ -76,6 +77,8 @@ PHPWord is an open source project licensed under the terms of [LGPL version 3](h
|
|||
- Insert list items as bulleted, numbered, or multilevel
|
||||
- Insert hyperlinks
|
||||
- Insert footnotes and endnotes
|
||||
- Insert drawing shapes (arc, curve, line, polyline, rect, oval)
|
||||
- Insert charts (pie, doughnut, bar, line, area, scatter, radar)
|
||||
- Create document from templates
|
||||
- Use XSL 1.0 style sheets to transform main document part of OOXML template
|
||||
- ... and many more features on progress
|
||||
|
|
@ -440,6 +443,7 @@ Below are the matrix of element availability in each container. The column shows
|
|||
| 18 | Field | v | v | v | v | v | v |
|
||||
| 19 | Line | v | v | v | v | v | v |
|
||||
| 20 | Shape | v | v | v | v | v | v |
|
||||
| 21 | Chart | v | - | - | - | - | - |
|
||||
|
||||
Legend:
|
||||
|
||||
|
|
@ -737,6 +741,10 @@ To be completed.
|
|||
|
||||
To be completed.
|
||||
|
||||
## Charts
|
||||
|
||||
To be completed.
|
||||
|
||||
# Styles
|
||||
|
||||
## Section
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
include_once 'Sample_Header.php';
|
||||
|
||||
// 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));
|
||||
|
||||
$chartTypes = array('pie', 'doughnut', 'bar', 'line', 'area', 'scatter', 'radar');
|
||||
$twoSeries = array('bar', 'line', 'area', 'scatter', 'radar');
|
||||
$threeSeries = array('bar', 'line');
|
||||
$categories = array('A', 'B', 'C', 'D', 'E');
|
||||
$series1 = array(1, 3, 2, 5, 4);
|
||||
$series2 = array(3, 1, 7, 2, 6);
|
||||
$series3 = array(8, 3, 2, 5, 4);
|
||||
|
||||
foreach ($chartTypes as $chartType) {
|
||||
$section->addTitle(ucfirst($chartType), 1);
|
||||
$chart = $section->addChart($chartType, $categories, $series1);
|
||||
if (in_array($chartType, $twoSeries)) {
|
||||
$chart->addSeries($categories, $series2);
|
||||
}
|
||||
if (in_array($chartType, $threeSeries)) {
|
||||
$chart->addSeries($categories, $series3);
|
||||
}
|
||||
$section->addTextBreak();
|
||||
}
|
||||
|
||||
// Save file
|
||||
echo write($phpWord, basename(__FILE__, '.php'), $writers);
|
||||
if (!CLI) {
|
||||
include_once 'Sample_Footer.php';
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?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/old-licenses/lgpl-2.1.txt LGPL
|
||||
*/
|
||||
|
||||
namespace PhpOffice\PhpWord\Collection;
|
||||
|
||||
/**
|
||||
* Charts collection
|
||||
*
|
||||
* @since 0.12.0
|
||||
*/
|
||||
class Charts extends AbstractCollection
|
||||
{
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ namespace PhpOffice\PhpWord\Element;
|
|||
* @method Field addField(string $type = null, array $properties = array(), array $options = array())
|
||||
* @method Line addLine(mixed $lineStyle = null)
|
||||
* @method Shape addObject(string $type, mixed $style = null)
|
||||
* @method Chart addChart()
|
||||
*
|
||||
* @since 0.10.0
|
||||
*/
|
||||
|
|
@ -77,7 +78,7 @@ abstract class AbstractContainer extends AbstractElement
|
|||
$elements = array('Text', 'TextRun', 'Link', 'PreserveText', 'TextBreak',
|
||||
'ListItem', 'ListItemRun', 'Table', 'Image', 'Object', 'Footnote',
|
||||
'Endnote', 'CheckBox', 'TextBox', 'Field', 'Line', 'Shape',
|
||||
'Title', 'TOC', 'PageBreak');
|
||||
'Title', 'TOC', 'PageBreak', 'Chart');
|
||||
$functions = array();
|
||||
for ($i = 0; $i < count($elements); $i++) {
|
||||
$functions[$i] = 'add' . $elements[$i];
|
||||
|
|
@ -201,6 +202,7 @@ abstract class AbstractContainer extends AbstractElement
|
|||
'Title' => array('Section'),
|
||||
'TOC' => array('Section'),
|
||||
'PageBreak' => array('Section'),
|
||||
'Chart' => array('Section'),
|
||||
);
|
||||
// Special condition, e.g. preservetext can only exists in cell when
|
||||
// the cell is located in header or footer
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ abstract class AbstractElement
|
|||
protected $mediaRelation = false;
|
||||
|
||||
/**
|
||||
* Is part of collection; true for Title, Footnote, and Endnote
|
||||
* Is part of collection; true for Title, Footnote, Endnote, and Chart
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
<?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\Element;
|
||||
|
||||
/**
|
||||
* Chart element
|
||||
*
|
||||
* @since 0.12.0
|
||||
*/
|
||||
class Chart extends AbstractElement
|
||||
{
|
||||
/**
|
||||
* Is part of collection
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $collectionRelation = true;
|
||||
|
||||
/**
|
||||
* Type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $type = 'pie';
|
||||
|
||||
/**
|
||||
* Series
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $series = array();
|
||||
|
||||
/**
|
||||
* Create new instance
|
||||
*
|
||||
* @param string $type
|
||||
* @param array $categories
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct($type, $categories, $values)
|
||||
{
|
||||
$this->setType($type);
|
||||
$this->addSeries($categories, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set type
|
||||
*
|
||||
* @param string $value
|
||||
*/
|
||||
public function setType($value)
|
||||
{
|
||||
$enum = array('pie', 'doughnut', 'line', 'bar', 'area', 'radar', 'scatter');
|
||||
$this->type = $this->setEnumVal($value, $enum, 'pie');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add series
|
||||
*
|
||||
* @param array $categories
|
||||
* @param array $values
|
||||
*/
|
||||
public function addSeries($categories, $values)
|
||||
{
|
||||
$this->series[] = array('categories' => $categories, 'values' => $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get series
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSeries()
|
||||
{
|
||||
return $this->series;
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ class Footnote extends AbstractContainer
|
|||
protected $paragraphStyle;
|
||||
|
||||
/**
|
||||
* Is part of collection; true for Title, Footnote, and Endnote
|
||||
* Is part of collection
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class Title extends AbstractElement
|
|||
private $style;
|
||||
|
||||
/**
|
||||
* Is part of collection; true for Title, Footnote, and Endnote
|
||||
* Is part of collection
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,9 +26,11 @@ use PhpOffice\PhpWord\Exception\Exception;
|
|||
* @method Collection\Titles getTitles()
|
||||
* @method Collection\Footnotes getFootnotes()
|
||||
* @method Collection\Endnotes getEndnotes()
|
||||
* @method Collection\Charts getCharts()
|
||||
* @method int addTitle(Element\Title $title)
|
||||
* @method int addFootnote(Element\Footnote $footnote)
|
||||
* @method int addEndnote(Element\Endnote $endnote)
|
||||
* @method int addChart(Element\Chart $chart)
|
||||
*
|
||||
* @method Style\Paragraph addParagraphStyle(string $styleName, array $styles)
|
||||
* @method Style\Font addFontStyle(string $styleName, mixed $fontStyle, mixed $paragraphStyle = null)
|
||||
|
|
@ -80,7 +82,7 @@ class PhpWord
|
|||
{
|
||||
$this->documentProperties = new DocumentProperties();
|
||||
|
||||
$collections = array('Titles', 'Footnotes', 'Endnotes');
|
||||
$collections = array('Titles', 'Footnotes', 'Endnotes', 'Charts');
|
||||
foreach ($collections as $collection) {
|
||||
$class = 'PhpOffice\\PhpWord\\Collection\\' . $collection;
|
||||
$this->collections[$collection] = new $class();
|
||||
|
|
@ -108,7 +110,7 @@ class PhpWord
|
|||
$addCollection = array();
|
||||
$addStyle = array();
|
||||
|
||||
$collections = array('Title', 'Footnote', 'Endnote');
|
||||
$collections = array('Title', 'Footnote', 'Endnote', 'Chart');
|
||||
foreach ($collections as $collection) {
|
||||
$getCollection[] = strtolower("get{$collection}s");
|
||||
$addCollection[] = strtolower("add{$collection}");
|
||||
|
|
|
|||
|
|
@ -139,6 +139,29 @@ class XMLWriter
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write simple element and attribute(s) block
|
||||
*
|
||||
* There are two options:
|
||||
* 1. If the `$attributes` is an array, then it's an associative array of attributes
|
||||
* 2. If not, then it's a simple attribute-value pair
|
||||
*
|
||||
* @param string $element
|
||||
* @param string|array $attributes
|
||||
* @param string $value
|
||||
*/
|
||||
public function writeElementBlock($element, $attributes, $value = null)
|
||||
{
|
||||
$this->xmlWriter->startElement($element);
|
||||
if (!is_array($attributes)) {
|
||||
$attributes = array($attributes => $value);
|
||||
}
|
||||
foreach ($attributes as $attribute => $value) {
|
||||
$this->xmlWriter->writeAttribute($attribute, $value);
|
||||
}
|
||||
$this->xmlWriter->endElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write element if ...
|
||||
*
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ class Word2007 extends AbstractWriter implements WriterInterface
|
|||
'Footer' => '',
|
||||
'Footnotes' => '',
|
||||
'Endnotes' => '',
|
||||
'Chart' => '',
|
||||
);
|
||||
foreach (array_keys($this->parts) as $partName) {
|
||||
$partClass = get_class($this) . '\\Part\\' . $partName;
|
||||
|
|
@ -127,6 +128,7 @@ class Word2007 extends AbstractWriter implements WriterInterface
|
|||
|
||||
$this->addNotes($zip, $rId, 'footnote');
|
||||
$this->addNotes($zip, $rId, 'endnote');
|
||||
$this->addChart($zip, $rId);
|
||||
|
||||
// Write parts
|
||||
foreach ($this->parts as $partName => $fileName) {
|
||||
|
|
@ -249,6 +251,40 @@ class Word2007 extends AbstractWriter implements WriterInterface
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add chart
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Shared\ZipArchive $zip
|
||||
* @param integer $rId
|
||||
*/
|
||||
private function addChart(ZipArchive $zip, &$rId)
|
||||
{
|
||||
$phpWord = $this->getPhpWord();
|
||||
|
||||
$collection = $phpWord->getCharts();
|
||||
$index = 0;
|
||||
if ($collection->countItems() > 0) {
|
||||
foreach ($collection->getItems() as $chart) {
|
||||
$index++;
|
||||
$rId++;
|
||||
$filename = "charts/chart{$index}.xml";
|
||||
|
||||
// ContentTypes.xml
|
||||
$this->contentTypes['override']["/word/{$filename}"] = 'chart';
|
||||
|
||||
// word/_rels/document.xml.rel
|
||||
$this->relationships[] = array('target' => $filename, 'type' => 'chart', 'rID' => $rId);
|
||||
|
||||
// word/charts/chartN.xml
|
||||
/** @var \PhpOffice\PhpWord\Element\Chart $chart */
|
||||
$chart->setRelationId($rId);
|
||||
$writerPart = $this->getWriterPart('Chart');
|
||||
$writerPart->setElement($chart);
|
||||
$zip->addFromString("word/{$filename}", $writerPart->write());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register content types for each media
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
<?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\Writer\Word2007\Element;
|
||||
|
||||
use PhpOffice\PhpWord\Element\Chart as ChartElement;
|
||||
|
||||
/**
|
||||
* Chart element writer
|
||||
*
|
||||
* @since 0.12.0
|
||||
*/
|
||||
class Chart extends AbstractElement
|
||||
{
|
||||
/**
|
||||
* Write element
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$xmlWriter = $this->getXmlWriter();
|
||||
$element = $this->getElement();
|
||||
if (!$element instanceof ChartElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rId = $element->getRelationId();
|
||||
|
||||
if (!$this->withoutP) {
|
||||
$xmlWriter->startElement('w:p');
|
||||
}
|
||||
|
||||
$xmlWriter->startElement('w:r');
|
||||
$xmlWriter->startElement('w:drawing');
|
||||
$xmlWriter->startElement('wp:inline');
|
||||
|
||||
// EMU
|
||||
$xmlWriter->writeElementBlock('wp:extent', array('cx' => '2000000', 'cy' => '2000000'));
|
||||
$xmlWriter->writeElementBlock('wp:docPr', array('id' => $rId, 'name' => "Chart{$rId}"));
|
||||
|
||||
$xmlWriter->startElement('a:graphic');
|
||||
$xmlWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
|
||||
$xmlWriter->startElement('a:graphicData');
|
||||
$xmlWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
|
||||
|
||||
$xmlWriter->startElement('c:chart');
|
||||
$xmlWriter->writeAttribute('r:id', "rId{$rId}");
|
||||
$xmlWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
|
||||
$xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
|
||||
$xmlWriter->endElement(); // c:chart
|
||||
|
||||
$xmlWriter->endElement(); // a:graphicData
|
||||
$xmlWriter->endElement(); // a:graphic
|
||||
|
||||
$xmlWriter->endElement(); // wp:inline
|
||||
$xmlWriter->endElement(); // w:drawing
|
||||
$xmlWriter->endElement(); // w:r
|
||||
|
||||
$this->endElementP(); // w:p
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
<?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\Writer\Word2007\Part;
|
||||
|
||||
use PhpOffice\PhpWord\Shared\XMLWriter;
|
||||
use PhpOffice\PhpWord\Element\Chart as ChartElement;
|
||||
|
||||
/**
|
||||
* Word2007 chart part writer: word/charts/chartx.xml
|
||||
*
|
||||
* @since 0.12.0
|
||||
* @link http://www.datypic.com/sc/ooxml/e-draw-chart_chartSpace.html
|
||||
*/
|
||||
class Chart extends AbstractPart
|
||||
{
|
||||
/**
|
||||
* Chart element
|
||||
*
|
||||
* @var \PhpOffice\PhpWord\Element\Chart $element
|
||||
*/
|
||||
private $element;
|
||||
|
||||
/**
|
||||
* Type definition
|
||||
*
|
||||
* @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'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Chart options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $options = array();
|
||||
|
||||
/**
|
||||
* Set chart element
|
||||
*/
|
||||
public function setElement(ChartElement $element)
|
||||
{
|
||||
$this->element = $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write part
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$xmlWriter = $this->getXmlWriter();
|
||||
|
||||
$xmlWriter->startDocument('1.0', 'UTF-8', 'yes');
|
||||
$xmlWriter->startElement('c:chartSpace');
|
||||
$xmlWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
|
||||
$xmlWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
|
||||
$xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
|
||||
|
||||
$this->writeChart($xmlWriter);
|
||||
$this->writeShape($xmlWriter);
|
||||
|
||||
$xmlWriter->endElement(); // c:chartSpace
|
||||
|
||||
return $xmlWriter->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write chart
|
||||
*
|
||||
* @link http://www.datypic.com/sc/ooxml/t-draw-chart_CT_Chart.html
|
||||
*/
|
||||
private function writeChart(XMLWriter $xmlWriter)
|
||||
{
|
||||
$xmlWriter->startElement('c:chart');
|
||||
|
||||
$xmlWriter->writeElementBlock('c:autoTitleDeleted', 'val', 1);
|
||||
|
||||
$this->writePlotArea($xmlWriter);
|
||||
|
||||
$xmlWriter->endElement(); // c:chart
|
||||
}
|
||||
|
||||
/**
|
||||
* Write plot area
|
||||
*
|
||||
* @link http://www.datypic.com/sc/ooxml/t-draw-chart_CT_PlotArea.html
|
||||
* @link http://www.datypic.com/sc/ooxml/t-draw-chart_CT_PieChart.html
|
||||
* @link http://www.datypic.com/sc/ooxml/t-draw-chart_CT_DoughnutChart.html
|
||||
* @link http://www.datypic.com/sc/ooxml/t-draw-chart_CT_BarChart.html
|
||||
* @link http://www.datypic.com/sc/ooxml/t-draw-chart_CT_LineChart.html
|
||||
* @link http://www.datypic.com/sc/ooxml/t-draw-chart_CT_AreaChart.html
|
||||
* @link http://www.datypic.com/sc/ooxml/t-draw-chart_CT_RadarChart.html
|
||||
* @link http://www.datypic.com/sc/ooxml/t-draw-chart_CT_ScatterChart.html
|
||||
*/
|
||||
private function writePlotArea(XMLWriter $xmlWriter)
|
||||
{
|
||||
$type = $this->element->getType();
|
||||
$this->options = $this->types[$type];
|
||||
|
||||
$xmlWriter->startElement('c:plotArea');
|
||||
$xmlWriter->writeElement('c:layout');
|
||||
|
||||
// Chart
|
||||
$xmlWriter->startElement('c:' . $this->options['type']);
|
||||
|
||||
$xmlWriter->writeElementBlock('c:varyColors', 'val', $this->options['colors']);
|
||||
if ($type == 'area') {
|
||||
$xmlWriter->writeElementBlock('c:grouping', 'val', 'standard');
|
||||
}
|
||||
if (isset($this->options['hole'])) {
|
||||
$xmlWriter->writeElementBlock('c:holeSize', 'val', $this->options['hole']);
|
||||
}
|
||||
if (isset($this->options['bar'])) {
|
||||
$xmlWriter->writeElementBlock('c:barDir', 'val', $this->options['bar']); // bar|col
|
||||
$xmlWriter->writeElementBlock('c:grouping', 'val', 'clustered');
|
||||
}
|
||||
if (isset($this->options['radar'])) {
|
||||
$xmlWriter->writeElementBlock('c:radarStyle', 'val', $this->options['radar']);
|
||||
}
|
||||
if (isset($this->options['scatter'])) {
|
||||
$xmlWriter->writeElementBlock('c:scatterStyle', 'val', $this->options['scatter']);
|
||||
}
|
||||
|
||||
// Series
|
||||
$this->writeSeries($xmlWriter, isset($this->options['scatter']));
|
||||
|
||||
// Axes
|
||||
if (isset($this->options['axes'])) {
|
||||
$xmlWriter->writeElementBlock('c:axId', 'val', 1);
|
||||
$xmlWriter->writeElementBlock('c:axId', 'val', 2);
|
||||
}
|
||||
|
||||
$xmlWriter->endElement(); // chart type
|
||||
|
||||
// Axes
|
||||
if (isset($this->options['axes'])) {
|
||||
$this->writeAxis($xmlWriter, 'cat');
|
||||
$this->writeAxis($xmlWriter, 'val');
|
||||
}
|
||||
|
||||
$xmlWriter->endElement(); // c:plotArea
|
||||
}
|
||||
|
||||
/**
|
||||
* Write series
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
|
||||
* @param bool $scatter
|
||||
*/
|
||||
private function writeSeries(XMLWriter $xmlWriter, $scatter = false)
|
||||
{
|
||||
$series = $this->element->getSeries();
|
||||
|
||||
$index = 0;
|
||||
foreach ($series as $seriesItem) {
|
||||
$categories = $seriesItem['categories'];
|
||||
$values = $seriesItem['values'];
|
||||
|
||||
$xmlWriter->startElement('c:ser');
|
||||
|
||||
$xmlWriter->writeElementBlock('c:idx', 'val', $index);
|
||||
$xmlWriter->writeElementBlock('c:order', 'val', $index);
|
||||
|
||||
if (isset($this->options['scatter'])) {
|
||||
$this->writeShape($xmlWriter);
|
||||
}
|
||||
|
||||
if ($scatter === true) {
|
||||
$this->writeSeriesItem($xmlWriter, 'xVal', $categories);
|
||||
$this->writeSeriesItem($xmlWriter, 'yVal', $values);
|
||||
} else {
|
||||
$this->writeSeriesItem($xmlWriter, 'cat', $categories);
|
||||
$this->writeSeriesItem($xmlWriter, 'val', $values);
|
||||
}
|
||||
|
||||
$xmlWriter->endElement(); // c:ser
|
||||
$index++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Write series items
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
|
||||
* @param string $type
|
||||
* @param array $values
|
||||
*/
|
||||
private function writeSeriesItem(XMLWriter $xmlWriter, $type, $values)
|
||||
{
|
||||
$types = array(
|
||||
'cat' => array('c:cat', 'c:strLit'),
|
||||
'val' => array('c:val', 'c:numLit'),
|
||||
'xVal' => array('c:xVal', 'c:strLit'),
|
||||
'yVal' => array('c:yVal', 'c:numLit'),
|
||||
);
|
||||
list($itemType, $itemLit) = $types[$type];
|
||||
|
||||
$xmlWriter->startElement($itemType);
|
||||
$xmlWriter->startElement($itemLit);
|
||||
|
||||
$index = 0;
|
||||
foreach ($values as $value) {
|
||||
$xmlWriter->startElement('c:pt');
|
||||
$xmlWriter->writeAttribute('idx', $index);
|
||||
|
||||
$xmlWriter->startElement('c:v');
|
||||
$xmlWriter->writeRaw($value);
|
||||
$xmlWriter->endElement(); // c:v
|
||||
|
||||
$xmlWriter->endElement(); // c:pt
|
||||
$index++;
|
||||
}
|
||||
|
||||
$xmlWriter->endElement(); // $itemLit
|
||||
$xmlWriter->endElement(); // $itemType
|
||||
}
|
||||
|
||||
/**
|
||||
* Write axis
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
|
||||
* @param string $type
|
||||
* @link http://www.datypic.com/sc/ooxml/t-draw-chart_CT_CatAx.html
|
||||
*/
|
||||
private function writeAxis(XMLWriter $xmlWriter, $type)
|
||||
{
|
||||
$types = array(
|
||||
'cat' => array('c:catAx', 1, 'b', 2),
|
||||
'val' => array('c:valAx', 2, 'l', 1),
|
||||
);
|
||||
list($axisType, $axisId, $axisPos, $axisCross) = $types[$type];
|
||||
|
||||
$xmlWriter->startElement($axisType);
|
||||
|
||||
$xmlWriter->writeElementBlock('c:axId', 'val', $axisId);
|
||||
$xmlWriter->writeElementBlock('c:axPos', 'val', $axisPos);
|
||||
$xmlWriter->writeElementBlock('c:crossAx', 'val', $axisCross);
|
||||
$xmlWriter->writeElementBlock('c:auto', 'val', 1);
|
||||
|
||||
if (isset($this->options['axes'])) {
|
||||
$xmlWriter->writeElementBlock('c:delete', 'val', 0);
|
||||
$xmlWriter->writeElementBlock('c:majorTickMark', 'val', 'none');
|
||||
$xmlWriter->writeElementBlock('c:minorTickMark', 'val', 'none');
|
||||
$xmlWriter->writeElementBlock('c:tickLblPos', 'val', 'none'); // nextTo
|
||||
$xmlWriter->writeElementBlock('c:crosses', 'val', 'autoZero');
|
||||
}
|
||||
if (isset($this->options['radar'])) {
|
||||
$xmlWriter->writeElement('c:majorGridlines');
|
||||
}
|
||||
|
||||
$xmlWriter->startElement('c:scaling');
|
||||
$xmlWriter->writeElementBlock('c:orientation', 'val', 'minMax');
|
||||
$xmlWriter->endElement(); // c:scaling
|
||||
|
||||
$this->writeShape($xmlWriter, true);
|
||||
|
||||
$xmlWriter->endElement(); // $axisType
|
||||
}
|
||||
|
||||
/**
|
||||
* Write shape
|
||||
*
|
||||
* @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
|
||||
* @param bool $line
|
||||
* @link http://www.datypic.com/sc/ooxml/t-a_CT_ShapeProperties.html
|
||||
*/
|
||||
private function writeShape(XMLWriter $xmlWriter, $line = false)
|
||||
{
|
||||
$xmlWriter->startElement('c:spPr');
|
||||
$xmlWriter->startElement('a:ln');
|
||||
if ($line === true) {
|
||||
$xmlWriter->writeElement('a:solidFill');
|
||||
} else {
|
||||
$xmlWriter->writeElement('a:noFill');
|
||||
}
|
||||
$xmlWriter->endElement(); // a:ln
|
||||
$xmlWriter->endElement(); // c:spPr
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ class ContentTypes extends AbstractPart
|
|||
|
||||
$openXMLPrefix = 'application/vnd.openxmlformats-';
|
||||
$wordMLPrefix = $openXMLPrefix . 'officedocument.wordprocessingml.';
|
||||
$drawingMLPrefix = $openXMLPrefix . 'officedocument.drawingml.';
|
||||
$overrides = array(
|
||||
'/docProps/core.xml' => $openXMLPrefix . 'package.core-properties+xml',
|
||||
'/docProps/app.xml' => $openXMLPrefix . 'officedocument.extended-properties+xml',
|
||||
|
|
@ -53,7 +54,11 @@ class ContentTypes extends AbstractPart
|
|||
$defaults = $contentTypes['default'];
|
||||
if (!empty($contentTypes['override'])) {
|
||||
foreach ($contentTypes['override'] as $key => $val) {
|
||||
$overrides[$key] = $wordMLPrefix . $val . '+xml';
|
||||
if ($val == 'chart') {
|
||||
$overrides[$key] = $drawingMLPrefix . $val . '+xml';
|
||||
} else {
|
||||
$overrides[$key] = $wordMLPrefix . $val . '+xml';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class RTFTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
$this->assertTrue(file_exists($file));
|
||||
|
||||
unlink($file);
|
||||
@unlink($file);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class ElementTest extends \PHPUnit_Framework_TestCase
|
|||
$elements = array(
|
||||
'CheckBox', 'Container', 'Footnote', 'Image', 'Link', 'ListItem', 'ListItemRun',
|
||||
'Object', 'PreserveText', 'Table', 'Text', 'TextBox', 'TextBreak', 'Title', 'TOC',
|
||||
'Field', 'Line', 'Shape'
|
||||
'Field', 'Line', 'Shape', 'Chart'
|
||||
);
|
||||
foreach ($elements as $element) {
|
||||
$objectClass = 'PhpOffice\\PhpWord\\Writer\\Word2007\\Element\\' . $element;
|
||||
|
|
@ -148,4 +148,30 @@ class ElementTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertTrue($doc->elementExists($path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test shape elements
|
||||
*/
|
||||
public function testChartElement()
|
||||
{
|
||||
$phpWord = new PhpWord();
|
||||
$section = $phpWord->addSection();
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
$doc = TestHelperDOCX::getDocument($phpWord);
|
||||
|
||||
$index = 0;
|
||||
foreach ($chartTypes as $chartType) {
|
||||
$index++;
|
||||
$file = "word/charts/chart{$index}.xml";
|
||||
$path = "/c:chartSpace/c:chart/c:plotArea/c:{$chartType}Chart";
|
||||
$this->assertTrue($doc->elementExists($path, $file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue