]> source.dussan.org Git - poi.git/commitdiff
Patch from Jens Gotze from bug #49581 - Ability to add, modify and remove series...
authorNick Burch <nick@apache.org>
Fri, 16 Jul 2010 16:46:42 +0000 (16:46 +0000)
committerNick Burch <nick@apache.org>
Fri, 16 Jul 2010 16:46:42 +0000 (16:46 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@964855 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/record/RecordFactory.java
src/java/org/apache/poi/hssf/record/chart/ChartEndBlockRecord.java
src/java/org/apache/poi/hssf/record/chart/ChartStartBlockRecord.java
src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFChart.java
src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestHSSFChart.java
test-data/spreadsheet/49581.xls [new file with mode: 0644]

index b7b6e6c4239cad637ca4c252d7104f31875a5df6..18ae27fb982d2bde47bc2abf3e4683aa564df734 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.7-beta2" date="2010-??-??">
+           <action dev="POI-DEVELOPERS" type="add">49581 - Ability to add, modify and remove series from HSSF Charts</action>
            <action dev="POI-DEVELOPERS" type="add">49185 - Support for HSSFNames where the comment is stored in a NameCommentRecord</action>
            <action dev="POI-DEVELOPERS" type="fix">49599 - Correct writing of NoteRecord author text when switching between ASCII and Unicode</action>
            <action dev="POI-DEVELOPERS" type="fix">HWPF: Improve reading of auto-saved ("complex") documents</action>
index 07db07133e22c7159359d524aff6f8251166aa7b..029b7e0413dbaa6917bb227ee21c76c128475c64 100644 (file)
@@ -232,6 +232,7 @@ public final class RecordFactory {
                ChartStartObjectRecord.class,
                ChartEndObjectRecord.class,
                CatLabRecord.class,
+      DataFormatRecord.class,
                EndRecord.class,
                LinkedDataRecord.class,
                SeriesToChartGroupRecord.class,
index ac823b2b1282ed8418658f5c29d9fdc51f16f9f9..dcb722b826b6708a768dd2618ada684a495a394b 100644 (file)
@@ -35,6 +35,9 @@ public final class ChartEndBlockRecord extends StandardRecord {
        private short iObjectKind;
        private byte[] unused;
 
+       public ChartEndBlockRecord() {
+       }
+       
        public ChartEndBlockRecord(RecordInputStream in) {
                rt = in.readShort();
                grbitFrt = in.readShort();
@@ -80,4 +83,16 @@ public final class ChartEndBlockRecord extends StandardRecord {
                buffer.append("[/ENDBLOCK]\n");
                return buffer.toString();
        }
+       
+       @Override
+       public ChartEndBlockRecord clone() {
+               ChartEndBlockRecord record = new ChartEndBlockRecord();
+               
+               record.rt = rt ;
+               record.grbitFrt = grbitFrt ;
+               record.iObjectKind = iObjectKind ;
+               record.unused = unused.clone() ;
+               
+               return record;
+       }
 }
index f4e1f2f6556bc1f5b44c47e94e22c25affd11759..1bb41ddc7bc86470b2fb7596e67139c62eb9b47f 100644 (file)
@@ -37,6 +37,9 @@ public final class ChartStartBlockRecord extends StandardRecord {
        private short iObjectInstance1;
        private short iObjectInstance2;
 
+       public ChartStartBlockRecord() {
+       }
+       
        public ChartStartBlockRecord(RecordInputStream in) {
                rt = in.readShort();
                grbitFrt = in.readShort();
@@ -80,4 +83,18 @@ public final class ChartStartBlockRecord extends StandardRecord {
                buffer.append("[/STARTBLOCK]\n");
                return buffer.toString();
        }
+       
+       @Override
+       public ChartStartBlockRecord clone() {
+               ChartStartBlockRecord record = new ChartStartBlockRecord();
+               
+               record.rt = rt;
+               record.grbitFrt = grbitFrt;
+               record.iObjectKind = iObjectKind;
+               record.iObjectContext = iObjectContext;
+               record.iObjectInstance1 = iObjectInstance1;
+               record.iObjectInstance2 = iObjectInstance2;
+               
+               return record;
+       }
 }
index 9192d97d787875353a6bf997a2f4b2e242c3f182..b1a26f798b9e820289ed318c5aab1fb5b34982b3 100644 (file)
@@ -18,6 +18,7 @@
 package org.apache.poi.hssf.usermodel;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 import org.apache.poi.hssf.record.chart.*;
@@ -35,8 +36,10 @@ import org.apache.poi.hssf.record.SCLRecord;
 import org.apache.poi.hssf.record.UnknownRecord;
 import org.apache.poi.hssf.record.VCenterRecord;
 import org.apache.poi.hssf.record.formula.Area3DPtg;
+import org.apache.poi.hssf.record.formula.AreaPtgBase;
 import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.chart.LinkedDataRecord;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressBase;
 
 /**
  * Has methods for construction of a chart object.
@@ -44,6 +47,7 @@ import org.apache.poi.hssf.record.chart.LinkedDataRecord;
  * @author Glen Stampoultzis (glens at apache.org)
  */
 public final class HSSFChart {
+       private HSSFSheet sheet;
        private ChartRecord chartRecord;
 
        private LegendRecord legendRecord;
@@ -51,10 +55,54 @@ public final class HSSFChart {
        private SeriesTextRecord chartTitleText;
        private List<ValueRangeRecord> valueRanges = new ArrayList<ValueRangeRecord>(); 
        
+       private HSSFChartType type = HSSFChartType.Unknown;
+       
        private List<HSSFSeries> series = new ArrayList<HSSFSeries>();
 
-       private HSSFChart(ChartRecord chartRecord) {
+       public enum HSSFChartType {
+               Area {
+                       @Override
+                       public short getSid() {
+                               return 0x101A;
+                       }
+               },
+               Bar {
+                       @Override
+                       public short getSid() {
+                               return 0x1017;
+                       }
+               },
+               Line {
+                       @Override
+                       public short getSid() {
+                               return 0x1018;
+                       }
+               },
+               Pie {
+                       @Override
+                       public short getSid() {
+                               return 0x1019;
+                       }
+               },
+               Scatter {
+                       @Override
+                       public short getSid() {
+                               return 0x101B;
+                       }
+               },
+               Unknown {
+                       @Override
+                       public short getSid() {
+                               return 0;
+                       }
+               };
+               
+               public abstract short getSid();
+       }
+
+       private HSSFChart(HSSFSheet sheet, ChartRecord chartRecord) {
                this.chartRecord = chartRecord;
+               this.sheet = sheet;
        }
 
        /**
@@ -146,22 +194,20 @@ public final class HSSFChart {
                for(RecordBase r : records) {
 
                        if(r instanceof ChartRecord) {
-                               lastChart = new HSSFChart((ChartRecord)r);
+                               lastSeries = null;
+                               
+                               lastChart = new HSSFChart(sheet,(ChartRecord)r);
                                charts.add(lastChart);
-                       }
-                       if(r instanceof LegendRecord) {
+                       } else if(r instanceof LegendRecord) {
                                lastChart.legendRecord = (LegendRecord)r;
-                       }
-                       if(r instanceof SeriesRecord) {
+                       } else if(r instanceof SeriesRecord) {
                                HSSFSeries series = lastChart.new HSSFSeries( (SeriesRecord)r );
                                lastChart.series.add(series);
                                lastSeries = series;
-                       }
-                       if(r instanceof ChartTitleFormatRecord) {
+                       } else if(r instanceof ChartTitleFormatRecord) {
                                lastChart.chartTitleFormat =
                                        (ChartTitleFormatRecord)r;
-                       }
-                       if(r instanceof SeriesTextRecord) {
+                       } else if(r instanceof SeriesTextRecord) {
                                // Applies to a series, unless we've seen
                                //  a legend already
                                SeriesTextRecord str = (SeriesTextRecord)r;
@@ -173,13 +219,28 @@ public final class HSSFChart {
                                } else {
                                        lastChart.chartTitleText = str;
                                }
-                       }
-                       if(r instanceof LinkedDataRecord) {
-                               LinkedDataRecord data = (LinkedDataRecord)r;
-                               lastSeries.insertData( data );
-                       }
-                       if(r instanceof ValueRangeRecord){
+                       } else if (r instanceof LinkedDataRecord) {
+                               LinkedDataRecord linkedDataRecord = (LinkedDataRecord) r;
+                               if (lastSeries != null) {
+                                       lastSeries.insertData(linkedDataRecord);
+                               }
+                       } else if(r instanceof ValueRangeRecord){
                                lastChart.valueRanges.add((ValueRangeRecord)r);
+                       } else if (r instanceof Record) {
+                               if (lastChart != null)
+                               {
+                                       Record record = (Record) r;
+                                       for (HSSFChartType type : HSSFChartType.values()) {
+                                               if (type == HSSFChartType.Unknown)
+                                               {
+                                                       continue;
+                                               }
+                                               if (record.getSid() == type.getSid()) {
+                                                       lastChart.type = type ;
+                                                       break;
+                                               }
+                                       }
+                               }
                        }
                }
 
@@ -908,14 +969,13 @@ public final class HSSFChart {
                private LinkedDataRecord dataValues;
                private LinkedDataRecord dataCategoryLabels;
                private LinkedDataRecord dataSecondaryCategoryLabels;
-               private int dataReaded = 0;
 
                /* package */ HSSFSeries(SeriesRecord series) {
                        this.series = series;
                }
 
-               public void insertData(LinkedDataRecord data){
-                       switch(dataReaded){
+               /* package */ void insertData(LinkedDataRecord data){
+                       switch(data.getLinkType()){
                                case 0: dataName = data;
                                break;
                                case 1: dataValues = data;
@@ -925,7 +985,11 @@ public final class HSSFChart {
                                case 3: dataSecondaryCategoryLabels = data;
                                break;
                        }
-                       dataReaded++;
+               }
+               
+               /* package */ void setSeriesTitleText(SeriesTextRecord seriesTitleText)
+               {
+                       this.seriesTitleText = seriesTitleText;
                }
                
                public short getNumValues() {
@@ -996,5 +1060,281 @@ public final class HSSFChart {
                public SeriesRecord getSeries() {
                        return series;
                }
+               
+               private CellRangeAddressBase getCellRange(LinkedDataRecord linkedDataRecord) {
+                       if (linkedDataRecord == null)
+                       {
+                               return null ;
+                       }
+                       
+                       int firstRow = 0;
+                       int lastRow = 0;
+                       int firstCol = 0;
+                       int lastCol = 0;
+                       
+                       for (Ptg ptg : linkedDataRecord.getFormulaOfLink()) {
+                               if (ptg instanceof AreaPtgBase) {
+                                       AreaPtgBase areaPtg = (AreaPtgBase) ptg;
+                                       
+                                       firstRow = areaPtg.getFirstRow();
+                                       lastRow = areaPtg.getLastRow();
+                                       
+                                       firstCol = areaPtg.getFirstColumn();
+                                       lastCol = areaPtg.getLastColumn();
+                               }
+                       }
+                       
+                       return new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
+               }
+               
+               public CellRangeAddressBase getValuesCellRange() {
+                       return getCellRange(dataValues);
+               }
+       
+               public CellRangeAddressBase getCategoryLabelsCellRange() {
+                       return getCellRange(dataCategoryLabels);
+               }
+       
+               private Integer setVerticalCellRange(LinkedDataRecord linkedDataRecord,
+                                                            CellRangeAddressBase range) {
+                       if (linkedDataRecord == null)
+                       {
+                               return null;
+                       }
+                       
+                       List<Ptg> ptgList = new ArrayList<Ptg>();
+                       
+                       int rowCount = (range.getLastRow() - range.getFirstRow()) + 1;
+                       int colCount = (range.getLastColumn() - range.getFirstColumn()) + 1;
+                       
+                       for (Ptg ptg : linkedDataRecord.getFormulaOfLink()) {
+                               if (ptg instanceof AreaPtgBase) {
+                                       AreaPtgBase areaPtg = (AreaPtgBase) ptg;
+                                       
+                                       areaPtg.setFirstRow(range.getFirstRow());
+                                       areaPtg.setLastRow(range.getLastRow());
+                                       
+                                       areaPtg.setFirstColumn(range.getFirstColumn());
+                                       areaPtg.setLastColumn(range.getLastColumn());
+                                       ptgList.add(areaPtg);
+                               }
+                       }
+                       
+                       linkedDataRecord.setFormulaOfLink(ptgList.toArray(new Ptg[ptgList.size()]));
+                       
+                       return rowCount * colCount;
+               }
+               
+               public void setValuesCellRange(CellRangeAddressBase range) {
+                       Integer count = setVerticalCellRange(dataValues, range);
+                       if (count == null)
+                       {
+                               return;
+                       }
+                       
+                       series.setNumValues((short)(int)count);
+               }
+               
+               public void setCategoryLabelsCellRange(CellRangeAddressBase range) {
+                       Integer count = setVerticalCellRange(dataCategoryLabels, range);
+                       if (count == null)
+                       {
+                               return;
+                       }
+                       
+                       series.setNumCategories((short)(int)count);
+               }
+       }
+       
+       public HSSFSeries createSeries() throws Exception {
+               ArrayList<RecordBase> seriesTemplate = new ArrayList<RecordBase>();
+               boolean seriesTemplateFilled = false;
+               
+               int idx = 0;
+               int deep = 0;
+               int chartRecordIdx = -1;
+               int chartDeep = -1;
+               int lastSeriesDeep = -1;
+               int endSeriesRecordIdx = -1;
+               int seriesIdx = 0;
+               final List<RecordBase> records = sheet.getSheet().getRecords();
+               
+               /* store first series as template and find last series index */
+               for(final RecordBase record : records) {                
+                       
+                       idx++;
+                       
+                       if (record instanceof BeginRecord) {
+                               deep++;
+                       } else if (record instanceof EndRecord) {
+                               deep--;
+                               
+                               if (lastSeriesDeep == deep) {
+                                       lastSeriesDeep = -1;
+                                       endSeriesRecordIdx = idx;
+                                       if (!seriesTemplateFilled) {
+                                               seriesTemplate.add(record);
+                                               seriesTemplateFilled = true;
+                                       }
+                               }
+                               
+                               if (chartDeep == deep) {
+                                       break;
+                               }
+                       }
+                       
+                       if (record instanceof ChartRecord) {
+                               if (record == chartRecord) {
+                                       chartRecordIdx = idx;
+                                       chartDeep = deep;
+                               }
+                       } else if (record instanceof SeriesRecord) {
+                               if (chartRecordIdx != -1) {
+                                       seriesIdx++;
+                                       lastSeriesDeep = deep;
+                               }
+                       }
+                       
+                       if (lastSeriesDeep != -1 && !seriesTemplateFilled) {
+                               seriesTemplate.add(record) ;
+                       }
+               }
+               
+               /* check if a series was found */
+               if (endSeriesRecordIdx == -1) {
+                       return null;
+               }
+               
+               /* next index in the records list where the new series can be inserted */
+               idx = endSeriesRecordIdx + 1;
+
+               HSSFSeries newSeries = null;
+               
+               /* duplicate record of the template series */
+               ArrayList<RecordBase> clonedRecords = new ArrayList<RecordBase>();
+               for(final RecordBase record : seriesTemplate) {         
+                       
+                       Record newRecord = null;
+                       
+                       if (record instanceof BeginRecord) {
+                               newRecord = new BeginRecord();
+                       } else if (record instanceof EndRecord) {
+                               newRecord = new EndRecord();
+                       } else if (record instanceof SeriesRecord) {
+                               SeriesRecord seriesRecord = (SeriesRecord) ((SeriesRecord)record).clone();
+                               newSeries = new HSSFSeries(seriesRecord);
+                               newRecord = seriesRecord;
+                       } else if (record instanceof LinkedDataRecord) {
+                               LinkedDataRecord linkedDataRecord = (LinkedDataRecord) ((LinkedDataRecord)record).clone();
+                               if (newSeries != null) {
+                                       newSeries.insertData(linkedDataRecord);
+                               }
+                               newRecord = linkedDataRecord;
+                       } else if (record instanceof DataFormatRecord) {
+                               DataFormatRecord dataFormatRecord = (DataFormatRecord) ((DataFormatRecord)record).clone();
+                               
+                               dataFormatRecord.setSeriesIndex((short)seriesIdx) ;
+                               dataFormatRecord.setSeriesNumber((short)seriesIdx) ;
+                               
+                               newRecord = dataFormatRecord;
+                       } else if (record instanceof SeriesTextRecord) {
+                               SeriesTextRecord seriesTextRecord = (SeriesTextRecord) ((SeriesTextRecord)record).clone();
+                               if (newSeries != null) {
+                                       newSeries.setSeriesTitleText(seriesTextRecord);
+                               }
+                               newRecord = seriesTextRecord;
+                       } else if (record instanceof Record) {
+                               newRecord = (Record) ((Record)record).clone();
+                       }
+                       
+                       if (newRecord != null)
+                       {
+                               clonedRecords.add(newRecord);
+                       }
+               }
+               
+               /* check if a user model series object was created */
+               if (newSeries == null)
+               {
+                       return null;
+               }
+               
+               /* transfer series to record list */
+               for(final RecordBase record : clonedRecords) {          
+                       records.add(idx++, record);
+               }
+               
+               return newSeries;
+       }
+       
+       public boolean removeSeries(HSSFSeries series) {
+               int idx = 0;
+               int deep = 0;
+               int chartDeep = -1;
+               int lastSeriesDeep = -1;
+               int seriesIdx = -1;
+               boolean removeSeries = false;
+               boolean chartEntered = false;
+               boolean result = false;
+               final List<RecordBase> records = sheet.getSheet().getRecords();
+               
+               /* store first series as template and find last series index */
+               Iterator<RecordBase> iter = records.iterator();
+               while (iter.hasNext()) {                
+                       RecordBase record = iter.next();
+                       idx++;
+                       
+                       if (record instanceof BeginRecord) {
+                               deep++;
+                       } else if (record instanceof EndRecord) {
+                               deep--;
+                               
+                               if (lastSeriesDeep == deep) {
+                                       lastSeriesDeep = -1;
+                                       
+                                       if (removeSeries) {
+                                               removeSeries = false;
+                                               result = true;
+                                               iter.remove();
+                                       }
+                               }
+                               
+                               if (chartDeep == deep) {
+                                       break;
+                               }
+                       }
+                       
+                       if (record instanceof ChartRecord) {
+                               if (record == chartRecord) {
+                                       chartDeep = deep;
+                                       chartEntered = true;
+                               }
+                       } else if (record instanceof SeriesRecord) {
+                               if (chartEntered) {
+                                       if (series.series == record) {
+                                               lastSeriesDeep = deep;
+                                               removeSeries = true;
+                                       } else {
+                                               seriesIdx++;
+                                       }
+                               }
+                       } else if (record instanceof DataFormatRecord) {
+                               if (chartEntered && !removeSeries) {
+                                       DataFormatRecord dataFormatRecord = (DataFormatRecord) record;
+                                       dataFormatRecord.setSeriesIndex((short) seriesIdx);
+                                       dataFormatRecord.setSeriesNumber((short) seriesIdx);
+                               }
+                       }
+                       
+                       if (removeSeries) {
+                               iter.remove();
+                       }
+               }
+               
+               return result;
+       }
+       
+       public HSSFChartType getType() {
+               return type;
        }
 }
index 5e2a34f1ed2cc4fd27928c4055e6913a27b5b76b..54d248319a18e712b15552e514a16a3a4a94efcd 100644 (file)
@@ -19,8 +19,12 @@ package org.apache.poi.hssf.usermodel;
 
 import junit.framework.TestCase;
 
+import org.apache.poi.hssf.HSSFITestDataProvider;
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.record.chart.SeriesRecord;
+import org.apache.poi.hssf.usermodel.HSSFChart.HSSFSeries;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressBase;
 
 /**
  * Tests for {@link HSSFChart}
@@ -127,4 +131,99 @@ public final class TestHSSFChart extends TestCase {
                assertEquals("Base Numbers", charts[0].getSeries()[1].getSeriesTitle());
                assertEquals("Sheet 3 Chart with Title", charts[0].getChartTitle());
        }
+       
+    public void testExistingSheet3() throws Exception {
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("49581.xls");
+        
+        HSSFSheet sheet = wb.getSheetAt( 2 ) ;
+        HSSFChart[] charts = HSSFChart.getSheetCharts( sheet ) ;
+        assertEquals(1, charts.length);
+        
+        for ( HSSFChart chart : charts ) {
+            for ( HSSFSeries series : chart.getSeries() ) {
+                chart.removeSeries( series ) ;
+            }
+        }
+        
+        // Save and re-check
+        wb = HSSFITestDataProvider.instance.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt( 2 ) ;
+        assertEquals(1, HSSFChart.getSheetCharts(sheet).length);
+        
+        HSSFChart c = HSSFChart.getSheetCharts(sheet)[0];
+        assertEquals(0, c.getSeries().length);
+    }
+
+    public void testExistingSheet2() throws Exception {
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("49581.xls");
+        HSSFSheet sheet = wb.getSheetAt( 1 ) ;
+        HSSFChart[] charts = HSSFChart.getSheetCharts( sheet ) ;
+        
+        assertEquals(1, charts.length);
+        for ( HSSFChart chart : charts ) {
+            HSSFSeries series ;
+            
+            // Starts with one
+            assertEquals(1, chart.getSeries().length);
+
+            // Add two more
+            series = chart.createSeries() ;
+            series.setCategoryLabelsCellRange( new CellRangeAddress( 3, 4, 0, 0 ) ) ;
+            series.setValuesCellRange( new CellRangeAddress( 3, 4, 1, 1 ) ) ;
+
+            series = chart.createSeries() ;
+            series.setCategoryLabelsCellRange( new CellRangeAddress( 6, 7, 0, 0 ) ) ;
+            series.setValuesCellRange( new CellRangeAddress( 6, 7, 1, 1 ) ) ;
+        }
+        
+        // Save and re-check
+        wb = HSSFITestDataProvider.instance.writeOutAndReadBack(wb);
+        sheet = wb.getSheetAt( 1 ) ;
+        assertEquals(1, HSSFChart.getSheetCharts(sheet).length);
+        
+        HSSFChart c = HSSFChart.getSheetCharts(sheet)[0];
+        assertEquals(3, c.getSeries().length);
+    }
+
+    public void testExistingSheet1() throws Exception {
+       HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("49581.xls");
+        HSSFSheet sheet = wb.getSheetAt( 0 ) ;
+        HSSFChart[] charts = HSSFChart.getSheetCharts( sheet ) ;
+        
+        for ( HSSFChart chart : charts ) {
+            //System.out.println( chart.getType() ) ;
+            HSSFSeries[] seriesArray = chart.getSeries() ;
+            //System.out.println( "seriesArray.length=" + seriesArray.length ) ;
+            for ( HSSFSeries series : seriesArray )
+            {
+                //System.out.println( "serie.getNumValues()=" + series.getNumValues() ) ;
+                CellRangeAddressBase range ;
+
+                range = series.getValuesCellRange() ;
+                //System.out.println( range.toString() ) ;
+                range.setLastRow( range.getLastRow() + 1 ) ;
+                series.setValuesCellRange( range ) ;
+
+                range = series.getCategoryLabelsCellRange() ;
+                //System.out.println( range.toString() ) ;
+                range.setLastRow( range.getLastRow() + 1 ) ;
+                series.setCategoryLabelsCellRange( range ) ;
+            }
+
+            for ( int id = 0 ; id < 2 ; id++ )
+            {
+                HSSFSeries newSeries = chart.createSeries() ;
+                newSeries.setValuesCellRange( new CellRangeAddress( 1 + id, 4, 3, 3 ) ) ;
+                String oldSeriesTitle = newSeries.getSeriesTitle() ;
+                if ( oldSeriesTitle != null )
+                {
+                    //System.out.println( "old series title: " + oldSeriesTitle ) ;
+                    newSeries.setSeriesTitle( "new series" ) ;
+                }
+            }
+        }
+
+        HSSFChart chart = charts[ 2 ] ;
+        chart.removeSeries( chart.getSeries()[ 0 ] ) ;
+    }
 }
diff --git a/test-data/spreadsheet/49581.xls b/test-data/spreadsheet/49581.xls
new file mode 100644 (file)
index 0000000..d7fbf13
Binary files /dev/null and b/test-data/spreadsheet/49581.xls differ