private IEnumerable <T> SetChartSeries <T>(OpenXmlCompositeElement chart, int newSeriesCount, bool addNewIfRequired) where T : OpenXmlCompositeElement { var seriesList = chart.Elements <T>(); int currentSeriesCount = seriesList.Count(); if (currentSeriesCount > newSeriesCount) { //chart on template has more series than in the data, remove last x series int seriesToRemove = currentSeriesCount - newSeriesCount; for (int i = 0; i < seriesToRemove; i++) { chart.RemoveChild <T>(seriesList.Last()); } seriesList = chart.Elements <T>(); } else if (addNewIfRequired && currentSeriesCount < newSeriesCount) { //chart on the template has fewer series so we need to add some by clonning the last one for (int i = 0; i < newSeriesCount - currentSeriesCount; i++) { var lastSeries = chart.Elements <T>().Last(); var seriesClone = (T)lastSeries.CloneNode(true); var lastSeriesIndex = lastSeries.FirstElement <DocumentFormat.OpenXml.Drawing.Charts.Index>(); var seriesCloneIndex = seriesClone.FirstElement <DocumentFormat.OpenXml.Drawing.Charts.Index>(); seriesCloneIndex.Val = new UInt32Value(lastSeriesIndex.Val.Value + 1); var lastSeriesOrder = lastSeries.FirstElement <DocumentFormat.OpenXml.Drawing.Charts.Order>(); var seriesCloneOrder = seriesClone.FirstElement <DocumentFormat.OpenXml.Drawing.Charts.Order>(); seriesCloneOrder.Val = new UInt32Value(lastSeriesOrder.Val.Value + 1); chart.InsertAfter(seriesClone, lastSeries); } seriesList = chart.Elements <T>(); } return(chart.Elements <T>()); }
// SetProperties (to enforce XSD Schema compliance) #region SetProperties /// <summary> /// Insert a style element inside a RunProperties, taking care of the correct sequence order as defined in the ECMA Standard. /// </summary> /// <param name="containerProperties">A RunProperties or ParagraphProperties wherein the tag will be inserted.</param> /// <param name="tag">The style to apply to the run.</param> protected void SetProperties(OpenXmlCompositeElement containerProperties, OpenXmlElement tag) { // This implementation is largely inspired by DocumentFormat.OpenXml.OpenXmlCompositeElement.SetElement which is internal. int tagOrder = GetTagOrder(tag); OpenXmlElement firstChild = containerProperties.FirstChild; OpenXmlElement openXmlElement = null; Type type = tag.GetType(); while (firstChild != null) { bool isKnownElement = (!(firstChild is OpenXmlUnknownElement) && !(firstChild is OpenXmlMiscNode)); if (isKnownElement) { int num = GetTagOrder(firstChild); if (num != tagOrder) { if (num > tagOrder) { break; } openXmlElement = firstChild; } #if FEATURE_REFLECTION else if (!type.IsInstanceOfType(tag)) #else else if (!type.GetTypeInfo().IsAssignableFrom(tag.GetType().GetTypeInfo())) #endif { openXmlElement = firstChild; } else { openXmlElement = firstChild.PreviousSibling(); containerProperties.RemoveChild <OpenXmlElement>(firstChild); break; } } firstChild = firstChild.NextSibling(); } if (tag != null) { containerProperties.InsertAfter(tag, openXmlElement); } }
private void FixNakedText(OpenXmlCompositeElement par, INodeProvider nodeProvider) //Simple Spreadsheets cells { if (par.ChildElements.Count != 1) { return; } var only = par.ChildElements.Only(); if (!nodeProvider.IsText(only)) { return; } var text = nodeProvider.GetText(only); if (!TemplateUtils.KeywordsRegex.IsMatch(text)) { return; } par.RemoveChild(only); par.AppendChild(nodeProvider.WrapInRun(only)); }
/// <summary> /// Insert a style element inside a RunProperties, taking care of the correct sequence order as defined in the ECMA Standard. /// </summary> /// <param name="containerProperties">A RunProperties or ParagraphProperties wherein the tag will be inserted.</param> /// <param name="tag">The style to apply to the run.</param> protected void SetProperties(OpenXmlCompositeElement containerProperties, OpenXmlElement tag) { // This implementation is largely inspired by DocumentFormat.OpenXml.OpenXmlCompositeElement.SetElement which is internal. int tagOrder = GetTagOrder(tag); OpenXmlElement firstChild = containerProperties.FirstChild; OpenXmlElement openXmlElement = null; Type type = tag.GetType(); while (firstChild != null) { bool isKnownElement = (!(firstChild is OpenXmlUnknownElement) && !(firstChild is OpenXmlMiscNode)); if (isKnownElement) { int num = GetTagOrder(firstChild); if (num != tagOrder) { if (num > tagOrder) break; openXmlElement = firstChild; } else if (!type.IsInstanceOfType(tag)) { openXmlElement = firstChild; } else { openXmlElement = firstChild.PreviousSibling(); containerProperties.RemoveChild<OpenXmlElement>(firstChild); break; } } firstChild = firstChild.NextSibling(); } if (tag != null) containerProperties.InsertAfter(tag, openXmlElement); }
/// <summary> /// Sets the color of the series using a solidcolor brush /// If a null brush is supplied any color is removed so the color will be automatic /// </summary> /// <param name="line">The line.</param> /// <param name="brush">The brush.</param> public static void UpdateLineBrush(this OpenXmlCompositeElement line, Brush brush) { if (line == null) { return; } // If we have a BarChart, we really want tp update the SolidFill (not the Outline.SolidFill) BarChartSeries barChartSeries = line as BarChartSeries; if (barChartSeries != null) { // For BarCharts, we update the SolidFill barChartSeries.UpdateSeriesColour((SolidColorBrush)brush); } else { // Update the Outline.SolidFill + set the SolidFill to the same colour var chartShapeProperties = line.Descendants <ChartShapeProperties>().FirstOrDefault(); if (brush == null && !(brush is SolidColorBrush)) { if (chartShapeProperties != null) { line.RemoveChild <ChartShapeProperties>(chartShapeProperties); } return; } // the series title, this is the name of the column header var seriesText = line.Descendants <SeriesText>().FirstOrDefault(); if (chartShapeProperties == null) { chartShapeProperties = new ChartShapeProperties(); // if there's a series text then insert afterwards if (seriesText == null) { line.InsertAt <ChartShapeProperties>(chartShapeProperties, 0); } else { line.InsertAfter <ChartShapeProperties>(chartShapeProperties, seriesText); } } var outline = chartShapeProperties.Descendants <Outline>().FirstOrDefault(); if (outline == null) { outline = new Outline(); chartShapeProperties.InsertAt(outline, 0); } var outlineSolidFill = outline.Descendants <SolidFill>().FirstOrDefault(); if (outlineSolidFill == null) { outlineSolidFill = new SolidFill(); outline.Append(outlineSolidFill); } // Update the fill with the supplied brush colour outlineSolidFill.UpdateSolidFill((SolidColorBrush)brush); // Clones the OutlineSolidFill as the SolidFill of the series... var solidFill = chartShapeProperties.GetFirstChild <SolidFill>(); if (solidFill != null) { chartShapeProperties.RemoveChild(solidFill); } chartShapeProperties.InsertAt(outlineSolidFill.CloneNode(true), 0); } }