diff --git a/ooxml/XSSF/UserModel/XSSFDrawing.cs b/ooxml/XSSF/UserModel/XSSFDrawing.cs index f7deaf970..b0912c1dd 100644 --- a/ooxml/XSSF/UserModel/XSSFDrawing.cs +++ b/ooxml/XSSF/UserModel/XSSFDrawing.cs @@ -26,7 +26,8 @@ limitations under the License. using NPOI.OpenXmlFormats.Dml; using NPOI.SS.Util; using NPOI.Util; - +using System.Text.RegularExpressions; +using System.Linq; namespace NPOI.XSSF.UserModel { @@ -170,8 +171,7 @@ public IPicture CreatePicture(IClientAnchor anchor, int pictureIndex) /// the newly created chart public IChart CreateChart(IClientAnchor anchor) { - int chartNumber = GetPackagePart().Package. - GetPartsByContentType(XSSFRelation.CHART.ContentType).Count + 1; + int chartNumber = GetNewChartNumber(); RelationPart rp = CreateRelationship( XSSFRelation.CHART, XSSFFactory.GetInstance(), chartNumber, false); @@ -184,6 +184,54 @@ public IChart CreateChart(IClientAnchor anchor) return chart; } + /// + /// Removes chart. + /// + /// The chart to be removed. + public void RemoveChart(XSSFChart chart) + { + CT_Drawing ctDrawing = GetCTDrawing(); + XSSFGraphicFrame frame = chart.GetGraphicFrame(); + CT_GraphicalObjectFrame internalFrame = frame.GetCTGraphicalObjectFrame(); + int anchorIndex = ctDrawing.CellAnchors.FindIndex(anchor => anchor.graphicFrame == internalFrame); + + if (anchorIndex != -1) + { + ctDrawing.CellAnchors.RemoveAt(anchorIndex); + + foreach (var part in GetRelations().Where(part => part is XSSFChart && part == chart)) + { + RemoveRelation(part); + } + } + } + + private int GetNewChartNumber() + { + List existingCharts = GetPackagePart().Package. + GetPartsByContentType(XSSFRelation.CHART.ContentType); + HashSet numbers = new HashSet(); + + foreach (PackagePart chart in existingCharts) + { + var match = Regex.Match(chart.PartName.Name, @"\d+"); + + if (match.Success) + { + numbers.Add(int.Parse(match.Value)); + } + } + + var newChartNumber = 1; + + while (numbers.Contains(newChartNumber)) + { + newChartNumber++; + } + + return newChartNumber; + } + //public XSSFChart CreateChart(IClientAnchor anchor) //{ // return CreateChart((XSSFClientAnchor)anchor); diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs index ecd718e98..c54fc920b 100644 --- a/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs @@ -21,6 +21,8 @@ limitations under the License. using NPOI.SS.UserModel.Charts; using NPOI.XSSF.UserModel; using NPOI.XSSF; +using NPOI.OpenXmlFormats.Dml.Spreadsheet; +using System.Linq; namespace TestCases.XSSF.UserModel { @@ -66,6 +68,7 @@ public void TestGetCharts() Assert.IsNotNull(XSSFTestDataSamples.WriteOutAndReadBack(wb)); } + [Test] public void TestAddChartsToNewWorkbook() { @@ -88,6 +91,47 @@ public void TestAddChartsToNewWorkbook() Assert.IsNotNull(XSSFTestDataSamples.WriteOutAndReadBack(wb)); } + [Test] + public void TestRemoveChart() + { + XSSFWorkbook workbook = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet)workbook.CreateSheet(); + XSSFDrawing drawingPatriarch = (XSSFDrawing)sheet.CreateDrawingPatriarch(); + XSSFClientAnchor anchor1 = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); + XSSFChart chart = (XSSFChart)drawingPatriarch.CreateChart(anchor1); + XSSFClientAnchor anchor2 = new XSSFClientAnchor(0, 0, 0, 0, 1, 11, 10, 60); + _ = (XSSFChart)drawingPatriarch.CreateChart(anchor2); + + Assert.AreEqual(2, drawingPatriarch.GetCharts().Count); + + drawingPatriarch.RemoveChart(chart); + + Assert.AreEqual(1, drawingPatriarch.GetCharts().Count); + } + + [Test] + public void TestRemoveOneOfTwoChartsAndAddNewOne() + { + XSSFWorkbook workbook = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet)workbook.CreateSheet(); + XSSFDrawing drawingPatriarch = (XSSFDrawing)sheet.CreateDrawingPatriarch(); + XSSFClientAnchor anchor1 = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); + XSSFChart chart = (XSSFChart)drawingPatriarch.CreateChart(anchor1); + XSSFClientAnchor anchor2 = new XSSFClientAnchor(0, 0, 0, 0, 1, 11, 10, 60); + _ = (XSSFChart)drawingPatriarch.CreateChart(anchor2); + + Assert.AreEqual(2, drawingPatriarch.GetCharts().Count); + + drawingPatriarch.RemoveChart(chart); + + Assert.AreEqual(1, drawingPatriarch.GetCharts().Count); + + XSSFClientAnchor a3 = new XSSFClientAnchor(0, 0, 0, 0, 1, 111, 10, 90); + _ = (XSSFChart)drawingPatriarch.CreateChart(a3); + + Assert.AreEqual(2, drawingPatriarch.GetCharts().Count); + } + [Test] public void TestGetChartAxisBug57362() {