-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Charts - Missing ability to modify Chart Settings #957
Comments
It seems a user needs to be able to pass the graph options (data labels options, axis options, etc...) to the PhpOffice\PhpWord\Element\Chart class. In the PhpOffice\PhpWord\Writer\Word2007\Part\Chart class's writeSeries method after it writes all the series data it needs to take the private class variable $element which is a PhpOffice\PhpWord\Element\Chart and use the data labels options to output c:dLbls values. In the writeAxis method where it checks if the option axes is set it should use the $element axis options instead of using the hard coded values below 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');
} It also appears having the developer send over the raw XML data for the options might be easiest, as creating a data structure for the xml can be a pain with multiple attributes and nested xml. something like: $chart = $section->addChart('line', $categories, array());
$chartOptions = array();
$chartOptions['c:dLbls']='<c:dLblPos val="t"/>
<c:showLegendKey val="0"/>
<c:showVal val="1"/>
<c:showCatName val="0"/>
<c:showSerName val="0"/>
<c:showPercent val="0"/>
<c:showBubbleSize val="0"/>';
$chartOptions['c:catAx']=' <c:scaling>
<c:orientation val="minMax"/>
</c:scaling>
<c:delete val="0"/>
<c:numFmt formatCode="General" sourceLinked="1"/>
<c:majorTickMark val="none"/>
<c:minorTickMark val="none"/>
<c:tickLblPos val="nextTo"/>
<c:crosses val="autoZero"/>
<c:lblAlgn val="ctr"/>
<c:lblOffset val="100"/>
<c:noMultiLvlLbl val="0"/>';
$chartOptions['c:valAx']=' <c:scaling>
<c:orientation val="minMax"/>
</c:scaling>
<c:delete val="0"/>
<c:majorGridlines/>
<c:numFmt formatCode="General" sourceLinked="1"/>
<c:majorTickMark val="none"/>
<c:minorTickMark val="none"/>
<c:tickLblPos val="nextTo"/>
<c:spPr>
<a:ln w="9525">
<a:noFill/>
</a:ln>
</c:spPr>
<c:crosses val="autoZero"/>
<c:crossBetween val="between"/>';
$chart->setOptions($chartOptions); and in PhpOffice\PhpWord\Writer\Word2007\Part\Chart.php Get the Axis Options outputted 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);
//::NOTE:: NEW CODE
//Axis options @link http://www.datypic.com/sc/ooxml/e-draw-chart_catAx-1.html
$chartOptions = $this->element->getOptions();
if($axisType=='c:catAx' && isset($chartOptions['c:catAx']))
{
//write raw xml options and return back
$xmlWriter->writeRaw($chartOptions['c:catAx']);
$xmlWriter->endElement(); // $axisType
return;
}
else if($axisType=='c:valAx' && isset($chartOptions['c:valAx']))
{
//write raw xml options and return back
$xmlWriter->writeRaw($chartOptions['c:valAx']);
$xmlWriter->endElement(); // $axisType
return;
}
else 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
} Get the Data Labels options outputted 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++;
}
//::NOTE:: NEW CODE
//Series Data Labels @link http://www.datypic.com/sc/ooxml/e-draw-chart_dLbls-1.html
$chartOptions = $this->element->getOptions();
if(isset($chartOptions['c:dLbls']))
{
$xmlWriter->startElement('c:dLbls');
$xmlWriter->writeRaw($chartOptions['c:dLbls']);
$xmlWriter->endElement(); // </c:dLbls>
}
} get the legend to display private function writeChart(XMLWriter $xmlWriter)
{
$xmlWriter->startElement('c:chart');
$xmlWriter->writeElementBlock('c:autoTitleDeleted', 'val', 1);
$this->writePlotArea($xmlWriter);
//::NOTE:: New Code
$xmlWriter->writeRaw('<c:legend>
<c:legendPos val="b"/>
<c:overlay val="0"/>
</c:legend>');
$xmlWriter->endElement(); // c:chart
} To give the SeriesItem a name so that in the legend each line has a name you have to add private function writeSeriesItem(XMLWriter $xmlWriter, $type, $values,$name)
{
$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];
$seriesName = '
<c:tx>
<c:strRef>
<c:strCache>
<c:ptCount val="1"/>
<c:pt idx="0">
<c:v>'.$name.'</c:v>
</c:pt>
</c:strCache>
</c:strRef>
</c:tx>';
$chartOptions = $this->element->getOptions();
if(isset($seriesName) && $type ==='cat')
{
$xmlWriter->writeRaw($seriesName);
} |
How can I implement these Data Label properties |
@scalco19 not sure, that's a bar graph and not a line graph in the issue I was working on. I'd recommend looking into reverse engineering the xml and just writing the rawxml of the entire graph from a template. |
@phpdave did you manage to add legends and chart data |
@marwankhanfar If you follow his instructions stated in this thread, everything works like a charm for me. I think, if you have the time, you could build some setters for the data labels and legend if you want to, so that you don't have to work with the raw xml. @phpdave Do you have an idea how to position multiple chart elements in a row side-by-side. As far as I have tested, I only get them like a block element beneath each other. |
@diggamies I would make that change in word, save it as xml and view the difference it made to the xml. That seems like the quickest way to figure out how to do it. @marwabjhanfar yes if you follow what I wrote it will work. |
@phpdave Yeah, been there, done that. As I have found out, there is always a new paragraph around a chart element. Wenn you put them in word side-by-side you have both of them inside one paragraph. I found a variable $withoutP in the AbstractElement but it is not working on the Chart Element, when you change it to true. |
@phpdave @diggamies can you please send me the package with the changes, I tried to implement yours with no luck at my email : [email protected] |
Hello @phpdave thank you for your post |
@phpdave thank you so much for the Legend. It now shows up in the pie-chart. I now want to display the DATA LABELS in pie chart. Would the hard coding suggested by you work with pie-chart? |
My code is not recognizing the setOptions function...any idea? |
@ARC113 Sorry, for not answering in such a long time, but I think with a new version of PHPWord the setOptions function has been removed. There are some options available now in the style object of the Chart class, @phpdave Did you update to the current version and can tell us a workaround to get the legend back? |
I’d recommend looking over the recent changes 65b0f06#diff-f95e31bde7c0c2535019d08b30203161 |
@jaek-s did some work to charts that may fix the issues I was running into |
Looks like he added Data labels :-) |
@phpdave Yeah, I was just checking these changes and since the setOptions method is not available anymore and only dataLabels are supported, I lost the otion to add the legend. Maybe i have to fork and set up a pull request in some time in the future to add legends to charts. Since I am using mostly pieCharts the dataLabels are not a big help in my case. |
Ah I understand your issue now. Looks like fork and PR is the best approach. At least you have the documentation above to help. Good luck @diggamies! |
Missing ability to modify Chart Settings
Data Labels above line graph points
Location of where these values are set:
Other Missing XML data that I'd like to help get working
Note I removed xml data that already is being set and just showing tags that appear to not be set
3. Set Axis Number Format (http://www.datypic.com/sc/ooxml/e-draw-chart_numFmt-1.html)
4. Set Axis Tick Label Position (http://www.datypic.com/sc/ooxml/e-draw-chart_tickLblPos-1.html)
5. Set Axis Shape Properties Shape Properties (http://www.datypic.com/sc/ooxml/e-draw-chart_spPr-1.html)
6. Set Axis No Multi-level Labels (http://www.datypic.com/sc/ooxml/e-draw-chart_noMultiLvlLbl-1.html)
7. Set Axis Major Gridlines (http://www.datypic.com/sc/ooxml/e-draw-chart_majorGridlines-1.html)
8. Set Legend Position (http://www.datypic.com/sc/ooxml/t-draw-chart_CT_LegendPos.html)
9. Set Legend Overlay http://www.datypic.com/sc/ooxml/e-draw-chart_overlay-1.html
10. Set Display Blanks As http://www.datypic.com/sc/ooxml/e-draw-chart_dispBlanksAs-1.html
11. Show Data Labels over Maximum http://www.datypic.com/sc/ooxml/e-draw-chart_showDLblsOverMax-1.html
12. Set External Data Relationship http://www.datypic.com/sc/ooxml/e-draw-chart_externalData-1.html
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: