33namespace PhpOffice \PhpSpreadsheet \Reader \Xlsx ;
44
55use PhpOffice \PhpSpreadsheet \Calculation \Information \ExcelError ;
6+ use PhpOffice \PhpSpreadsheet \Chart \Axis ;
67use PhpOffice \PhpSpreadsheet \Chart \DataSeries ;
78use PhpOffice \PhpSpreadsheet \Chart \DataSeriesValues ;
89use PhpOffice \PhpSpreadsheet \Chart \Layout ;
910use PhpOffice \PhpSpreadsheet \Chart \Legend ;
1011use PhpOffice \PhpSpreadsheet \Chart \PlotArea ;
12+ use PhpOffice \PhpSpreadsheet \Chart \Properties ;
1113use PhpOffice \PhpSpreadsheet \Chart \Title ;
1214use PhpOffice \PhpSpreadsheet \RichText \RichText ;
1315use PhpOffice \PhpSpreadsheet \Style \Color ;
@@ -67,6 +69,8 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
6769 $ dispBlanksAs = $ plotVisOnly = null ;
6870 $ plotArea = null ;
6971 $ rotX = $ rotY = $ rAngAx = $ perspective = null ;
72+ $ xAxis = new Axis ();
73+ $ yAxis = new Axis ();
7074 foreach ($ chartElementsC as $ chartElementKey => $ chartElement ) {
7175 switch ($ chartElementKey ) {
7276 case 'chart ' :
@@ -93,6 +97,7 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
9397 if (isset ($ chartDetail ->title )) {
9498 $ XaxisLabel = $ this ->chartTitle ($ chartDetail ->title ->children ($ this ->cNamespace ));
9599 }
100+ $ this ->readEffects ($ chartDetail , $ xAxis );
96101
97102 break ;
98103 case 'dateAx ' :
@@ -102,6 +107,7 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
102107
103108 break ;
104109 case 'valAx ' :
110+ $ whichAxis = null ;
105111 if (isset ($ chartDetail ->title , $ chartDetail ->axPos )) {
106112 $ axisLabel = $ this ->chartTitle ($ chartDetail ->title ->children ($ this ->cNamespace ));
107113 $ axPos = self ::getAttribute ($ chartDetail ->axPos , 'val ' , 'string ' );
@@ -110,15 +116,18 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
110116 case 't ' :
111117 case 'b ' :
112118 $ XaxisLabel = $ axisLabel ;
119+ $ whichAxis = $ xAxis ;
113120
114121 break ;
115122 case 'r ' :
116123 case 'l ' :
117124 $ YaxisLabel = $ axisLabel ;
125+ $ whichAxis = $ yAxis ;
118126
119127 break ;
120128 }
121129 }
130+ $ this ->readEffects ($ chartDetail , $ whichAxis );
122131
123132 break ;
124133 case 'barChart ' :
@@ -240,7 +249,7 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
240249 }
241250 }
242251 }
243- $ chart = new \PhpOffice \PhpSpreadsheet \Chart \Chart ($ chartName , $ title , $ legend , $ plotArea , $ plotVisOnly , (string ) $ dispBlanksAs , $ XaxisLabel , $ YaxisLabel );
252+ $ chart = new \PhpOffice \PhpSpreadsheet \Chart \Chart ($ chartName , $ title , $ legend , $ plotArea , $ plotVisOnly , (string ) $ dispBlanksAs , $ XaxisLabel , $ YaxisLabel, $ xAxis , $ yAxis );
244253 if (is_int ($ rotX )) {
245254 $ chart ->setRotX ($ rotX );
246255 }
@@ -345,9 +354,8 @@ private function chartDataSeries(SimpleXMLElement $chartDetail, string $plotType
345354 if (is_countable ($ ln ->noFill ) && count ($ ln ->noFill ) === 1 ) {
346355 $ noFill = true ;
347356 }
348- $ sf = $ children ->solidFill ->schemeClr ;
349- if ($ sf ) {
350- $ schemeClr = self ::getAttribute ($ sf , 'val ' , 'string ' );
357+ if (isset ($ children ->solidFill )) {
358+ $ this ->readColor ($ children ->solidFill , $ srgbClr , $ schemeClr );
351359 }
352360
353361 break ;
@@ -357,8 +365,8 @@ private function chartDataSeries(SimpleXMLElement $chartDetail, string $plotType
357365 $ pointSize = is_numeric ($ pointSize ) ? ((int ) $ pointSize ) : null ;
358366 if (count ($ seriesDetail ->spPr ) === 1 ) {
359367 $ ln = $ seriesDetail ->spPr ->children ($ this ->aNamespace );
360- if (count ($ ln ->solidFill ) === 1 ) {
361- $ srgbClr = self :: getAttribute ($ ln ->solidFill -> srgbClr , ' val ' , ' string ' );
368+ if (isset ($ ln ->solidFill )) {
369+ $ this -> readColor ($ ln ->solidFill , $ srgbClr , $ schemeClr );
362370 }
363371 }
364372
@@ -603,7 +611,8 @@ private function parseRichText(SimpleXMLElement $titleDetailPart): RichText
603611 $ defaultLatin = null ;
604612 $ defaultEastAsian = null ;
605613 $ defaultComplexScript = null ;
606- $ defaultColor = null ;
614+ $ defaultSrgbColor = '' ;
615+ $ defaultSchemeColor = '' ;
607616 if (isset ($ titleDetailPart ->pPr ->defRPr )) {
608617 /** @var ?int */
609618 $ defaultFontSize = self ::getAttribute ($ titleDetailPart ->pPr ->defRPr , 'sz ' , 'integer ' );
@@ -632,9 +641,8 @@ private function parseRichText(SimpleXMLElement $titleDetailPart): RichText
632641 /** @var ?string */
633642 $ defaultComplexScript = self ::getAttribute ($ titleDetailPart ->pPr ->defRPr ->cs , 'typeface ' , 'string ' );
634643 }
635- if (isset ($ titleDetailPart ->pPr ->defRPr ->solidFill ->srgbClr )) {
636- /** @var ?string */
637- $ defaultColor = self ::getAttribute ($ titleDetailPart ->pPr ->defRPr ->solidFill ->srgbClr , 'val ' , 'string ' );
644+ if (isset ($ titleDetailPart ->pPr ->defRPr ->solidFill )) {
645+ $ this ->readColor ($ titleDetailPart ->pPr ->defRPr ->solidFill , $ defaultSrgbColor , $ defaultSchemeClr );
638646 }
639647 }
640648 foreach ($ titleDetailPart as $ titleDetailElementKey => $ titleDetailElement ) {
@@ -660,7 +668,8 @@ private function parseRichText(SimpleXMLElement $titleDetailPart): RichText
660668 $ latinName = null ;
661669 $ eastAsian = null ;
662670 $ complexScript = null ;
663- $ fontColor = null ;
671+ $ fontSrgbClr = '' ;
672+ $ fontSchemeClr = '' ;
664673 $ uSchemeClr = null ;
665674 if (isset ($ titleDetailElement ->rPr )) {
666675 // not used now, not sure it ever was, grandfathering
@@ -686,10 +695,9 @@ private function parseRichText(SimpleXMLElement $titleDetailPart): RichText
686695
687696 // not used now, not sure it ever was, grandfathering
688697 /** @var ?string */
689- $ fontColor = self ::getAttribute ($ titleDetailElement ->rPr , 'color ' , 'string ' );
690- if (isset ($ titleDetailElement ->rPr ->solidFill ->srgbClr )) {
691- /** @var ?string */
692- $ fontColor = self ::getAttribute ($ titleDetailElement ->rPr ->solidFill ->srgbClr , 'val ' , 'string ' );
698+ $ fontSrgbClr = self ::getAttribute ($ titleDetailElement ->rPr , 'color ' , 'string ' );
699+ if (isset ($ titleDetailElement ->rPr ->solidFill )) {
700+ $ this ->readColor ($ titleDetailElement ->rPr ->solidFill , $ fontSrgbClr , $ fontSchemeClr );
693701 }
694702
695703 /** @var ?bool */
@@ -742,11 +750,17 @@ private function parseRichText(SimpleXMLElement $titleDetailPart): RichText
742750 $ fontFound = true ;
743751 }
744752
745- $ fontColor = $ fontColor ?? $ defaultColor ;
746- if ($ fontColor !== null ) {
747- $ objText ->getFont ()->setColor (new Color ($ fontColor ));
753+ $ fontSrgbClr = $ fontSrgbClr ?? $ defaultSrgbColor ;
754+ if (! empty ( $ fontSrgbClr ) ) {
755+ $ objText ->getFont ()->setColor (new Color ($ fontSrgbClr ));
748756 $ fontFound = true ;
749757 }
758+ // need to think about what to do here
759+ //$fontSchemeClr = $fontSchemeClr ?? $defaultSchemeColor;
760+ //if (!empty($fontSchemeClr)) {
761+ // $objText->getFont()->setColor(new Color($fontSrgbClr));
762+ // $fontFound = true;
763+ //}
750764
751765 $ bold = $ bold ?? $ defaultBold ;
752766 if ($ bold !== null ) {
@@ -877,4 +891,56 @@ private function setChartAttributes(Layout $plotArea, $plotAttributes): void
877891 }
878892 }
879893 }
894+
895+ /**
896+ * @param null|Axis $chartObject may be extended to include other types
897+ */
898+ private function readEffects (SimpleXMLElement $ chartDetail , $ chartObject ): void
899+ {
900+ if (!isset ($ chartObject , $ chartDetail ->spPr )) {
901+ return ;
902+ }
903+ $ sppr = $ chartDetail ->spPr ->children ($ this ->aNamespace );
904+
905+ if (isset ($ sppr ->effectLst ->glow )) {
906+ $ axisGlowSize = (float ) self ::getAttribute ($ sppr ->effectLst ->glow , 'rad ' , 'integer ' ) / Properties::POINTS_WIDTH_MULTIPLIER ;
907+ if ($ axisGlowSize != 0.0 ) {
908+ $ srgbClr = $ schemeClr = '' ;
909+ $ colorArray = $ this ->readColor ($ sppr ->effectLst ->glow , $ srgbClr , $ schemeClr );
910+ $ chartObject ->setGlowProperties ($ axisGlowSize , $ colorArray ['value ' ], $ colorArray ['alpha ' ], $ colorArray ['type ' ]);
911+ }
912+ }
913+
914+ if (isset ($ sppr ->effectLst ->softEdge )) {
915+ $ chartObject ->setSoftEdges ((float ) self ::getAttribute ($ sppr ->effectLst ->softEdge , 'rad ' , 'string ' ) / Properties::POINTS_WIDTH_MULTIPLIER );
916+ }
917+ }
918+
919+ private function readColor (SimpleXMLElement $ colorXml , ?string &$ srgbClr , ?string &$ schemeClr ): array
920+ {
921+ $ result = [
922+ 'type ' => null ,
923+ 'value ' => null ,
924+ 'alpha ' => null ,
925+ ];
926+ if (isset ($ colorXml ->srgbClr )) {
927+ $ result ['type ' ] = Properties::EXCEL_COLOR_TYPE_ARGB ;
928+ $ result ['value ' ] = $ srgbClr = self ::getAttribute ($ colorXml ->srgbClr , 'val ' , 'string ' );
929+ if (isset ($ colorXml ->srgbClr ->alpha )) {
930+ $ alpha = (int ) self ::getAttribute ($ colorXml ->srgbClr ->alpha , 'val ' , 'string ' );
931+ $ alpha = 100 - (int ) ($ alpha / 1000 );
932+ $ result ['alpha ' ] = $ alpha ;
933+ }
934+ } elseif (isset ($ colorXml ->schemeClr )) {
935+ $ result ['type ' ] = Properties::EXCEL_COLOR_TYPE_SCHEME ;
936+ $ result ['value ' ] = $ schemeClr = self ::getAttribute ($ colorXml ->schemeClr , 'val ' , 'string ' );
937+ if (isset ($ colorXml ->schemeClr ->alpha )) {
938+ $ alpha = (int ) self ::getAttribute ($ colorXml ->schemeClr ->alpha , 'val ' , 'string ' );
939+ $ alpha = 100 - (int ) ($ alpha / 1000 );
940+ $ result ['alpha ' ] = $ alpha ;
941+ }
942+ }
943+
944+ return $ result ;
945+ }
880946}
0 commit comments