I am wondering if there is a way to manually set the legend entry colors.
I changed the series colors to a custom color, but the legend color is not updating. See image:
Here is an improved version of the code that the OP linked to in the comments. This version you pass in the color you want (instead of it just using random ones) to SetChartPointsColor
and it will set all point colors to the same as well as create and entry for the legend:
public static void SetChartPointsColor(this ExcelChart chart, int serieNumber, Color color)
{
var chartXml = chart.ChartXml;
var nsa = chart.WorkSheet.Drawings.NameSpaceManager.LookupNamespace("a");
var nsuri = chartXml.DocumentElement.NamespaceURI;
var nsm = new XmlNamespaceManager(chartXml.NameTable);
nsm.AddNamespace("a", nsa);
nsm.AddNamespace("c", nsuri);
var serieNode = chart.ChartXml.SelectSingleNode(@"c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[c:idx[@val='" + serieNumber + "']]", nsm);
var serie = chart.Series[serieNumber];
var points = serie.Series.Length;
//Add reference to the color for the legend and data points
var srgbClr = chartXml.CreateNode(XmlNodeType.Element, "srgbClr", nsa);
var att = chartXml.CreateAttribute("val");
att.Value = $"{color.R:X2}{color.G:X2}{color.B:X2}";
srgbClr.Attributes.Append(att);
var solidFill = chartXml.CreateNode(XmlNodeType.Element, "solidFill", nsa);
solidFill.AppendChild(srgbClr);
var spPr = chartXml.CreateNode(XmlNodeType.Element, "spPr", nsuri);
spPr.AppendChild(solidFill);
serieNode.AppendChild(spPr);
}
Use it like this:
using (var pck = new ExcelPackage(fileInfo))
{
var workbook = pck.Workbook;
var worksheet = workbook.Worksheets.Add("Sheet1");
worksheet.Cells.LoadFromDataTable(datatable, true);
var chart = worksheet.Drawings.AddChart("chart test", eChartType.ColumnStacked);
chart.Series.Add(worksheet.Cells["B2:B11"], worksheet.Cells["A2:A11"]);
chart.Series.Add(worksheet.Cells["C2:C11"], worksheet.Cells["A2:A11"]);
var rand = new Random();
var color = Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256));
chart.SetChartPointsColor(0, color);
color = Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256));
chart.SetChartPointsColor(1, color);
pck.Save();
}
Gives this in the output:
RESPONSE TO COMMENTS
For a line series it would be a little different:
public static void SetLineChartColor(this ExcelChart chart, int serieNumber, Color color)
{
var chartXml = chart.ChartXml;
var nsa = chart.WorkSheet.Drawings.NameSpaceManager.LookupNamespace("a");
var nsuri = chartXml.DocumentElement.NamespaceURI;
var nsm = new XmlNamespaceManager(chartXml.NameTable);
nsm.AddNamespace("a", nsa);
nsm.AddNamespace("c", nsuri);
var serieNode = chart.ChartXml.SelectSingleNode($@"c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser[c:idx[@val='{serieNumber}']]", nsm);
var serie = chart.Series[serieNumber];
var points = serie.Series.Length;
//Add reference to the color for the legend
var srgbClr = chartXml.CreateNode(XmlNodeType.Element, "srgbClr", nsa);
var att = chartXml.CreateAttribute("val");
att.Value = $"{color.R:X2}{color.G:X2}{color.B:X2}";
srgbClr.Attributes.Append(att);
var solidFill = chartXml.CreateNode(XmlNodeType.Element, "solidFill", nsa);
solidFill.AppendChild(srgbClr);
var ln = chartXml.CreateNode(XmlNodeType.Element, "ln", nsa);
ln.AppendChild(solidFill);
var spPr = chartXml.CreateNode(XmlNodeType.Element, "spPr", nsuri);
spPr.AppendChild(ln);
serieNode.AppendChild(spPr);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With