6

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:

Incorrect legend color

user1854458
  • 615
  • 8
  • 16
  • Might want to post the code you used. – Ernie S Apr 09 '16 at 23:42
  • I am using the code from this post, it just seems the author didn't account for legend color. http://stackoverflow.com/questions/34356874/epplus-columnstacked-chart-data-point-colors – user1854458 Apr 10 '16 at 15:52

1 Answers1

8

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:

Example 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);
}
Ernie S
  • 13,902
  • 4
  • 52
  • 79
  • Thanks, this is great! Follow up question: How can this work for a line graph? I've updated the xml to select "c:barChart/" but it will not change the default colors. – user1854458 Apr 12 '16 at 23:46
  • For anyone who wants to modify this solution for another type of of graph, you need to change 'c:barChart' to your chart type. You can find your chart type by making a sample xlsx file with the type of chart you want. Then change the file extension of the xlsx file to .zip then unzip the folder. The chart name will be defined in the /xl/ folder. I did a search for the keyword 'Chart' and was able to find mine. – Seabass77 Jul 31 '19 at 13:28