2087 |
17 Mar 06 |
nicklas |
1 |
/* |
2087 |
17 Mar 06 |
nicklas |
$Id$ |
2087 |
17 Mar 06 |
nicklas |
3 |
|
4889 |
06 Apr 09 |
nicklas |
Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg |
2087 |
17 Mar 06 |
nicklas |
5 |
|
2304 |
22 May 06 |
jari |
This file is part of BASE - BioArray Software Environment. |
2304 |
22 May 06 |
jari |
Available at http://base.thep.lu.se/ |
2087 |
17 Mar 06 |
nicklas |
8 |
|
2087 |
17 Mar 06 |
nicklas |
BASE is free software; you can redistribute it and/or |
2087 |
17 Mar 06 |
nicklas |
modify it under the terms of the GNU General Public License |
4479 |
05 Sep 08 |
jari |
as published by the Free Software Foundation; either version 3 |
2087 |
17 Mar 06 |
nicklas |
of the License, or (at your option) any later version. |
2087 |
17 Mar 06 |
nicklas |
13 |
|
2087 |
17 Mar 06 |
nicklas |
BASE is distributed in the hope that it will be useful, |
2087 |
17 Mar 06 |
nicklas |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
2087 |
17 Mar 06 |
nicklas |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2087 |
17 Mar 06 |
nicklas |
GNU General Public License for more details. |
2087 |
17 Mar 06 |
nicklas |
18 |
|
2087 |
17 Mar 06 |
nicklas |
You should have received a copy of the GNU General Public License |
4515 |
11 Sep 08 |
jari |
along with BASE. If not, see <http://www.gnu.org/licenses/>. |
2087 |
17 Mar 06 |
nicklas |
21 |
*/ |
2087 |
17 Mar 06 |
nicklas |
22 |
package net.sf.basedb.util.plot; |
2087 |
17 Mar 06 |
nicklas |
23 |
|
2137 |
31 Mar 06 |
nicklas |
24 |
import net.sf.basedb.core.BaseException; |
2087 |
17 Mar 06 |
nicklas |
25 |
import net.sf.basedb.core.query.SqlResult; |
2131 |
30 Mar 06 |
nicklas |
26 |
import net.sf.basedb.core.query.SqlResultIterator; |
4128 |
05 Feb 08 |
nicklas |
27 |
import net.sf.basedb.core.signal.ThreadSignalHandler; |
2087 |
17 Mar 06 |
nicklas |
28 |
|
2087 |
17 Mar 06 |
nicklas |
29 |
import org.jfree.chart.JFreeChart; |
2087 |
17 Mar 06 |
nicklas |
30 |
import org.jfree.chart.axis.NumberAxis; |
2131 |
30 Mar 06 |
nicklas |
31 |
import org.jfree.chart.plot.SeriesRenderingOrder; |
2087 |
17 Mar 06 |
nicklas |
32 |
import org.jfree.chart.plot.XYPlot; |
2087 |
17 Mar 06 |
nicklas |
33 |
import org.jfree.chart.renderer.xy.XYDotRenderer; |
2087 |
17 Mar 06 |
nicklas |
34 |
import org.jfree.data.xy.XYSeries; |
2087 |
17 Mar 06 |
nicklas |
35 |
import org.jfree.data.xy.XYSeriesCollection; |
2087 |
17 Mar 06 |
nicklas |
36 |
|
2087 |
17 Mar 06 |
nicklas |
37 |
import java.sql.SQLException; |
2137 |
31 Mar 06 |
nicklas |
38 |
import java.util.ArrayList; |
2137 |
31 Mar 06 |
nicklas |
39 |
import java.util.Collection; |
2137 |
31 Mar 06 |
nicklas |
40 |
import java.util.HashMap; |
2137 |
31 Mar 06 |
nicklas |
41 |
import java.util.List; |
2137 |
31 Mar 06 |
nicklas |
42 |
import java.util.Map; |
2087 |
17 Mar 06 |
nicklas |
43 |
|
2087 |
17 Mar 06 |
nicklas |
44 |
|
2087 |
17 Mar 06 |
nicklas |
45 |
/** |
2327 |
24 May 06 |
nicklas |
A simple plot utility for generating scatter plots without |
2327 |
24 May 06 |
nicklas |
the need to delve deep into the JFreePlot package. Note! This class |
2327 |
24 May 06 |
nicklas |
is experimental and it is likely that the implementation will change |
2327 |
24 May 06 |
nicklas |
in the future. |
2087 |
17 Mar 06 |
nicklas |
50 |
|
2087 |
17 Mar 06 |
nicklas |
@author Nicklas |
2087 |
17 Mar 06 |
nicklas |
@version 2.0 |
2087 |
17 Mar 06 |
nicklas |
@base.modified $Date$ |
2087 |
17 Mar 06 |
nicklas |
54 |
*/ |
2087 |
17 Mar 06 |
nicklas |
55 |
public class ScatterPlot |
2087 |
17 Mar 06 |
nicklas |
56 |
{ |
2087 |
17 Mar 06 |
nicklas |
57 |
|
2087 |
17 Mar 06 |
nicklas |
58 |
private XYPlot plot; |
2087 |
17 Mar 06 |
nicklas |
59 |
private XYSeriesCollection allSeries; |
2087 |
17 Mar 06 |
nicklas |
60 |
private JFreeChart chart; |
2087 |
17 Mar 06 |
nicklas |
61 |
|
2327 |
24 May 06 |
nicklas |
62 |
/** |
2327 |
24 May 06 |
nicklas |
Create a new ScatterPlot. |
2327 |
24 May 06 |
nicklas |
@param nameX The label on the X-axis |
2327 |
24 May 06 |
nicklas |
@param nameY The label on the Y-axis |
2327 |
24 May 06 |
nicklas |
66 |
*/ |
2087 |
17 Mar 06 |
nicklas |
67 |
public ScatterPlot(String nameX, String nameY) |
2087 |
17 Mar 06 |
nicklas |
68 |
{ |
2087 |
17 Mar 06 |
nicklas |
69 |
allSeries = new XYSeriesCollection(); |
2087 |
17 Mar 06 |
nicklas |
70 |
NumberAxis domainAxis = new NumberAxis(nameX); |
2087 |
17 Mar 06 |
nicklas |
71 |
domainAxis.setAutoRangeIncludesZero(false); |
2087 |
17 Mar 06 |
nicklas |
72 |
|
2087 |
17 Mar 06 |
nicklas |
73 |
NumberAxis rangeAxis = new NumberAxis(nameY); |
2087 |
17 Mar 06 |
nicklas |
74 |
rangeAxis.setAutoRangeIncludesZero(true); |
2087 |
17 Mar 06 |
nicklas |
75 |
|
2087 |
17 Mar 06 |
nicklas |
76 |
plot = new XYPlot(allSeries, domainAxis, rangeAxis, new XYDotRenderer()); |
2131 |
30 Mar 06 |
nicklas |
77 |
plot.setSeriesRenderingOrder(SeriesRenderingOrder.FORWARD); |
2087 |
17 Mar 06 |
nicklas |
78 |
chart = new JFreeChart(plot); |
2087 |
17 Mar 06 |
nicklas |
79 |
chart.setAntiAlias(false); |
2087 |
17 Mar 06 |
nicklas |
80 |
} |
2137 |
31 Mar 06 |
nicklas |
81 |
|
2327 |
24 May 06 |
nicklas |
82 |
/** |
2327 |
24 May 06 |
nicklas |
Add data to the plot. The <code>SqlResultIterator</code> should return |
2327 |
24 May 06 |
nicklas |
the x value as a float in the first position, ie. <code>data.getFloat(1)</code> |
2327 |
24 May 06 |
nicklas |
and y values in the positions 2 and up. |
2327 |
24 May 06 |
nicklas |
86 |
|
2327 |
24 May 06 |
nicklas |
@param data The data to plot |
2327 |
24 May 06 |
nicklas |
@param names An array of series names, x-value for series 'i' is found |
2327 |
24 May 06 |
nicklas |
in <code>data.getFloat(2+i)</code> |
2327 |
24 May 06 |
nicklas |
90 |
*/ |
2131 |
30 Mar 06 |
nicklas |
91 |
public void addData(SqlResultIterator data, String... names) |
2087 |
17 Mar 06 |
nicklas |
92 |
throws SQLException |
2087 |
17 Mar 06 |
nicklas |
93 |
{ |
2131 |
30 Mar 06 |
nicklas |
94 |
XYSeries[] series = new XYSeries[names.length]; |
2131 |
30 Mar 06 |
nicklas |
95 |
for (int i = 0; i < names.length; ++i) |
2131 |
30 Mar 06 |
nicklas |
96 |
{ |
2137 |
31 Mar 06 |
nicklas |
97 |
XYSeries s = new XYSeries(names[i]); |
2137 |
31 Mar 06 |
nicklas |
98 |
s.setNotify(false); |
2137 |
31 Mar 06 |
nicklas |
99 |
series[i] = s; |
2131 |
30 Mar 06 |
nicklas |
100 |
} |
2087 |
17 Mar 06 |
nicklas |
101 |
while (data.hasNext()) |
2087 |
17 Mar 06 |
nicklas |
102 |
{ |
4128 |
05 Feb 08 |
nicklas |
103 |
ThreadSignalHandler.checkInterrupted(); |
2087 |
17 Mar 06 |
nicklas |
104 |
SqlResult r = data.next(); |
2131 |
30 Mar 06 |
nicklas |
105 |
float x = r.getFloat(1); |
2131 |
30 Mar 06 |
nicklas |
106 |
for (int i = 0; i < series.length; ++i) |
2131 |
30 Mar 06 |
nicklas |
107 |
{ |
2131 |
30 Mar 06 |
nicklas |
108 |
series[i].add(x, r.getFloat(2+i)); |
2131 |
30 Mar 06 |
nicklas |
109 |
} |
2087 |
17 Mar 06 |
nicklas |
110 |
} |
2131 |
30 Mar 06 |
nicklas |
111 |
for (int i = 0; i < series.length; ++i) |
2131 |
30 Mar 06 |
nicklas |
112 |
{ |
2131 |
30 Mar 06 |
nicklas |
113 |
allSeries.addSeries(series[i]); |
2131 |
30 Mar 06 |
nicklas |
114 |
} |
2087 |
17 Mar 06 |
nicklas |
115 |
} |
2087 |
17 Mar 06 |
nicklas |
116 |
|
2327 |
24 May 06 |
nicklas |
117 |
/** |
2327 |
24 May 06 |
nicklas |
Add data to the plot. The SqlResultIterator must return at least 3 columns. |
2327 |
24 May 06 |
nicklas |
The first column in the result is used to determine which annotation/series |
2327 |
24 May 06 |
nicklas |
the spot belongs to. The second column is the x value and the third column |
2327 |
24 May 06 |
nicklas |
is the y value. Additional columns are not used. |
2327 |
24 May 06 |
nicklas |
<p> |
2327 |
24 May 06 |
nicklas |
The annotations collection contains the mappings from the actual value to |
2327 |
24 May 06 |
nicklas |
the annotation. Ie. if the result contains a 1 in the first column we |
2327 |
24 May 06 |
nicklas |
check which annotation returns a 1 in it's {@link PlotAnnotation#getValues()} |
2327 |
24 May 06 |
nicklas |
method. One value may not be used by more than one annotation. |
2327 |
24 May 06 |
nicklas |
127 |
|
2327 |
24 May 06 |
nicklas |
@param data The data to plot |
2327 |
24 May 06 |
nicklas |
@param annotations Annotation information that maps each data spot to |
2327 |
24 May 06 |
nicklas |
an annotation |
2327 |
24 May 06 |
nicklas |
131 |
*/ |
2137 |
31 Mar 06 |
nicklas |
132 |
public void addData(SqlResultIterator data, Collection<PlotAnnotation> annotations) |
2137 |
31 Mar 06 |
nicklas |
133 |
throws SQLException |
2137 |
31 Mar 06 |
nicklas |
134 |
{ |
2137 |
31 Mar 06 |
nicklas |
135 |
Map<Integer, XYSeries> series = new HashMap<Integer, XYSeries>(annotations.size()); |
2137 |
31 Mar 06 |
nicklas |
136 |
List<XYSeries> newSeries = new ArrayList<XYSeries>(annotations.size()); |
2137 |
31 Mar 06 |
nicklas |
137 |
for (PlotAnnotation pa : annotations) |
2137 |
31 Mar 06 |
nicklas |
138 |
{ |
2137 |
31 Mar 06 |
nicklas |
139 |
XYSeries s = new XYSeries(pa.getName()); |
2137 |
31 Mar 06 |
nicklas |
140 |
s.setNotify(false); |
2137 |
31 Mar 06 |
nicklas |
141 |
newSeries.add(s); |
2327 |
24 May 06 |
nicklas |
142 |
for (Integer value : pa.getValues()) |
2137 |
31 Mar 06 |
nicklas |
143 |
{ |
2327 |
24 May 06 |
nicklas |
144 |
if (series.containsKey(value)) |
2137 |
31 Mar 06 |
nicklas |
145 |
{ |
2327 |
24 May 06 |
nicklas |
146 |
throw new BaseException("Value " + value + " has already been mapped to another series"); |
2137 |
31 Mar 06 |
nicklas |
147 |
} |
2327 |
24 May 06 |
nicklas |
148 |
series.put(value, s); |
2137 |
31 Mar 06 |
nicklas |
149 |
} |
2137 |
31 Mar 06 |
nicklas |
150 |
} |
2137 |
31 Mar 06 |
nicklas |
151 |
while (data.hasNext()) |
2137 |
31 Mar 06 |
nicklas |
152 |
{ |
4128 |
05 Feb 08 |
nicklas |
153 |
ThreadSignalHandler.checkInterrupted(); |
2137 |
31 Mar 06 |
nicklas |
154 |
SqlResult r = data.next(); |
2137 |
31 Mar 06 |
nicklas |
155 |
XYSeries s = series.get(r.getInt(1)); |
2137 |
31 Mar 06 |
nicklas |
156 |
s.add(r.getFloat(2), r.getFloat(3)); |
2137 |
31 Mar 06 |
nicklas |
157 |
} |
2137 |
31 Mar 06 |
nicklas |
158 |
for (XYSeries s : newSeries) |
2137 |
31 Mar 06 |
nicklas |
159 |
{ |
2137 |
31 Mar 06 |
nicklas |
160 |
allSeries.addSeries(s); |
3015 |
11 Dec 06 |
nicklas |
161 |
plot.getRenderer().setSeriesVisibleInLegend(allSeries.getSeriesCount()-1, !s.getKey().equals("")); |
2137 |
31 Mar 06 |
nicklas |
162 |
} |
2137 |
31 Mar 06 |
nicklas |
163 |
} |
2137 |
31 Mar 06 |
nicklas |
164 |
|
2327 |
24 May 06 |
nicklas |
165 |
/** |
2327 |
24 May 06 |
nicklas |
Get the underlying JFreeChar object. Use this method to polish up |
2327 |
24 May 06 |
nicklas |
everything and save the image. |
2327 |
24 May 06 |
nicklas |
168 |
*/ |
2087 |
17 Mar 06 |
nicklas |
169 |
public JFreeChart getChart() |
2087 |
17 Mar 06 |
nicklas |
170 |
{ |
2087 |
17 Mar 06 |
nicklas |
171 |
return chart; |
2087 |
17 Mar 06 |
nicklas |
172 |
} |
2087 |
17 Mar 06 |
nicklas |
173 |
} |