1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.dispatcher;
23
24 import org.apache.struts2.ServletActionContext;
25 import com.opensymphony.xwork2.ActionInvocation;
26 import com.opensymphony.xwork2.Result;
27 import org.jfree.chart.ChartUtilities;
28 import org.jfree.chart.JFreeChart;
29
30 import java.io.OutputStream;
31
32 /***
33 * <!-- START SNIPPET: description -->
34 * <p/>
35 * A custom Result type for chart data. Built on top of
36 * <a href="http://www.jfree.org/jfreechart/" target="_blank">JFreeChart</a>. When executed
37 * this Result will write the given chart as a PNG or JPG to the servlet output stream.
38 * <p/>
39 * <!-- END SNIPPET: description -->
40 * <p/>
41 * <b>This result type takes the following parameters:</b>
42 * <p/>
43 * <!-- START SNIPPET: params -->
44 * <p/>
45 * <ul>
46 * <p/>
47 * <li><b>value</b> - the name of the JFreeChart object on the ValueStack, defaults to 'chart'.</li>
48 * <p/>
49 * <li><b>type</b> - the render type for this chart. Can be jpg (or jpeg) or png. Defaults to png.</li>
50 * <p/>
51 * <li><b>width (required)</b> - the width (in pixels) of the rendered chart.</li>
52 * <p/>
53 * <li><b>height (required)</b> - the height (in pixels) of the rendered chart.</li>
54 * <p/>
55 * </ul>
56 * <!-- END SNIPPET: params -->
57 * <p/>
58 * <b>Example:</b>
59 * <p/>
60 * <pre><!-- START SNIPPET: example -->
61 * public class ExampleChartAction extends ActionSupport {
62 *
63 * private JFreeChart chart;
64 *
65 * public String execute() throws Exception {
66 * // chart creation logic...
67 * XYSeries dataSeries = new XYSeries(new Integer(1)); // pass a key for this serie
68 * for (int i = 0; i <= 100; i++) {
69 * dataSeries.add(i, RandomUtils.nextInt());
70 * }
71 * XYSeriesCollection xyDataset = new XYSeriesCollection(dataSeries);
72 *
73 * ValueAxis xAxis = new NumberAxis("Raw Marks");
74 * ValueAxis yAxis = new NumberAxis("Moderated Marks");
75 *
76 * // set my chart variable
77 * chart =
78 * new JFreeChart( "Moderation Function", JFreeChart.DEFAULT_TITLE_FONT,
79 * new XYPlot( xyDataset, xAxis, yAxis, new StandardXYItemRenderer(StandardXYItemRenderer.LINES)),
80 * false);
81 * chart.setBackgroundPaint(java.awt.Color.white);
82 *
83 * return SUCCESS;
84 * }
85 *
86 * // this method will get called if we specify <param name="value">chart</param>
87 * public JFreeChart getChart() {
88 * return chart;
89 * }
90 * }
91 *
92 * <result name="success" type="chart">
93 * <param name="value">chart</param>
94 * <param name="type">png</param>
95 * <param name="width">640</param>
96 * <param name="height">480</param>
97 * </result>
98 * <!-- END SNIPPET: example --></pre>
99 */
100 public class ChartResult implements Result {
101
102 private static final long serialVersionUID = -6484761870055986612L;
103 private static final String DEFAULT_TYPE = "png";
104 private static final String DEFAULT_VALUE = "chart";
105
106 private JFreeChart chart;
107 private boolean chartSet;
108 Integer height, width;
109 String type = DEFAULT_TYPE;
110 String value = DEFAULT_VALUE;
111
112
113
114 public ChartResult() {
115 super();
116 }
117
118 public ChartResult(JFreeChart chart, int height, int width) {
119 this.chart = chart;
120 this.height = height;
121 this.width = width;
122 }
123
124
125
126 public Integer getHeight() {
127 return height;
128 }
129
130 public void setHeight(Integer height) {
131 this.height = height;
132 }
133
134 public Integer getWidth() {
135 return width;
136 }
137
138 public void setWidth(Integer width) {
139 this.width = width;
140 }
141
142 public String getType() {
143 return type;
144 }
145
146 public void setType(String type) {
147 this.type = type;
148 }
149
150 public String getValue() {
151 return value;
152 }
153
154 public void setValue(String value) {
155 this.value = value;
156 }
157
158 public JFreeChart getChart() {
159 return chart;
160 }
161
162 public void setChart(JFreeChart chart) {
163 this.chartSet = true;
164 this.chart = chart;
165 }
166
167
168
169
170
171 /***
172 * Executes the result. Writes the given chart as a PNG or JPG to the servlet output stream.
173 *
174 * @param invocation an encapsulation of the action execution state.
175 * @throws Exception if an error occurs when creating or writing the chart to the servlet output stream.
176 */
177 public void execute(ActionInvocation invocation) throws Exception {
178 if (!chartSet)
179 chart = (JFreeChart) invocation.getStack().findValue(value, JFreeChart.class);
180 if (chart == null)
181 throw new NullPointerException("No JFreeChart object found on the stack with name " + value);
182
183 if (height == null)
184 throw new NullPointerException("No height parameter was given.");
185 if (width == null)
186 throw new NullPointerException("No width parameter was given.");
187
188
189 OutputStream os = ServletActionContext.getResponse().getOutputStream();
190 try {
191
192 if ("png".equalsIgnoreCase(type))
193 ChartUtilities.writeChartAsPNG(os, chart, width, height);
194 else if ("jpg".equalsIgnoreCase(type) || "jpeg".equalsIgnoreCase(type))
195 ChartUtilities.writeChartAsJPEG(os, chart, width, height);
196 else
197 throw new IllegalArgumentException(type + " is not a supported render type (only JPG and PNG are).");
198 } finally {
199 if (os != null) os.flush();
200 }
201 }
202 }