KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pentaho > plugin > jfreechart > DialWidgetDefinition


1 /*
2  * Copyright 2006 Pentaho Corporation. All rights reserved.
3  * This software was developed by Pentaho Corporation and is provided under the terms
4  * of the Mozilla Public License, Version 1.1, or any later version. You may not use
5  * this file except in compliance with the license. If you need a copy of the license,
6  * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
7  * BI Platform. The Initial Developer is Pentaho Corporation.
8  *
9  * Software distributed under the Mozilla Public License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
11  * the license for the specific language governing your rights and limitations.
12  *
13  * @created Aug 15, 2005
14  * @author James Dixon
15  *
16  */

17
18 package org.pentaho.plugin.jfreechart;
19
20 import org.dom4j.Document;
21 import org.dom4j.Element;
22 import org.dom4j.Node;
23 import org.jfree.chart.plot.DialShape;
24 import org.jfree.chart.plot.MeterInterval;
25 import org.jfree.data.Range;
26 import org.jfree.ui.RectangleEdge;
27 import org.pentaho.core.connection.IPentahoResultSet;
28 import org.pentaho.core.connection.PentahoDataTransmuter;
29 import org.pentaho.core.session.IPentahoSession;
30
31 import java.awt.BasicStroke JavaDoc;
32 import java.awt.Color JavaDoc;
33 import java.awt.Font JavaDoc;
34 import java.awt.Image JavaDoc;
35 import java.awt.Paint JavaDoc;
36 import java.awt.Stroke JavaDoc;
37 import java.util.ArrayList JavaDoc;
38 import java.util.Iterator JavaDoc;
39 import java.util.List JavaDoc;
40
41 /**
42  * This class represents the definition of a dashboard dial. It holds:
43  * <ul>
44  * <li>The value to be displayed on the dial</li>
45  * <li>Minimum value of the dial</li>
46  * <li>Maximum value of the dial</li>
47  * <li>A list of intervals with the dial. Each interval specifies a minimum,
48  * maximum and information about how the interval should be painted.</li>
49  * <li>Painting information
50  * <ul>
51  * <li>Background paint</li>
52  * <li>Dial paint</li>
53  * <li>Needle paint</li>
54  * </ul>
55  * </ul>
56  *
57  * <p/> This class does not generate an image of the dial, it just defines the
58  * properties of the dial. <p/> Dial definitions are stored in xml documents in
59  * the solution folders with *.dial.xml extensions. These definition files store
60  * XML representations of all the settings here. Typically the value to be
61  * displayed is provided at runtime by a query or business rule, but the value
62  * can also read from the definition file. <p/> The definitions are read by
63  * org.pentaho.core.ui.component.DashboardWidgetComponent objects, which create
64  * instances of this object and set the properties defined here. <p/> The
65  * DashboardWidgetComponent objects pass this, now populated, object to
66  *
67  * The dial image is generated by
68  * {@link org.pentaho.core.ui.component.JFreeChartEngine} <p/>
69  *
70  * Example Dial <br/> <img SRC="doc-files/DialWidgetDefinition-1.png">
71  */

72 public class DialWidgetDefinition extends WidgetDefinition implements ChartDefinition {
73
74     /**
75      *
76      */

77     private static final long serialVersionUID = 2232742163326878608L;
78
79     private ArrayList JavaDoc intervals = new ArrayList JavaDoc();
80
81     private RectangleEdge titlePosition = RectangleEdge.TOP;
82
83     private Paint JavaDoc chartBackgroundPaint = Color.WHITE;
84
85     private Paint JavaDoc plotBackgroundPaint = Color.GRAY;
86
87     private Paint JavaDoc needlePaint = Color.blue;
88
89     private DialShape dialShape = DialShape.CHORD;
90
91     private Font JavaDoc titleFont;
92
93     private List JavaDoc subTitles = new ArrayList JavaDoc();
94
95     private boolean rangeLimited;
96
97     private int tickSize = 5;
98
99     private Paint JavaDoc tickPaint = Color.blue;
100
101     private Paint JavaDoc valuePaint = Color.BLUE;
102
103     private Font JavaDoc valueFont;
104     
105     private String JavaDoc units;
106     
107 // private IPentahoSession session;
108

109     public DialWidgetDefinition(double value, double minimum, double maximum, boolean rangeLimited) {
110         super(value, minimum, maximum);
111         this.rangeLimited = rangeLimited;
112     }
113     
114     public DialWidgetDefinition(IPentahoResultSet data, boolean byRow, Node chartAttributes, int width, int height, IPentahoSession session) {
115         this(0.0, Double.MIN_VALUE, Double.MAX_VALUE, false);
116
117         if (byRow) {
118             setDataByRow(data);
119         } else {
120             setDataByColumn(data);
121         }
122
123         createDial( this, chartAttributes, width, height, session );
124     }
125
126     public DialWidgetDefinition( Document document, double value, int width, int height, IPentahoSession session) {
127         this(value, Double.MIN_VALUE, Double.MAX_VALUE, false);
128
129         // get the dial node from the document
130
Node dialNode = document.selectSingleNode("//dial"); //$NON-NLS-1$
131

132         double min = 0;
133         double max = 100;
134         Node node = dialNode.selectSingleNode("range-limited"); //$NON-NLS-1$
135
rangeLimited = (node == null) || ("true".equalsIgnoreCase(node.getText())); //$NON-NLS-1$
136

137         if (!rangeLimited) {
138         } else {
139             max = 0.1;
140             double absValue = Math.abs(value);
141             // based on the current value, to to select some sensible min and
142
// max values
143
while (max < absValue) {
144                 max *= 2;
145                 if (max < absValue) {
146                     min *= 2.5;
147                     max *= 2.5;
148                 }
149                 if (max < absValue) {
150                     min *= 2;
151                     max *= 2;
152                 }
153             }
154             if (value > 0) {
155                 min = 0;
156             } else {
157                 min = -max;
158             }
159             setMaximum( max );
160             setMinimum( min );
161         }
162         // create the dial definition object
163
createDial( this, dialNode, width, height, session );
164     }
165     
166     /*
167      * public ThermometerWidgetDefinition createThermometer( Document doc ) { //
168      * TODO implement this to return a ThermometerWidgetDefinition object return
169      * null; }
170      */

171     /**
172      * Create a dial definition object from an XML document
173      *
174      * @param doc
175      * definition XML document
176      * @return Dial definition object
177      */

178     public static void createDial(DialWidgetDefinition widgetDefinition, Node dialNode, int width, int height, IPentahoSession session) {
179
180         Node node = dialNode.selectSingleNode("units"); //$NON-NLS-1$
181
if( node != null ) {
182             String JavaDoc units = node.getText();
183             widgetDefinition.setUnits( units );
184         }
185
186         // set the background Paint
187
Paint JavaDoc paint = JFreeChartEngine.getPaint(dialNode.selectSingleNode("background-color")); //$NON-NLS-1$
188
if (paint == null) {
189             Element backgroundNode = (Element) dialNode.selectSingleNode("chart-background"); //$NON-NLS-1$
190
if (backgroundNode != null) {
191                 String JavaDoc backgroundType = backgroundNode.attributeValue("type"); //$NON-NLS-1$
192
if ("texture".equals(backgroundType)) { //$NON-NLS-1$
193
paint = JFreeChartEngine.getTexturePaint(backgroundNode, width, height, session);
194                 } else if ("gradient".equals(backgroundType)) { //$NON-NLS-1$
195
paint = JFreeChartEngine.getGradientPaint(backgroundNode, width, height);
196                 }
197             }
198         }
199
200         if (paint != null) {
201             widgetDefinition.setChartBackgroundPaint(paint);
202         }
203
204         // set the dial background Paint
205
paint = JFreeChartEngine.getPaint(dialNode.selectSingleNode("plot-background-color")); //$NON-NLS-1$
206
if (paint == null) {
207             Element backgroundNode = (Element) dialNode.selectSingleNode("plot-background"); //$NON-NLS-1$
208
if (backgroundNode != null) {
209                 String JavaDoc backgroundType = backgroundNode.attributeValue("type"); //$NON-NLS-1$
210
if ("texture".equals(backgroundType)) { //$NON-NLS-1$
211
paint = JFreeChartEngine.getTexturePaint(backgroundNode, width, height, session);
212                 } else if ("gradient".equals(backgroundType)) { //$NON-NLS-1$
213
paint = JFreeChartEngine.getGradientPaint(backgroundNode, width, height);
214                 }
215             }
216         }
217         if (paint != null) {
218             widgetDefinition.setPlotBackgroundPaint(paint);
219         }
220
221         // set the needle Paint
222
paint = JFreeChartEngine.getPaint(dialNode.selectSingleNode("needle-color")); //$NON-NLS-1$
223
if (paint != null) {
224             widgetDefinition.setNeedlePaint(paint);
225         }
226
227         // set the tick Paint
228
paint = JFreeChartEngine.getPaint(dialNode.selectSingleNode("tick-color")); //$NON-NLS-1$
229
if (paint != null) {
230             widgetDefinition.setTickPaint(paint);
231         }
232
233         Node tmpNode = dialNode.selectSingleNode("tick-interval"); //$NON-NLS-1$
234
if (tmpNode != null) {
235             widgetDefinition.setTickSize(Integer.parseInt(dialNode.selectSingleNode("tick-interval").getText())); //$NON-NLS-1$
236
}
237
238         // set the value Paint
239
paint = JFreeChartEngine.getPaint(dialNode.selectSingleNode("value-color")); //$NON-NLS-1$
240
if (paint != null) {
241             widgetDefinition.setValuePaint(paint);
242         }
243
244         // TODO get this from the XML document
245
widgetDefinition.setDialShape(DialShape.CHORD);
246
247         Node titleFontNode = dialNode.selectSingleNode("title-font"); //$NON-NLS-1$
248
if (titleFontNode != null) {
249             String JavaDoc titleFontStr = titleFontNode.getText().trim();
250             if (!"".equals(titleFontStr)) { //$NON-NLS-1$
251
widgetDefinition.setTitleFont(new Font JavaDoc(titleFontStr, Font.ITALIC, 24));
252             }
253         }
254
255         Node valueFontNode = dialNode.selectSingleNode("title-font"); //$NON-NLS-1$
256
if (valueFontNode != null) {
257             String JavaDoc fontStr = valueFontNode.getText().trim();
258             if (!"".equals(fontStr)) { //$NON-NLS-1$
259
widgetDefinition.setValueFont(new Font JavaDoc(fontStr, Font.ITALIC, 24));
260             }
261         }
262
263         // set any intervals that are defined in the document
264
List JavaDoc intervals = dialNode.selectNodes("interval"); //$NON-NLS-1$
265
Iterator JavaDoc intervalIterator = intervals.iterator();
266         while (intervalIterator.hasNext()) {
267             // get the interval node
268
Node intervalNode = (Node) intervalIterator.next();
269
270             // get the interval name
271
String JavaDoc label = intervalNode.selectSingleNode("label").getText(); //$NON-NLS-1$
272

273             // get the range of the interval
274
double minimum = Double.parseDouble(intervalNode.selectSingleNode("minimum").getText()); //$NON-NLS-1$
275
double maximum = Double.parseDouble(intervalNode.selectSingleNode("maximum").getText()); //$NON-NLS-1$
276
Range range = new Range(minimum, maximum);
277
278             Paint JavaDoc backgroundPaint = JFreeChartEngine.getPaint(intervalNode.selectSingleNode("color")); //$NON-NLS-1$
279
if (backgroundPaint == null) {
280                 Element backgroundNode = (Element) intervalNode.selectSingleNode("interval-background"); //$NON-NLS-1$
281
if (backgroundNode != null) {
282                     String JavaDoc backgroundType = backgroundNode.attributeValue("type"); //$NON-NLS-1$
283
if ("texture".equals(backgroundType)) { //$NON-NLS-1$
284
backgroundPaint = JFreeChartEngine.getTexturePaint(backgroundNode, width, height, session);
285                     } else if ("gradient".equals(backgroundType)) { //$NON-NLS-1$
286
backgroundPaint = JFreeChartEngine.getGradientPaint(backgroundNode, width, height);
287                     }
288                 }
289             }
290
291             // get the text color of the interval
292
String JavaDoc textColor = intervalNode.selectSingleNode("text-color").getText(); //$NON-NLS-1$
293
Stroke JavaDoc outlineStroke;
294             if (intervalNode.selectSingleNode("stroke-width") != null) { //$NON-NLS-1$
295
outlineStroke = new BasicStroke JavaDoc(Float.parseFloat(intervalNode.selectSingleNode("stroke-width").getText())); //$NON-NLS-1$
296
} else {
297                 outlineStroke = new BasicStroke JavaDoc();
298             }
299             Paint JavaDoc outlinePaint = JFreeChartEngine.getPaint(textColor);
300
301             // create the interval object
302
MeterInterval interval = new MeterInterval(label, range, outlinePaint, outlineStroke, backgroundPaint);
303
304             // add the interval to the widget
305
widgetDefinition.addInterval(interval);
306         }
307
308     }
309
310     public void setUnits( String JavaDoc units ) {
311             this.units = units;
312     }
313
314     public String JavaDoc getUnits( ) {
315             return units;
316     }
317     
318     private void setDataByColumn(IPentahoResultSet data) {
319         setDataByRow(PentahoDataTransmuter.pivot(data));
320     }
321
322     private void setDataByRow(IPentahoResultSet data) {
323         Object JavaDoc[] rowData = data.next();
324         
325         double newValue = ((Number JavaDoc) rowData[0]).doubleValue();
326         double newMinimum = ((Number JavaDoc) rowData[1]).doubleValue();
327         double newMaximum = ((Number JavaDoc) rowData[2]).doubleValue();
328         this.setValue(newValue);
329         this.setMinimum(newMinimum);
330         this.setMaximum(newMaximum);
331     }
332
333     /**
334      * Add an interval (MeterInterval) to the dial definition. The interval
335      * defines a range and how it should be painted. <p/> The dial images here
336      * have three intervals. The lowest interval has a minimum of 0 and a
337      * maximum of 30. <p/> Intervals have a color. In this image the lowest
338      * interval color is set to red. <br/> <img
339      * SRC="doc-files/DialWidgetDefinition-5.png"> <p/> Intervals have a text
340      * color. In this image the lowest interval text color is set to red. This
341      * affects the outer rim, the interval value text <br/> <img
342      * SRC="doc-files/DialWidgetDefinition-6.png">
343      *
344      * @param interval
345      * A MeterInterval that defines an interval (range) on the dial
346      */

347     public void addInterval(MeterInterval interval) {
348         intervals.add(interval);
349         Range range = interval.getRange();
350         double min = range.getLowerBound();
351         double max = range.getUpperBound();
352         if (rangeLimited && intervals.size() == 1) {
353             setMinimum(min);
354             setMaximum(max);
355         } else {
356             if (min < getMinimum()) {
357                 setMinimum(min);
358             }
359             if (max > getMaximum()) {
360                 setMaximum(max);
361             }
362         }
363     }
364
365     /**
366      * Sets the value to be displayed on the dial image
367      *
368      * @param value
369      * The value to be displayed
370      */

371
372     public void setValue(double value) {
373         setValue(new Double JavaDoc(value));
374         if (rangeLimited) {
375             if (value < getMinimum()) {
376                 setValue(getMinimum());
377             } else if (value > getMaximum()) {
378                 setValue(getMaximum());
379             }
380         } else {
381             if (value < getMinimum()) {
382                 setMinimum(value);
383             } else if (value > getMaximum()) {
384                 setMaximum(value);
385             }
386         }
387     }
388
389     /**
390      * Return the java.awt.Paint object to be used to paint the backound of the
391      * dial.
392      *
393      * @return The Paint to be used
394      */

395     public Paint JavaDoc getPlotBackgroundPaint() {
396         return plotBackgroundPaint;
397     }
398
399     /**
400      * Return the java.awt.Paint object to be used to paint the backound of the
401      * dial. <p/> In this image the background paint has been set to red <br/>
402      * <img SRC="doc-files/DialWidgetDefinition-2.png">
403      *
404      * @return The Paint to used for the background of the image
405      */

406     public void setPlotBackgroundPaint(Paint JavaDoc plotBackgroundPaint) {
407         this.plotBackgroundPaint = plotBackgroundPaint;
408     }
409
410     /**
411      * Return the java.awt.Paint used to paint the needle of the dial image
412      *
413      * @return The Paint to use for the needle of this dial
414      */

415     public Paint JavaDoc getNeedlePaint() {
416         return needlePaint;
417     }
418
419     /**
420      * Sets the java.awt.Paint object to be used to paint the needle of the dial
421      * image. <p/> In this image the needle paint has been set to red. <br/>
422      * <img SRC="doc-files/DialWidgetDefinition-4.png">
423      *
424      * @param needlePaint
425      * The Paint to use for ths needle of this dial
426      */

427     public void setNeedlePaint(Paint JavaDoc needlePaint) {
428         this.needlePaint = needlePaint;
429     }
430
431     /**
432      * Return the shape to be used for the dial.
433      *
434      * @return DialShape The DialShape for this dial
435      */

436     public DialShape getDialShape() {
437         return dialShape;
438     }
439
440     /**
441      * Return the java.awt.Font to be used to display the dial title
442      *
443      * @return Font The Font for the title of this dial
444      */

445     public Font JavaDoc getTitleFont() {
446         if (titleFont != null) {
447             return titleFont;
448         } else {
449             return new Font JavaDoc("sans-serif", Font.PLAIN, 14); //$NON-NLS-1$
450
}
451     }
452
453     public void setTitleFont(Font JavaDoc tFont) {
454         titleFont = tFont;
455
456     }
457
458     /**
459      * Sets the shape to be used for the dial. This affects the area of dial
460      * outside the range that the needle covers. <table>
461      * <tr>
462      * <td><center>CIRCLE</center></td>
463      * <td><center>CHORD</center></td>
464      * <td><center>PIE</center></td>
465      * </tr>
466      * <tr>
467      * <td><img SRC="doc-files/DialWidgetDefinition-3.png"></td>
468      * <td><img SRC="doc-files/DialWidgetDefinition-8.png"></td>
469      * <td><img SRC="doc-files/DialWidgetDefinition-9.png"></td>
470      * </tr>
471      * </table>
472      *
473      * @param dialShape
474      * The shape for this dial
475      */

476     public void setDialShape(DialShape dialShape) {
477         this.dialShape = dialShape;
478     }
479
480     /**
481      * Return a list of the intervals for the dial. Each object in the list is a
482      * MeterInterval object.
483      *
484      * @return List The list of MeterInterval objects for this dial
485      */

486
487     public List JavaDoc getIntervals() {
488         return intervals;
489     }
490
491     public Paint JavaDoc[] getPaintSequence() {
492         return null;
493     }
494
495     public Image JavaDoc getPlotBackgroundImage() {
496         return null;
497     }
498
499     public List JavaDoc getSubtitles() {
500         return subTitles;
501     }
502
503     public Paint JavaDoc getChartBackgroundPaint() {
504         // TODO Auto-generated method stub
505
return chartBackgroundPaint;
506     }
507
508     public Image JavaDoc getChartBackgroundImage() {
509         // TODO Auto-generated method stub
510
return null;
511     }
512
513     public boolean isBorderVisible() {
514         // TODO Auto-generated method stub
515
return false;
516     }
517
518     public Paint JavaDoc getBorderPaint() {
519         // TODO Auto-generated method stub
520
return null;
521     }
522
523     public RectangleEdge getTitlePosition() {
524         return titlePosition;
525     }
526
527     /**
528      * @param chartBackgroundPaint
529      * The chartBackgroundPaint to set.
530      */

531     public void setChartBackgroundPaint(Paint JavaDoc chartBackgroundPaint) {
532         this.chartBackgroundPaint = chartBackgroundPaint;
533     }
534
535     public int getHeight() {
536         // TODO Auto-generated method stub
537
return 200;
538     }
539
540     public int getWidth() {
541         // TODO Auto-generated method stub
542
return 200;
543     }
544
545     public String JavaDoc getTitle() {
546         return null;
547     }
548
549     public boolean isLegendIncluded() {
550         // TODO Auto-generated method stub
551
return false;
552     }
553
554     public boolean isThreeD() {
555         // TODO Auto-generated method stub
556
return false;
557     }
558
559     public Paint JavaDoc getValuePaint() {
560         return valuePaint;
561     }
562
563     public Paint JavaDoc getTickPaint() {
564         return tickPaint;
565     }
566
567     public int getTickSize() {
568         return tickSize;
569     }
570
571     public void setValuePaint(Paint JavaDoc valuePaint) {
572         this.valuePaint = valuePaint;
573     }
574
575     public void setTickPaint(Paint JavaDoc tickPaint) {
576         this.tickPaint = tickPaint;
577     }
578
579     public void setTickSize(int tickSize) {
580         this.tickSize = tickSize;
581     }
582
583     public Font JavaDoc getValueFont() {
584         return valueFont;
585     }
586
587     public void setValueFont(Font JavaDoc valueFont) {
588         this.valueFont = valueFont;
589     }
590
591     public boolean isDisplayLabels() {
592         // TODO Auto-generated method stub
593
return false;
594     }
595 }
596
Popular Tags