2016-04-09 3 views
3

Ich frage mich, ob es eine Möglichkeit gibt, die Legendeneintragsfarben manuell festzulegen.Die Legendenfarbe ist falsch im Excel-Diagramm, das mit EPPlus erstellt wurde

Ich habe die Serienfarben in eine benutzerdefinierte Farbe geändert, aber die Legendenfarbe wird nicht aktualisiert. Siehe Bild:

Incorrect legend color

+0

könnte den Code verwendet zu stellen. – Ernie

+0

Ich benutze den Code von diesem Beitrag, es scheint nur, dass der Autor Legendenfarbe nicht berücksichtigt. http://stackoverflow.com/questions/34356874/epplus-columnstacked-chart-data-point-colors – user1854458

Antwort

4

Hier eine verbesserte Version des Codes ist, dass die OP in den Kommentaren verknüpft. Diese Version, die Sie in der Farbe übergeben Sie wollen (statt es nur zufällig diejenigen verwenden) SetChartPointsColor und es wird alle Punkte Farben auf den gleichen sowie Erstellen und Eintritt für die Legende ein:

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); 
} 

Verwenden Sie es wie dies:

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(); 
} 

Gibt dies in der Ausgabe:

Example Output

RESPONSE ZU KOMMENTARE

Für eine Linie Serie wäre es ein wenig anders:

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([email protected]"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); 
} 
+0

Danke, das ist großartig! Folgefrage: Wie kann das für ein Liniendiagramm funktionieren? Ich habe das XML aktualisiert, um "c: barChart /" auszuwählen, aber es wird die Standardfarben nicht ändern. – user1854458

+0

@ user1854458 Siehe meine Änderungen oben. – Ernie

Verwandte Themen