This project has moved. For the latest updates, please go here.

Color on Pie3D

Feb 11, 2010 at 8:21 AM

Hello,

It's possible to change the color or the quart on  "eChartType.Pie3D"

I don't not found how make.

 

 

Coordinator
Feb 11, 2010 at 8:50 AM

Sorry no, not in this release. Try to use a template, and style the pie chart the way you wan't it. I'm not sure it will work as expected, but you can try it out.

Feb 11, 2010 at 9:39 AM

It's not possible because i don't know the number of sheet.

I am going to use actual colours and to try to find a resolution

Thanks for your help.

 

Oct 7, 2011 at 2:24 PM

Any update on a possibility to change the colors of quarts? If no then do You have an idea how toachieve this in a different way?

Coordinator
Oct 9, 2011 at 6:34 PM

No, no update. If you can't use a template you have work with the ChartXml directly.

I haven't done that, so I cant help you with it.

Oct 14, 2011 at 9:56 AM

1. Hm could You explain how to use a template?

2. As for charts XML, I would need to modify it using the official MS OpenXML SDK right? 

 

BTW: great library, thanks for sharing it!

Oct 19, 2011 at 11:07 AM

1. Ok I found that You can use templates for whole documents, not chart, but thanks anyway.

Feb 27, 2012 at 3:12 PM
Edited Mar 12, 2012 at 1:07 PM

Ok, I've been toying around with EPPlus and Pie3D chart's xml and found out that colors are controlled by Data Points:

<c:dPt>
	<c:idx val="1"/>
	<c:bubble3D val="0"/>
	<c:spPr>
		<a:solidFill>
			<a:srgbClr val="FFFF00"/>
		</a:solidFill>
	</c:spPr>
</c:dPt>

So I've created a method which can change the DataPoint (quart) colors. The method should:

  • add Color and Data Point xml to chart (if it wasn't added yet by our program, by default this is done when you open a .xlsx with Microsoft Office)
  • change existing Data Point color
  • if data point index is higher than  amount of columns used by our chart -> throw an Exception, for example we have 2 quarts and we try to change color of third
  • only Pie3D chart has been tested by me (and support for it is hardcoded), take a look at supportedChartTypes List. Maybe other pie charts can also be handled by my code, dunno that.

This is only a hack, the real solution for this should be 2 separate classes - DataPoint (which would have ExcelDrawingFill class) and DataPoints class for collection. Feel free to copy and redistribute my code anyway you like. How to use it:

Add this to class ExcelChartSerie

const string dataPointChildrenPath = "c:spPr/a:solidFill/a:srgbClr/@val";
        const string dataPointFullPath = "c:dPt/c:spPr/a:solidFill/a:srgbClr/@val";
        const string dataPointPath = "c:dPt";
        const string dataPointIdxPath = "c:dPt/c:idx/@val";
        const string dataPointBubble3DPath = "c:dPt/c:bubble3D/@val";

        /// 

        /// Change color of Pie3D chart pieces (DataPoints)
        /// 

        /// 
        /// 
        public void SetDataPointColor(int dataPointNr, Color newColor)
        {
            //the list might be longer as there are more pie type charts, haven't tested it on other than Pie3D
            List supportedChartTypes = new List() {eChartType.Pie3D};
            eChartType currentChartType = _chartSeries.Chart.ChartType;

            if (dataPointNr < 0)
            {
                throw new IndexOutOfRangeException("Data point index can't be less than 0.");
            }

            if (!supportedChartTypes.Contains(currentChartType)) 
            { 
                StringBuilder types = new StringBuilder();
                foreach(eChartType e in supportedChartTypes)
                {
                    types.Append(e.ToString());
                    types.Append(" ");
                }
                throw new Exception("Unsupported chart type. Please use one of these chart types: " + types.ToString());
                
            }

            //supported chart type
            switch (currentChartType)
            {
                case eChartType.Pie3D:
                    {
                        //check if index in less than amount of columns (cells?) for this series
                        //if chart has DataPoints in rows A1:A2 then serie.SetDataPointColor(2, Color.Red) throws an exception!
                        ExcelAddress address = new ExcelAddress(XSeries);
                        if (dataPointNr > (address._toCol - address._fromCol))
                        {
                            throw new Exception("Data Point index is higher than  amount of columns (cells?) for this series. Max possible value is: " + (address._toCol - address._fromCol));
                        }
                        else
                        {
                            //color string
                            string color = newColor.ToArgb().ToString("X").Substring(2, 6);
                            //get all Data Point nodes
                            XmlNodeList nodeList = _node.SelectNodes("c:dPt", _ns);
                            //create node because it doesn't exist
                            if (dataPointNr + 1 > nodeList.Count)
                            {
                               XmlElement dpt = _node.OwnerDocument.CreateElement("c", "dPt", ExcelPackage.schemaChart);
                               //index
                               XmlElement temp = _node.OwnerDocument.CreateElement("c", "idx", ExcelPackage.schemaChart);
                               XmlAttribute tempAttr = _node.OwnerDocument.CreateAttribute("val");
                               //index must be incremental if previous Data Points exist
                               tempAttr.Value = nodeList.Count.ToString();
                               temp.Attributes.Append(tempAttr);
                               dpt.AppendChild(temp);
                               //bubble
                               temp = _node.OwnerDocument.CreateElement("c", "bubble3D", ExcelPackage.schemaChart);
                               tempAttr = _node.OwnerDocument.CreateAttribute("val");
                               tempAttr.Value = "0";
                               temp.Attributes.Append(tempAttr);
                               dpt.AppendChild(temp);
                               temp = _node.OwnerDocument.CreateElement("c", "spPr", ExcelPackage.schemaChart);
                               string nameSpaceURI = NameSpaceManager.LookupNamespace("a");
                               XmlElement temp2 = _node.OwnerDocument.CreateElement("a", "solidFill", nameSpaceURI);
                               XmlElement temp3 = _node.OwnerDocument.CreateElement("a", "srgbClr", nameSpaceURI);
                               tempAttr = _node.OwnerDocument.CreateAttribute("val");
                               tempAttr.Value = color;
                               temp3.Attributes.Append(tempAttr);
                               temp2.AppendChild(temp3);
                               temp.AppendChild(temp2);
                               dpt.AppendChild(temp);

                               if (nodeList.Count > 0)
                               {
                                   //if other Data Points exist
                                   _node.InsertAfter(dpt, nodeList[nodeList.Count - 1]);
                               }
                               else
                               {
                                   //if first Data Point
                                   InserAfter(_node, "c:tx", dpt);
                               }
                            }
                            else 
                            {
                                //node already exists, change it
                                SetXmlNodeString(nodeList[dataPointNr], dataPointChildrenPath, color);
                            }
                         }
                         break;
                    }
                default:
                    throw new Exception("Ooops! Update the supported chart type list or the implementation for this chart type, something is missing!");
            }
        }

Also change the SchemaNodeOrder in the same class to

SchemaNodeOrder = new string[] { "idx", "order", "dPt", "tx", "marker", "trendline", "explosion", "dLbls", "cat", "val", "yVal", "xVal" };

That's it! :D

Mar 12, 2012 at 1:07 PM
Edited Mar 12, 2012 at 1:10 PM

<please moderator delete me! - wrong button pressed>