public void ProcessChildShapes(ShapeElementBase shape, ChildShapeElement childShape, ChartType type, OpenXmlElement childChart, List <ChartSeriesElement> newSeries)
        {
            childShape.Data = fullData.GetFragmentByIndexes(childShape.RowIndexes, childShape.ColumnIndexes);
            element.ProcessCommands(childShape.Data);
            switch (type)
            {
            case ChartType.Waterfall:
            case ChartType.Bar:
                ReplaceBarChart(newSeries, childChart as BarChart, childShape, false);
                break;

            case ChartType.Scatter:
                ReplaceScatterChart(newSeries, childChart as ScatterChart, childShape);
                break;

            case ChartType.Line:
                ReplaceLineChart(newSeries, childChart as LineChart, childShape);
                break;
            }
        }
        public void Process(ShapeElementBase shape)
        {
            element      = shape as ChartElement;
            fullData     = element.Data.Clone();
            element.Data = fullData.GetFragmentByIndexes(element.RowIndexes, element.ColumnIndexes);
            element.ProcessCommands(element.Data);
            if (element.Data == null)
            {
                return;
            }

            //get chart reference
            A.GraphicData  graphicData    = element.ChartFrame.Graphic.GraphicData;
            ChartReference chartReference = graphicData.FirstElement <ChartReference>();

            if (chartReference == null)
            {
                return;
            }

            //various chart structure elements
            ChartPart chartPart = element.Slide.Slide.SlidePart.GetPartById(chartReference.Id.Value) as ChartPart;
            Chart     chart     = chartPart.ChartSpace.FirstElement <Chart>();

            //get external data and update it
            DataElement dataToInsert = element.Data.Clone();

            foreach (var item in element.ChildShapes)
            {
                var childDataElement = fullData.GetFragmentByIndexes(item.RowIndexes, item.ColumnIndexes);
                element.ProcessCommands(childDataElement);
                dataToInsert.MergeWith(childDataElement);
            }
            ExternalData        externalData   = chartPart.ChartSpace.FirstElement <ExternalData>();
            EmbeddedPackagePart xlsPackagePart = chartPart.GetPartById(externalData.Id.Value) as EmbeddedPackagePart;
            Stream sourceStream = xlsPackagePart.GetStream();
            Stream outputStream = new MemoryStream();

            dataToInsert.TrimHiddenRowsAndColumns();
            List <ChartSeriesElement> newSeries = SpreadsheetProcessor.InsertData(dataToInsert, sourceStream, outputStream);

            outputStream.Seek(0, SeekOrigin.Begin);
            xlsPackagePart.FeedData(outputStream);


            ChartType        type      = ChartType.None;
            Tuple <int, int> dataRange = null;
            var charts = chart.PlotArea.Elements().ToList();

            OpenXmlElement mainChart  = null;
            int            chartIndex = 0;

            for (; chartIndex < charts.Count; chartIndex++)
            {
                GetChartTypeAndDataRange(ref type, ref dataRange, charts[chartIndex]);
                if (type != ChartType.None)
                {
                    mainChart = charts[chartIndex];
                    chartIndex++;
                    break;
                }
            }


            int seriesIndex = 0;

            foreach (ErrorBarCommand errorBarCommand in element.CommandsOf <ErrorBarCommand>())
            {
                ChartSeriesElement chartSeriesMinus = newSeries.FirstOrDefault(s => s.ColumnIndex == errorBarCommand.MinusIndex && !s.ColumnIndex.IsCore);
                ChartSeriesElement chartSeriesPlus  = null;
                if (errorBarCommand.PlusIndex != null)
                {
                    chartSeriesPlus = newSeries.FirstOrDefault(s => s.ColumnIndex == errorBarCommand.PlusIndex && !s.ColumnIndex.IsCore);
                }
                if (seriesIndex < newSeries.Count)
                {
                    newSeries[seriesIndex].MinusErrorBar = chartSeriesMinus;
                    newSeries[seriesIndex].PlusErrorBar  = chartSeriesPlus;
                }
                seriesIndex++;
            }
            foreach (ErrorBarCommand errorBarCommand in element.CommandsOf <ErrorBarCommand>())
            {
                ChartSeriesElement chartSeriesMinus = newSeries.FirstOrDefault(s => s.ColumnIndex == errorBarCommand.MinusIndex && !s.ColumnIndex.IsCore);
                ChartSeriesElement chartSeriesPlus  = null;
                if (errorBarCommand.PlusIndex != null)
                {
                    chartSeriesPlus = newSeries.FirstOrDefault(s => s.ColumnIndex == errorBarCommand.PlusIndex && !s.ColumnIndex.IsCore);
                }
                if (chartSeriesMinus != null)
                {
                    newSeries.Remove(chartSeriesMinus);
                }
                if (chartSeriesPlus != null)
                {
                    newSeries.Remove(chartSeriesPlus);
                }
            }
            seriesIndex = 0;
            if (element.CommandsOf <YCommand>().Count > 0)
            {
                List <ChartSeriesElement> newSeriesWithoutY = new List <ChartSeriesElement>(newSeries);
                foreach (YCommand yCommand in element.CommandsOf <YCommand>())
                {
                    ChartSeriesElement yChartSeries = newSeries.FirstOrDefault(s => s.ColumnIndex == yCommand.Index);  //  && !s.ColumnIndex.IsCore
                    if (yChartSeries != null)
                    {
                        newSeriesWithoutY.Remove(yChartSeries);
                    }
                }
                foreach (YCommand yCommand in element.CommandsOf <YCommand>())
                {
                    ChartSeriesElement yChartSeries = newSeries.FirstOrDefault(s => s.ColumnIndex == yCommand.Index); // && !s.ColumnIndex.IsCore
                    for (int i = seriesIndex; i < newSeriesWithoutY.Count; i++)
                    {
                        newSeriesWithoutY[i].YValues = yChartSeries;
                    }
                    //if (seriesIndex < newSeries.Count)
                    //{
                    //    newSeries[seriesIndex].YValues = yChartSeries;
                    //}
                    seriesIndex++;
                }
                newSeries = new List <ChartSeriesElement>(newSeriesWithoutY);
            }


            switch (type)
            {
            case ChartType.Waterfall:
            case ChartType.Bar:
                ReplaceBarChart(newSeries, mainChart as BarChart, element, element.IsWaterfall);
                break;

            case ChartType.Scatter:
                ReplaceScatterChart(newSeries, mainChart as ScatterChart, element);
                break;

            case ChartType.Line:
                ReplaceLineChart(newSeries, mainChart as LineChart, element);
                break;
            }
            int childShapeIndex = 0;

            for (; chartIndex < charts.Count; chartIndex++)
            {
                var childChart = charts[chartIndex];
                if (element.ChildShapes.Count > childShapeIndex)
                {
                    GetChartTypeAndDataRange(ref type, ref dataRange, childChart);
                    if (type != ChartType.None)
                    {
                        ProcessChildShapes(element, element.ChildShapes[childShapeIndex], type, childChart, newSeries);
                        childShapeIndex++;
                    }
                }
            }
        }