franta-hg@1
|
1 |
/* ================================================================
|
franta-hg@1
|
2 |
* Cewolf : Chart enabling Web Objects Framework
|
franta-hg@1
|
3 |
* ================================================================
|
franta-hg@1
|
4 |
*
|
franta-hg@1
|
5 |
* Project Info: http://cewolf.sourceforge.net
|
franta-hg@1
|
6 |
* Project Lead: Guido Laures (guido@laures.de);
|
franta-hg@1
|
7 |
*
|
franta-hg@1
|
8 |
* (C) Copyright 2002, by Guido Laures
|
franta-hg@1
|
9 |
*
|
franta-hg@1
|
10 |
* This library is free software; you can redistribute it and/or modify it under the terms
|
franta-hg@1
|
11 |
* of the GNU Lesser General Public License as published by the Free Software Foundation;
|
franta-hg@1
|
12 |
* either version 2.1 of
|
franta-hg@1
|
13 |
* the License, or (at your option) any later version.
|
franta-hg@1
|
14 |
*
|
franta-hg@1
|
15 |
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
franta-hg@1
|
16 |
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
franta-hg@1
|
17 |
* See the GNU Lesser General Public License for more details.
|
franta-hg@1
|
18 |
*
|
franta-hg@1
|
19 |
* You should have received a copy of the GNU Lesser General Public License along with this
|
franta-hg@1
|
20 |
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
franta-hg@1
|
21 |
* Boston, MA 02111-1307, USA.
|
franta-hg@1
|
22 |
*/
|
franta-hg@1
|
23 |
|
franta-hg@1
|
24 |
package de.laures.cewolf.taglib;
|
franta-hg@1
|
25 |
|
franta-hg@1
|
26 |
import java.awt.Image;
|
franta-hg@1
|
27 |
import java.awt.Paint;
|
franta-hg@1
|
28 |
import java.io.Serializable;
|
franta-hg@1
|
29 |
import java.util.ArrayList;
|
franta-hg@1
|
30 |
import java.util.Iterator;
|
franta-hg@1
|
31 |
import java.util.List;
|
franta-hg@1
|
32 |
import java.util.Map;
|
franta-hg@1
|
33 |
|
franta-hg@1
|
34 |
import org.apache.commons.logging.Log;
|
franta-hg@1
|
35 |
import org.apache.commons.logging.LogFactory;
|
franta-hg@1
|
36 |
import org.jfree.chart.JFreeChart;
|
franta-hg@1
|
37 |
import org.jfree.chart.title.LegendTitle;
|
franta-hg@1
|
38 |
import org.jfree.ui.RectangleEdge;
|
franta-hg@1
|
39 |
|
franta-hg@1
|
40 |
import de.laures.cewolf.ChartHolder;
|
franta-hg@1
|
41 |
import de.laures.cewolf.ChartPostProcessor;
|
franta-hg@1
|
42 |
import de.laures.cewolf.ChartValidationException;
|
franta-hg@1
|
43 |
import de.laures.cewolf.DatasetProduceException;
|
franta-hg@1
|
44 |
import de.laures.cewolf.PostProcessingException;
|
franta-hg@1
|
45 |
import de.laures.cewolf.event.ChartImageRenderListener;
|
franta-hg@1
|
46 |
import de.laures.cewolf.util.ImageHelper;
|
franta-hg@1
|
47 |
import de.laures.cewolf.util.RenderedImage;
|
franta-hg@1
|
48 |
|
franta-hg@1
|
49 |
/**
|
franta-hg@1
|
50 |
* Serializable implementaton of a ChartDefinition.
|
franta-hg@1
|
51 |
* @author glaures
|
franta-hg@1
|
52 |
* @see de.laures.cewolf.ChartHolder
|
franta-hg@1
|
53 |
*/
|
franta-hg@1
|
54 |
public abstract class AbstractChartDefinition implements ChartHolder, Serializable, TaglibConstants, ChartImageRenderListener {
|
franta-hg@1
|
55 |
|
franta-hg@1
|
56 |
protected static Log log = LogFactory.getLog(AbstractChartDefinition.class);
|
franta-hg@1
|
57 |
|
franta-hg@1
|
58 |
protected String title;
|
franta-hg@1
|
59 |
protected String xAxisLabel;
|
franta-hg@1
|
60 |
protected String yAxisLabel;
|
franta-hg@1
|
61 |
protected String type;
|
franta-hg@1
|
62 |
|
franta-hg@1
|
63 |
private boolean antialias = true;
|
franta-hg@1
|
64 |
private String background;
|
franta-hg@1
|
65 |
private float backgroundImageAlpha = 1.0f;
|
franta-hg@1
|
66 |
private Paint paint;
|
franta-hg@1
|
67 |
|
franta-hg@1
|
68 |
private int legendAnchor = ANCHOR_SOUTH;
|
franta-hg@1
|
69 |
private boolean showLegend = true;
|
franta-hg@1
|
70 |
|
franta-hg@1
|
71 |
private transient List postProcessors = new ArrayList();
|
franta-hg@1
|
72 |
private List postProcessorsParams = new ArrayList();
|
franta-hg@1
|
73 |
|
franta-hg@1
|
74 |
private transient JFreeChart chart;
|
franta-hg@1
|
75 |
|
franta-hg@1
|
76 |
protected abstract JFreeChart produceChart() throws DatasetProduceException, ChartValidationException;
|
franta-hg@1
|
77 |
|
franta-hg@1
|
78 |
|
franta-hg@1
|
79 |
//gets first legend in the list
|
franta-hg@1
|
80 |
public LegendTitle getLegend()
|
franta-hg@1
|
81 |
{
|
franta-hg@1
|
82 |
//i need to find the legend now.
|
franta-hg@1
|
83 |
LegendTitle legend = null;
|
franta-hg@1
|
84 |
List subTitles = chart.getSubtitles();
|
franta-hg@1
|
85 |
Iterator iter = subTitles.iterator();
|
franta-hg@1
|
86 |
while (iter.hasNext())
|
franta-hg@1
|
87 |
{
|
franta-hg@1
|
88 |
Object o = iter.next();
|
franta-hg@1
|
89 |
if (o instanceof LegendTitle)
|
franta-hg@1
|
90 |
{
|
franta-hg@1
|
91 |
legend = (LegendTitle) o;
|
franta-hg@1
|
92 |
break;
|
franta-hg@1
|
93 |
}
|
franta-hg@1
|
94 |
}
|
franta-hg@1
|
95 |
return legend;
|
franta-hg@1
|
96 |
}
|
franta-hg@1
|
97 |
|
franta-hg@1
|
98 |
//removes first legend in the list
|
franta-hg@1
|
99 |
public void removeLegend()
|
franta-hg@1
|
100 |
{
|
franta-hg@1
|
101 |
List subTitles = chart.getSubtitles();
|
franta-hg@1
|
102 |
Iterator iter = subTitles.iterator();
|
franta-hg@1
|
103 |
while (iter.hasNext())
|
franta-hg@1
|
104 |
{
|
franta-hg@1
|
105 |
Object o = iter.next();
|
franta-hg@1
|
106 |
if (o instanceof LegendTitle)
|
franta-hg@1
|
107 |
{
|
franta-hg@1
|
108 |
iter.remove();
|
franta-hg@1
|
109 |
break;
|
franta-hg@1
|
110 |
}
|
franta-hg@1
|
111 |
}
|
franta-hg@1
|
112 |
}
|
franta-hg@1
|
113 |
|
franta-hg@1
|
114 |
/**
|
franta-hg@1
|
115 |
* This method triggers the dataset and chart production. It is only
|
franta-hg@1
|
116 |
* from outside if there is no cached image available in the the
|
franta-hg@1
|
117 |
* image cache.
|
franta-hg@1
|
118 |
*/
|
franta-hg@1
|
119 |
public Object getChart() throws DatasetProduceException, ChartValidationException, PostProcessingException {
|
franta-hg@1
|
120 |
if (chart == null) {
|
franta-hg@1
|
121 |
chart = produceChart();
|
franta-hg@1
|
122 |
chart.setAntiAlias(antialias);
|
franta-hg@1
|
123 |
if (background != null) {
|
franta-hg@1
|
124 |
Image image = ImageHelper.loadImage(background);
|
franta-hg@1
|
125 |
chart.setBackgroundImage(image);
|
franta-hg@1
|
126 |
chart.setBackgroundImageAlpha(backgroundImageAlpha);
|
franta-hg@1
|
127 |
}
|
franta-hg@1
|
128 |
if (paint != null) {
|
franta-hg@1
|
129 |
chart.setBackgroundPaint(paint);
|
franta-hg@1
|
130 |
}
|
franta-hg@1
|
131 |
if (showLegend)
|
franta-hg@1
|
132 |
{
|
franta-hg@1
|
133 |
|
franta-hg@1
|
134 |
LegendTitle legend = this.getLegend();
|
franta-hg@1
|
135 |
switch (legendAnchor)
|
franta-hg@1
|
136 |
{
|
franta-hg@1
|
137 |
case ANCHOR_NORTH :
|
franta-hg@1
|
138 |
legend.setPosition(RectangleEdge.TOP);
|
franta-hg@1
|
139 |
break;
|
franta-hg@1
|
140 |
case ANCHOR_WEST :
|
franta-hg@1
|
141 |
legend.setPosition(RectangleEdge.RIGHT);
|
franta-hg@1
|
142 |
break;
|
franta-hg@1
|
143 |
case ANCHOR_EAST :
|
franta-hg@1
|
144 |
legend.setPosition(RectangleEdge.LEFT);
|
franta-hg@1
|
145 |
break;
|
franta-hg@1
|
146 |
default :
|
franta-hg@1
|
147 |
legend.setPosition(RectangleEdge.BOTTOM);
|
franta-hg@1
|
148 |
}
|
franta-hg@1
|
149 |
}
|
franta-hg@1
|
150 |
else
|
franta-hg@1
|
151 |
{
|
franta-hg@1
|
152 |
this.removeLegend();
|
franta-hg@1
|
153 |
}
|
franta-hg@1
|
154 |
// postProcessing
|
franta-hg@1
|
155 |
for (int i = 0; i < postProcessors.size(); i++) {
|
franta-hg@1
|
156 |
ChartPostProcessor pp = (ChartPostProcessor)postProcessors.get(i);
|
franta-hg@1
|
157 |
try {
|
franta-hg@1
|
158 |
pp.processChart(chart, (Map)postProcessorsParams.get(i));
|
franta-hg@1
|
159 |
} catch (Throwable t) {
|
franta-hg@1
|
160 |
log.error(t);
|
franta-hg@1
|
161 |
throw new PostProcessingException(t.getClass().getName() + " raised by post processor '" +
|
franta-hg@1
|
162 |
pp + "'.\nPost processing of this post processor " + "has been ignored.");
|
franta-hg@1
|
163 |
}
|
franta-hg@1
|
164 |
}
|
franta-hg@1
|
165 |
}
|
franta-hg@1
|
166 |
return chart;
|
franta-hg@1
|
167 |
}
|
franta-hg@1
|
168 |
|
franta-hg@1
|
169 |
/**
|
franta-hg@1
|
170 |
* Sets the antialias.
|
franta-hg@1
|
171 |
* @param antialias The antialias to set
|
franta-hg@1
|
172 |
*/
|
franta-hg@1
|
173 |
public void setAntialias(boolean antialias) {
|
franta-hg@1
|
174 |
this.antialias = antialias;
|
franta-hg@1
|
175 |
}
|
franta-hg@1
|
176 |
|
franta-hg@1
|
177 |
/**
|
franta-hg@1
|
178 |
* Sets the background.
|
franta-hg@1
|
179 |
* @param background The background to set
|
franta-hg@1
|
180 |
*/
|
franta-hg@1
|
181 |
public void setBackground(String background) {
|
franta-hg@1
|
182 |
this.background = background;
|
franta-hg@1
|
183 |
}
|
franta-hg@1
|
184 |
|
franta-hg@1
|
185 |
/**
|
franta-hg@1
|
186 |
* Sets the backgroundImageAlpha.
|
franta-hg@1
|
187 |
* @param backgroundImageAlpha The backgroundImageAlpha to set
|
franta-hg@1
|
188 |
*/
|
franta-hg@1
|
189 |
public void setBackgroundImageAlpha(float backgroundImageAlpha) {
|
franta-hg@1
|
190 |
this.backgroundImageAlpha = backgroundImageAlpha;
|
franta-hg@1
|
191 |
}
|
franta-hg@1
|
192 |
|
franta-hg@1
|
193 |
/**
|
franta-hg@1
|
194 |
* Sets the legendAnchor.
|
franta-hg@1
|
195 |
* @param legendAnchor The legendAnchor to set
|
franta-hg@1
|
196 |
*/
|
franta-hg@1
|
197 |
public void setLegendAnchor(int legendAnchor) {
|
franta-hg@1
|
198 |
this.legendAnchor = legendAnchor;
|
franta-hg@1
|
199 |
}
|
franta-hg@1
|
200 |
|
franta-hg@1
|
201 |
/**
|
franta-hg@1
|
202 |
* Sets the paint.
|
franta-hg@1
|
203 |
* @param paint The paint to set
|
franta-hg@1
|
204 |
*/
|
franta-hg@1
|
205 |
public void setPaint(Paint paint) {
|
franta-hg@1
|
206 |
this.paint = paint;
|
franta-hg@1
|
207 |
}
|
franta-hg@1
|
208 |
|
franta-hg@1
|
209 |
/**
|
franta-hg@1
|
210 |
* Sets the showLegend.
|
franta-hg@1
|
211 |
* @param showLegend The showLegend to set
|
franta-hg@1
|
212 |
*/
|
franta-hg@1
|
213 |
public void setShowLegend(boolean showLegend) {
|
franta-hg@1
|
214 |
this.showLegend = showLegend;
|
franta-hg@1
|
215 |
}
|
franta-hg@1
|
216 |
|
franta-hg@1
|
217 |
/**
|
franta-hg@1
|
218 |
* Sets the title.
|
franta-hg@1
|
219 |
* @param title The title to set
|
franta-hg@1
|
220 |
*/
|
franta-hg@1
|
221 |
public void setTitle(String title) {
|
franta-hg@1
|
222 |
this.title = title;
|
franta-hg@1
|
223 |
}
|
franta-hg@1
|
224 |
|
franta-hg@1
|
225 |
/**
|
franta-hg@1
|
226 |
* Sets the type.
|
franta-hg@1
|
227 |
* @param type The type to set
|
franta-hg@1
|
228 |
*/
|
franta-hg@1
|
229 |
public void setType(String type) {
|
franta-hg@1
|
230 |
this.type = type;
|
franta-hg@1
|
231 |
}
|
franta-hg@1
|
232 |
|
franta-hg@1
|
233 |
/**
|
franta-hg@1
|
234 |
* Sets the xAxisLabel.
|
franta-hg@1
|
235 |
* @param xAxisLabel The xAxisLabel to set
|
franta-hg@1
|
236 |
*/
|
franta-hg@1
|
237 |
public void setXAxisLabel(String xAxisLabel) {
|
franta-hg@1
|
238 |
this.xAxisLabel = xAxisLabel;
|
franta-hg@1
|
239 |
}
|
franta-hg@1
|
240 |
|
franta-hg@1
|
241 |
/**
|
franta-hg@1
|
242 |
* Sets the yAxisLabel.
|
franta-hg@1
|
243 |
* @param yAxisLabel The yAxisLabel to set
|
franta-hg@1
|
244 |
*/
|
franta-hg@1
|
245 |
public void setYAxisLabel(String yAxisLabel) {
|
franta-hg@1
|
246 |
this.yAxisLabel = yAxisLabel;
|
franta-hg@1
|
247 |
}
|
franta-hg@1
|
248 |
|
franta-hg@1
|
249 |
public void addPostProcessor(ChartPostProcessor pp) {
|
franta-hg@1
|
250 |
postProcessors.add(pp);
|
franta-hg@1
|
251 |
}
|
franta-hg@1
|
252 |
|
franta-hg@1
|
253 |
public void addPostProcessorParams(Map params) {
|
franta-hg@1
|
254 |
postProcessorsParams.add(params);
|
franta-hg@1
|
255 |
}
|
franta-hg@1
|
256 |
|
franta-hg@1
|
257 |
/**
|
franta-hg@1
|
258 |
* Callback right after a new image gets rendered.
|
franta-hg@1
|
259 |
* Implemented, so if postprocessors implement the ImageRenderListener interface
|
franta-hg@1
|
260 |
* then they will be called back also
|
franta-hg@1
|
261 |
*
|
franta-hg@1
|
262 |
* @param renderedImage The fresh image just got rendered
|
franta-hg@1
|
263 |
*/
|
franta-hg@1
|
264 |
public void onImageRendered (RenderedImage renderedImage) {
|
franta-hg@1
|
265 |
// if the postprocessor implements ImageRenderListener interface call it!
|
franta-hg@1
|
266 |
for (int i = 0; i < postProcessors.size(); i++) {
|
franta-hg@1
|
267 |
ChartPostProcessor pp = (ChartPostProcessor)postProcessors.get(i);
|
franta-hg@1
|
268 |
if (pp instanceof ChartImageRenderListener) {
|
franta-hg@1
|
269 |
((ChartImageRenderListener) pp).onImageRendered(renderedImage);
|
franta-hg@1
|
270 |
}
|
franta-hg@1
|
271 |
}
|
franta-hg@1
|
272 |
}
|
franta-hg@1
|
273 |
|
franta-hg@1
|
274 |
}
|