1 /*************************************************************************
2  *
3  *  The Contents of this file are made available subject to the terms of
4  *  the BSD license.
5  *
6  *  Copyright 2000, 2010 Oracle and/or its affiliates.
7  *  All rights reserved.
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
18  *     contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  *************************************************************************/
34 
35 // __________ Imports __________
36 
37 // base classes
38 import com.sun.star.uno.XInterface;
39 import com.sun.star.uno.UnoRuntime;
40 import com.sun.star.lang.*;
41 
42 // property access
43 import com.sun.star.beans.*;
44 
45 // application specific classes
46 import com.sun.star.chart.*;
47 import com.sun.star.drawing.*;
48 
49 import com.sun.star.table.CellRangeAddress;
50 import com.sun.star.table.XCellRange;
51 import com.sun.star.sheet.XCellRangeAddressable;
52 
53 import com.sun.star.frame.XModel;
54 import com.sun.star.frame.XController;
55 
56 import com.sun.star.util.XNumberFormatsSupplier;
57 import com.sun.star.util.XNumberFormats;
58 
59 // base graphics things
60 import com.sun.star.awt.Point;
61 import com.sun.star.awt.Size;
62 import com.sun.star.awt.Rectangle;
63 import com.sun.star.awt.FontWeight;
64 import com.sun.star.awt.FontRelief;
65 
66 // Exceptions
67 import com.sun.star.uno.Exception;
68 import com.sun.star.uno.RuntimeException;
69 import com.sun.star.beans.UnknownPropertyException;
70 import com.sun.star.lang.IndexOutOfBoundsException;
71 import com.sun.star.util.MalformedNumberFormatException;
72 
73 
74 // __________ Implementation __________
75 
76 /** Create a spreadsheet add some data and add a chart
77     @author Björn Milcke
78  */
79 public class ChartInCalc
80 {
81     // ____________________
82 
83     public static void main( String args[] )
84     {
85         Helper aHelper = new Helper( args );
86 
87         CalcHelper aCalcHelper = new CalcHelper( aHelper.createSpreadsheetDocument() );
88 
89         // insert a cell range with 4 columns and 24 rows filled with random numbers
90         XCellRange aRange = aCalcHelper.insertRandomRange( 4, 24 );
91         CellRangeAddress aRangeAddress = ((XCellRangeAddressable) UnoRuntime.queryInterface(
92             XCellRangeAddressable.class, aRange)).getRangeAddress();
93 
94         // change view to sheet containing the chart
95         aCalcHelper.raiseChartSheet();
96 
97         // the unit for measures is 1/100th of a millimeter
98         // position at (1cm, 1cm)
99         Point aPos    = new Point( 1000, 1000 );
100 
101         // size of the chart is 15cm x 9.271cm
102         Size  aExtent = new Size( 15000, 9271 );
103 
104         // insert a new chart into the "Chart" sheet of the
105         // spreadsheet document
106         XChartDocument aChartDoc = aCalcHelper.insertChart(
107             "ScatterChart",
108             aRangeAddress,
109             aPos,
110             aExtent,
111             "com.sun.star.chart.XYDiagram" );
112 
113         // instantiate test class with newly created chart
114         ChartInCalc aTest   = new ChartInCalc( aChartDoc );
115 
116         try
117         {
118             aTest.lockControllers();
119 
120             aTest.testDiagram();
121             aTest.testArea();
122             aTest.testWall();
123             aTest.testTitle();
124             aTest.testAxis();
125             aTest.testGrid();
126 
127             // show an intermediate state, ...
128             aTest.unlockControllers();
129             aTest.lockControllers();
130 
131             // ..., because the following takes a while:
132             // an internet URL has to be resolved
133             aTest.testDataRowProperties();
134             aTest.testDataPointProperties();
135 
136             aTest.unlockControllers();
137         }
138         catch( Exception ex )
139         {
140             System.out.println( "UNO Exception caught: " + ex );
141             System.out.println( "Message: " + ex.getMessage() );
142         }
143 
144         System.exit( 0 );
145     }
146 
147 
148     // ________________________________________
149 
150     public ChartInCalc( XChartDocument aChartDoc )
151     {
152         maChartDocument = aChartDoc;
153         maDiagram       = maChartDocument.getDiagram();
154     }
155 
156     // ____________________
157 
158     public void lockControllers()
159         throws RuntimeException
160     {
161         ((XModel) UnoRuntime.queryInterface( XModel.class, maChartDocument )).lockControllers();
162     }
163 
164     // ____________________
165 
166     public void unlockControllers()
167         throws RuntimeException
168     {
169         ((XModel) UnoRuntime.queryInterface( XModel.class, maChartDocument )).unlockControllers();
170     }
171 
172     // ____________________
173 
174     public void testDiagram()
175         throws RuntimeException, UnknownPropertyException, PropertyVetoException,
176                com.sun.star.lang.IllegalArgumentException, WrappedTargetException
177     {
178         XPropertySet aDiaProp = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, maDiagram );
179 
180         if( aDiaProp != null )
181         {
182             // change chart type
183             aDiaProp.setPropertyValue( "Lines", new Boolean( true ));
184 
185             // change attributes for all series
186             // set line width to 0.5mm
187             aDiaProp.setPropertyValue( "LineWidth",  new Integer( 50 ));
188         }
189     }
190 
191     // ____________________
192 
193     public void testDataRowProperties()
194         throws RuntimeException, UnknownPropertyException, PropertyVetoException,
195                com.sun.star.lang.IllegalArgumentException, WrappedTargetException
196     {
197         // change properties of the data series
198         try
199         {
200             XPropertySet aSeriesProp;
201             for( int i = 1; i <= 3; i++ )
202             {
203                 aSeriesProp = maDiagram.getDataRowProperties( i );
204                 aSeriesProp.setPropertyValue( "LineColor", new Integer(
205                                                   0x400000 * i +
206                                                   0x005000 * i +
207                                                   0x0000ff - 0x40 * i ));
208                 if( 1 == i )
209                 {
210                     StringBuffer sUrl = new StringBuffer("file:///");
211                     try {
212                         /* for use without net it's easier to load a local graphic */
213                         java.io.File sourceFile = new java.io.File("bullet.gif");
214                         sUrl.append(sourceFile.getCanonicalPath().replace('\\', '/'));
215                     } catch (java.io.IOException e) {
216                         sUrl = new StringBuffer("http://graphics.openoffice.org/chart/bullet1.gif");
217                     }
218 
219                     // set a bitmap via URL as symbol for the first series
220                     aSeriesProp.setPropertyValue( "SymbolType", new Integer( ChartSymbolType.BITMAPURL ));
221                     aSeriesProp.setPropertyValue( "SymbolBitmapURL", sUrl.toString() );
222                 }
223                 else
224                 {
225                     aSeriesProp.setPropertyValue( "SymbolType", new Integer( ChartSymbolType.SYMBOL1 ));
226                     aSeriesProp.setPropertyValue( "SymbolSize", new Size( 250, 250 ));
227                 }
228             }
229         }
230         catch( IndexOutOfBoundsException ex )
231         {
232             System.out.println( "Oops, there not enough series for setting properties: " + ex );
233         }
234     }
235 
236     // ____________________
237 
238     public void testDataPointProperties()
239         throws RuntimeException, UnknownPropertyException, PropertyVetoException,
240                com.sun.star.lang.IllegalArgumentException, WrappedTargetException
241     {
242         // set properties for a single data point
243         try
244         {
245             // determine the maximum value of the first series
246             int nMaxIndex = 0;
247 
248             XChartDataArray aDataArray = (XChartDataArray) UnoRuntime.queryInterface(
249                 XChartDataArray.class, maChartDocument.getData());
250             double aData[][] = aDataArray.getData();
251 
252             int i;
253             double fMax = aData[ 0 ][ 1 ];
254             for( i = 1; i < aData.length; i++ )
255             {
256                 if( aData[ i ][ 1 ] > fMax )
257                 {
258                     fMax = aData[ i ][ 1 ];
259                     nMaxIndex = i;
260                 }
261             }
262 
263             // first parameter is the index of the point, the second one is the series
264             XPropertySet aPointProp = maDiagram.getDataPointProperties( 0, 1 );
265 
266             // set a different, larger symbol
267             aPointProp.setPropertyValue( "SymbolType", new Integer( ChartSymbolType.SYMBOL6 ));
268             aPointProp.setPropertyValue( "SymbolSize", new Size( 600, 600 ));
269 
270             // add a label text with bold font, bordeaux red 14pt
271             aPointProp.setPropertyValue( "DataCaption", new Integer( ChartDataCaption.VALUE ));
272             aPointProp.setPropertyValue( "CharHeight",  new Float( 14.0 ));
273             aPointProp.setPropertyValue( "CharColor",   new Integer( 0x993366 ));
274             aPointProp.setPropertyValue( "CharWeight",  new Float( FontWeight.BOLD ));
275         }
276         catch( IndexOutOfBoundsException ex )
277         {
278             System.out.println( "Oops, there not enough data points or series for setting properties: " + ex );
279         }
280     }
281 
282     // ____________________
283 
284     public void testArea()
285         throws RuntimeException, UnknownPropertyException, PropertyVetoException,
286                com.sun.star.lang.IllegalArgumentException, WrappedTargetException
287     {
288         XPropertySet   aArea = maChartDocument.getArea();
289 
290         if( aArea != null )
291         {
292             // change background color of entire chart
293             aArea.setPropertyValue( "FillStyle", FillStyle.SOLID );
294             aArea.setPropertyValue( "FillColor", new Integer( 0xeeeeee ));
295         }
296     }
297 
298     // ____________________
299 
300     public void testWall()
301         throws RuntimeException, UnknownPropertyException, PropertyVetoException,
302                com.sun.star.lang.IllegalArgumentException, WrappedTargetException
303     {
304         XPropertySet aWall = ((X3DDisplay) UnoRuntime.queryInterface(
305                                   X3DDisplay.class, maDiagram )).getWall();
306 
307         // change background color of area
308         aWall.setPropertyValue( "FillStyle", FillStyle.SOLID );
309         aWall.setPropertyValue( "FillColor", new Integer( 0xcccccc ));
310     }
311 
312     // ____________________
313 
314     public void testTitle()
315         throws RuntimeException, UnknownPropertyException, PropertyVetoException,
316                com.sun.star.lang.IllegalArgumentException, WrappedTargetException
317     {
318         // change main title
319         XPropertySet aDocProp = (XPropertySet) UnoRuntime.queryInterface(
320             XPropertySet.class, maChartDocument );
321         aDocProp.setPropertyValue( "HasMainTitle", new Boolean( true ));
322 
323         XShape aTitle = maChartDocument.getTitle();
324         XPropertySet aTitleProp = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, aTitle );
325 
326         // set new text
327         if( aTitleProp != null )
328         {
329             aTitleProp.setPropertyValue( "String", "Random Scatter Chart" );
330             aTitleProp.setPropertyValue( "CharHeight", new Float(14.0) );
331         }
332 
333         // align title with y axis
334         XShape aAxis = (XShape) UnoRuntime.queryInterface(
335             XShape.class, ((XAxisYSupplier) UnoRuntime.queryInterface(
336                 XAxisYSupplier.class, maDiagram )).getYAxis() );
337 
338         if( aAxis != null &&
339             aTitle != null )
340         {
341             Point aPos = aTitle.getPosition();
342             aPos.X = ( aAxis.getPosition() ).X;
343             aTitle.setPosition( aPos );
344         }
345     }
346 
347     // ____________________
348 
349     public void testAxis()
350         throws RuntimeException, UnknownPropertyException, PropertyVetoException,
351                com.sun.star.lang.IllegalArgumentException, WrappedTargetException,
352                MalformedNumberFormatException
353     {
354         // x axis
355         XPropertySet aAxisProp = ((XAxisXSupplier) UnoRuntime.queryInterface(
356                                       XAxisXSupplier.class, maDiagram )).getXAxis();
357         if( aAxisProp != null )
358         {
359             aAxisProp.setPropertyValue( "Max",      new Integer( 24 ));
360             aAxisProp.setPropertyValue( "StepMain", new Integer( 3 ));
361         }
362 
363         // change number format for y axis
364         aAxisProp = ((XAxisYSupplier) UnoRuntime.queryInterface(
365                          XAxisYSupplier.class, maDiagram )).getYAxis();
366 
367         // add a new custom number format and get the new key
368         int nNewNumberFormat = 0;
369         XNumberFormatsSupplier aNumFmtSupp = (XNumberFormatsSupplier) UnoRuntime.queryInterface(
370             XNumberFormatsSupplier.class, maChartDocument );
371 
372         if( aNumFmtSupp != null )
373         {
374             XNumberFormats aFormats = aNumFmtSupp.getNumberFormats();
375             Locale aLocale = new Locale( "de", "DE", "de" );
376 
377             String aFormatStr = aFormats.generateFormat( nNewNumberFormat, aLocale, true, true, (short)3, (short)1 );
378             nNewNumberFormat = aFormats.addNew( aFormatStr, aLocale );
379         }
380 
381         if( aAxisProp != null )
382         {
383             aAxisProp.setPropertyValue( "NumberFormat", new Integer( nNewNumberFormat ));
384         }
385     }
386 
387     // ____________________
388 
389     public void testGrid()
390         throws RuntimeException, UnknownPropertyException, PropertyVetoException,
391                com.sun.star.lang.IllegalArgumentException, WrappedTargetException
392     {
393         // y major grid
394         XPropertySet aGridProp = (XPropertySet) UnoRuntime.queryInterface(
395             XPropertySet.class,
396             ( (XAxisYSupplier) UnoRuntime.queryInterface(
397                 XAxisYSupplier.class, maDiagram )).getYMainGrid());
398 
399         if( aGridProp != null )
400         {
401             LineDash aDash = new LineDash();
402             aDash.Style    = DashStyle.ROUND;
403             aDash.Dots     = 2;
404             aDash.DotLen   = 10;
405             aDash.Dashes   = 1;
406             aDash.DashLen  = 200;
407             aDash.Distance = 100;
408 
409             aGridProp.setPropertyValue( "LineColor", new Integer( 0x999999 ));
410             aGridProp.setPropertyValue( "LineStyle", LineStyle.DASH );
411             aGridProp.setPropertyValue( "LineDash", aDash );
412             aGridProp.setPropertyValue( "LineWidth", new Integer( 30 ));
413         }
414     }
415 
416 
417     // ______________________________
418     //
419     // private members
420     // ______________________________
421 
422     private XChartDocument maChartDocument;
423     private XDiagram       maDiagram;
424 }
425