Révision 19
tmp/org.txm.textsbalance.core/build.properties (revision 19) | ||
---|---|---|
1 |
source.. = src/ |
|
2 |
output.. = bin/ |
|
3 |
bin.includes = META-INF/,\ |
|
4 |
.,\ |
|
5 |
plugin.xml |
|
0 | 6 |
tmp/org.txm.textsbalance.core/plugin.xml (revision 19) | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<?eclipse version="3.4"?> |
|
3 |
<plugin> |
|
4 |
<extension |
|
5 |
point="org.eclipse.core.runtime.preferences"> |
|
6 |
<initializer |
|
7 |
class="org.txm.textsbalance.core.preferences.TextsBalancePreferences"> |
|
8 |
</initializer> |
|
9 |
</extension> |
|
10 |
<extension |
|
11 |
point="org.txm.chartsengine.chartcreator"> |
|
12 |
<ChartCreator |
|
13 |
chartsEngineName="jfreechart_charts_engine" |
|
14 |
class="org.txm.textsbalance.core.chartsengine.jfreechart.JFCBalanceSpiderChartCreator" |
|
15 |
fileNamePrefix="texts_balance"> |
|
16 |
</ChartCreator> |
|
17 |
<ChartCreator |
|
18 |
chartsEngineName="TMP_r_charts_engine" |
|
19 |
class="org.txm.textsbalance.core.chartsengine.r.RBalanceSpiderChartCreator" |
|
20 |
fileNamePrefix="texts_balance"> |
|
21 |
</ChartCreator> |
|
22 |
</extension> |
|
23 |
|
|
24 |
</plugin> |
|
0 | 25 |
tmp/org.txm.textsbalance.core/.settings/org.eclipse.jdt.core.prefs (revision 19) | ||
---|---|---|
1 |
eclipse.preferences.version=1 |
|
2 |
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled |
|
3 |
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 |
|
4 |
org.eclipse.jdt.core.compiler.compliance=1.6 |
|
5 |
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error |
|
6 |
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error |
|
7 |
org.eclipse.jdt.core.compiler.source=1.6 |
|
0 | 8 |
tmp/org.txm.textsbalance.core/.classpath (revision 19) | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<classpath> |
|
3 |
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> |
|
4 |
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> |
|
5 |
<classpathentry kind="src" path="src"/> |
|
6 |
<classpathentry kind="output" path="bin"/> |
|
7 |
</classpath> |
|
0 | 8 |
tmp/org.txm.textsbalance.core/META-INF/MANIFEST.MF (revision 19) | ||
---|---|---|
1 |
Manifest-Version: 1.0 |
|
2 |
Bundle-ManifestVersion: 2 |
|
3 |
Bundle-Name: Texts Balance TBX |
|
4 |
Bundle-SymbolicName: org.txm.textsbalance.core;singleton:=true |
|
5 |
Bundle-Version: 1.0.0.qualifier |
|
6 |
Bundle-RequiredExecutionEnvironment: JavaSE-1.6 |
|
7 |
Export-Package: org.txm.textsbalance.core.chartsengine.jfreechart, |
|
8 |
org.txm.textsbalance.core.chartsengine.r, |
|
9 |
org.txm.textsbalance.core.functions, |
|
10 |
org.txm.textsbalance.core.preferences |
|
11 |
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.10.0", |
|
12 |
org.txm.chartsengine.jfreechart.rcp;bundle-version="1.0.0", |
|
13 |
org.txm.chartsengine.r.rcp;bundle-version="1.0.0", |
|
14 |
org.txm.toolbox;bundle-version="0.7.0" |
|
15 |
Bundle-Vendor: TXM |
|
0 | 16 |
tmp/org.txm.textsbalance.core/.project (revision 19) | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<projectDescription> |
|
3 |
<name>org.txm.textsbalance.core</name> |
|
4 |
<comment></comment> |
|
5 |
<projects> |
|
6 |
</projects> |
|
7 |
<buildSpec> |
|
8 |
<buildCommand> |
|
9 |
<name>org.eclipse.jdt.core.javabuilder</name> |
|
10 |
<arguments> |
|
11 |
</arguments> |
|
12 |
</buildCommand> |
|
13 |
<buildCommand> |
|
14 |
<name>org.eclipse.pde.ManifestBuilder</name> |
|
15 |
<arguments> |
|
16 |
</arguments> |
|
17 |
</buildCommand> |
|
18 |
<buildCommand> |
|
19 |
<name>org.eclipse.pde.SchemaBuilder</name> |
|
20 |
<arguments> |
|
21 |
</arguments> |
|
22 |
</buildCommand> |
|
23 |
</buildSpec> |
|
24 |
<natures> |
|
25 |
<nature>org.eclipse.pde.PluginNature</nature> |
|
26 |
<nature>org.eclipse.jdt.core.javanature</nature> |
|
27 |
</natures> |
|
28 |
</projectDescription> |
|
0 | 29 |
tmp/org.txm.textsbalance.core/src/org/txm/textsbalance/core/chartsengine/jfreechart/MultipleSpiderWebPlot.java (revision 19) | ||
---|---|---|
1 |
/* =========================================================== |
|
2 |
* JFreeChart : a free chart library for the Java(tm) platform |
|
3 |
* =========================================================== |
|
4 |
* |
|
5 |
* (C) Copyright 2000-2013, by Object Refinery Limited and Contributors. |
|
6 |
* |
|
7 |
* Project Info: http://www.jfree.org/jfreechart/index.html |
|
8 |
* |
|
9 |
* This library is free software; you can redistribute it and/or modify it |
|
10 |
* under the terms of the GNU Lesser General Public License as published by |
|
11 |
* the Free Software Foundation; either version 2.1 of the License, or |
|
12 |
* (at your option) any later version. |
|
13 |
* |
|
14 |
* This library is distributed in the hope that it will be useful, but |
|
15 |
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|
16 |
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
|
17 |
* License for more details. |
|
18 |
* |
|
19 |
* You should have received a copy of the GNU Lesser General Public |
|
20 |
* License along with this library; if not, write to the Free Software |
|
21 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
|
22 |
* USA. |
|
23 |
* |
|
24 |
* [Oracle and Java are registered trademarks of Oracle and/or its affiliates. |
|
25 |
* Other names may be trademarks of their respective owners.] |
|
26 |
* |
|
27 |
* -------------------- |
|
28 |
* MultipleSpiderWebPlot.java |
|
29 |
* -------------------- |
|
30 |
* (C) Copyright 2004-2013, by Object Refinery Limited. |
|
31 |
* |
|
32 |
* Original Author: David Gilbert (for Object Refinery Limited); |
|
33 |
* Contributor(s): Brian Cabana (patch 1943021); |
|
34 |
* |
|
35 |
* Changes |
|
36 |
* ------- |
|
37 |
* 29-Jan-2004 : Version 1 (DG); |
|
38 |
* 31-Mar-2004 : Added setPieIndex() call during drawing (DG); |
|
39 |
* 20-Apr-2005 : Small change for update to LegendItem constructors (DG); |
|
40 |
* 05-May-2005 : Updated draw() method parameters (DG); |
|
41 |
* 16-Jun-2005 : Added get/setDataset() and equals() methods (DG); |
|
42 |
* ------------- JFREECHART 1.0.x --------------------------------------------- |
|
43 |
* 06-Apr-2006 : Fixed bug 1190647 - legend and section colors not consistent |
|
44 |
* when aggregation limit is specified (DG); |
|
45 |
* 27-Sep-2006 : Updated draw() method for deprecated code (DG); |
|
46 |
* 17-Jan-2007 : Updated prefetchSectionPaints() to check settings in |
|
47 |
* underlying SpiderWebPlot (DG); |
|
48 |
* 17-May-2007 : Added argument check to setPieChart() (DG); |
|
49 |
* 18-May-2007 : Set dataset for LegendItem (DG); |
|
50 |
* 18-Apr-2008 : In the constructor, register the plot as a dataset listener - |
|
51 |
* see patch 1943021 from Brian Cabana (DG); |
|
52 |
* 30-Dec-2008 : Added legendItemShape field, and fixed cloning bug (DG); |
|
53 |
* 09-Jan-2009 : See ignoreNullValues to true for sub-chart (DG); |
|
54 |
* 01-Jun-2009 : Set series key in getLegendItems() (DG); |
|
55 |
* 03-Jul-2013 : Use ParamChecks (DG); |
|
56 |
* |
|
57 |
*/ |
|
58 |
|
|
59 |
package org.txm.textsbalance.core.chartsengine.jfreechart; |
|
60 |
|
|
61 |
import java.awt.Color; |
|
62 |
import java.awt.Font; |
|
63 |
import java.awt.Graphics2D; |
|
64 |
import java.awt.Paint; |
|
65 |
import java.awt.Rectangle; |
|
66 |
import java.awt.Shape; |
|
67 |
import java.awt.geom.Ellipse2D; |
|
68 |
import java.awt.geom.Point2D; |
|
69 |
import java.awt.geom.Rectangle2D; |
|
70 |
import java.io.IOException; |
|
71 |
import java.io.ObjectInputStream; |
|
72 |
import java.io.ObjectOutputStream; |
|
73 |
import java.io.Serializable; |
|
74 |
import java.util.HashMap; |
|
75 |
import java.util.Iterator; |
|
76 |
import java.util.List; |
|
77 |
import java.util.Map; |
|
78 |
|
|
79 |
import org.jfree.chart.ChartRenderingInfo; |
|
80 |
import org.jfree.chart.JFreeChart; |
|
81 |
import org.jfree.chart.LegendItem; |
|
82 |
import org.jfree.chart.LegendItemCollection; |
|
83 |
import org.jfree.chart.event.PlotChangeEvent; |
|
84 |
import org.jfree.chart.plot.Plot; |
|
85 |
import org.jfree.chart.plot.PlotRenderingInfo; |
|
86 |
import org.jfree.chart.plot.PlotState; |
|
87 |
import org.jfree.chart.plot.SpiderWebPlot; |
|
88 |
import org.jfree.chart.title.TextTitle; |
|
89 |
import org.jfree.chart.util.ParamChecks; |
|
90 |
import org.jfree.data.category.CategoryDataset; |
|
91 |
import org.jfree.data.category.CategoryToPieDataset; |
|
92 |
import org.jfree.data.category.DefaultCategoryDataset; |
|
93 |
import org.jfree.data.general.DatasetChangeEvent; |
|
94 |
import org.jfree.data.general.DatasetUtilities; |
|
95 |
import org.jfree.data.general.PieDataset; |
|
96 |
import org.jfree.io.SerialUtilities; |
|
97 |
import org.jfree.ui.RectangleEdge; |
|
98 |
import org.jfree.ui.RectangleInsets; |
|
99 |
import org.jfree.util.ObjectUtilities; |
|
100 |
import org.jfree.util.PaintUtilities; |
|
101 |
import org.jfree.util.ShapeUtilities; |
|
102 |
import org.jfree.util.TableOrder; |
|
103 |
|
|
104 |
/** |
|
105 |
* A plot that displays multiple pie plots using data from a |
|
106 |
* {@link CategoryDataset}. |
|
107 |
*/ |
|
108 |
public class MultipleSpiderWebPlot extends Plot implements Cloneable, Serializable { |
|
109 |
|
|
110 |
/** The chart object that draws the individual pie charts. */ |
|
111 |
private JFreeChart spiderChart; |
|
112 |
|
|
113 |
/** The dataset. */ |
|
114 |
private DefaultCategoryDataset dataset; |
|
115 |
|
|
116 |
/** The data extract order (by row or by column). */ |
|
117 |
private TableOrder dataExtractOrder; |
|
118 |
|
|
119 |
/** The pie section limit percentage. */ |
|
120 |
private double limit = 0.0; |
|
121 |
|
|
122 |
/** |
|
123 |
* The key for the aggregated items. |
|
124 |
* |
|
125 |
* @since 1.0.2 |
|
126 |
*/ |
|
127 |
private Comparable aggregatedItemsKey; |
|
128 |
|
|
129 |
/** |
|
130 |
* The paint for the aggregated items. |
|
131 |
* |
|
132 |
* @since 1.0.2 |
|
133 |
*/ |
|
134 |
private transient Paint aggregatedItemsPaint; |
|
135 |
|
|
136 |
/** |
|
137 |
* The colors to use for each section. |
|
138 |
* |
|
139 |
* @since 1.0.2 |
|
140 |
*/ |
|
141 |
private transient Map sectionPaints; |
|
142 |
|
|
143 |
/** |
|
144 |
* The legend item shape (never null). |
|
145 |
* |
|
146 |
* @since 1.0.12 |
|
147 |
*/ |
|
148 |
private transient Shape legendItemShape; |
|
149 |
|
|
150 |
/** |
|
151 |
* Creates a new plot with no data. |
|
152 |
*/ |
|
153 |
public MultipleSpiderWebPlot() { |
|
154 |
this(null); |
|
155 |
} |
|
156 |
|
|
157 |
/** |
|
158 |
* Creates a new plot. |
|
159 |
* |
|
160 |
* @param dataset the dataset (<code>null</code> permitted). |
|
161 |
*/ |
|
162 |
public MultipleSpiderWebPlot(DefaultCategoryDataset dataset) { |
|
163 |
super(); |
|
164 |
setDataset(dataset); |
|
165 |
SpiderWebPlot piePlot = new SpiderWebPlot(null); |
|
166 |
this.spiderChart = new JFreeChart(piePlot); |
|
167 |
this.spiderChart.removeLegend(); |
|
168 |
this.dataExtractOrder = TableOrder.BY_COLUMN; |
|
169 |
this.spiderChart.setBackgroundPaint(null); |
|
170 |
TextTitle seriesTitle = new TextTitle("Series Title", |
|
171 |
new Font("SansSerif", Font.BOLD, 12)); |
|
172 |
seriesTitle.setPosition(RectangleEdge.BOTTOM); |
|
173 |
this.spiderChart.setTitle(seriesTitle); |
|
174 |
this.aggregatedItemsKey = "Other"; |
|
175 |
this.aggregatedItemsPaint = Color.lightGray; |
|
176 |
this.sectionPaints = new HashMap(); |
|
177 |
this.legendItemShape = new Ellipse2D.Double(-4.0, -4.0, 8.0, 8.0); |
|
178 |
} |
|
179 |
|
|
180 |
/** |
|
181 |
* Returns the dataset used by the plot. |
|
182 |
* |
|
183 |
* @return The dataset (possibly <code>null</code>). |
|
184 |
*/ |
|
185 |
public CategoryDataset getDataset() { |
|
186 |
return this.dataset; |
|
187 |
} |
|
188 |
|
|
189 |
/** |
|
190 |
* Sets the dataset used by the plot and sends a {@link PlotChangeEvent} |
|
191 |
* to all registered listeners. |
|
192 |
* |
|
193 |
* @param dataset the dataset (<code>null</code> permitted). |
|
194 |
*/ |
|
195 |
public void setDataset(DefaultCategoryDataset dataset) { |
|
196 |
// if there is an existing dataset, remove the plot from the list of |
|
197 |
// change listeners... |
|
198 |
if (this.dataset != null) { |
|
199 |
this.dataset.removeChangeListener(this); |
|
200 |
} |
|
201 |
|
|
202 |
// set the new dataset, and register the chart as a change listener... |
|
203 |
this.dataset = dataset; |
|
204 |
if (dataset != null) { |
|
205 |
setDatasetGroup(dataset.getGroup()); |
|
206 |
dataset.addChangeListener(this); |
|
207 |
} |
|
208 |
|
|
209 |
// send a dataset change event to self to trigger plot change event |
|
210 |
datasetChanged(new DatasetChangeEvent(this, dataset)); |
|
211 |
} |
|
212 |
|
|
213 |
/** |
|
214 |
* Returns the pie chart that is used to draw the individual pie plots. |
|
215 |
* Note that there are some attributes on this chart instance that will |
|
216 |
* be ignored at rendering time (for example, legend item settings). |
|
217 |
* |
|
218 |
* @return The pie chart (never <code>null</code>). |
|
219 |
* |
|
220 |
* @see #setPieChart(JFreeChart) |
|
221 |
*/ |
|
222 |
public JFreeChart getPieChart() { |
|
223 |
return this.spiderChart; |
|
224 |
} |
|
225 |
|
|
226 |
/** |
|
227 |
* Sets the chart that is used to draw the individual pie plots. The |
|
228 |
* chart's plot must be an instance of {@link SpiderWebPlot}. |
|
229 |
* |
|
230 |
* @param pieChart the pie chart (<code>null</code> not permitted). |
|
231 |
* |
|
232 |
* @see #getPieChart() |
|
233 |
*/ |
|
234 |
public void setPieChart(JFreeChart pieChart) { |
|
235 |
ParamChecks.nullNotPermitted(pieChart, "pieChart"); |
|
236 |
if (!(pieChart.getPlot() instanceof SpiderWebPlot)) { |
|
237 |
throw new IllegalArgumentException("The 'pieChart' argument must " |
|
238 |
+ "be a chart based on a SpiderWebPlot."); |
|
239 |
} |
|
240 |
this.spiderChart = pieChart; |
|
241 |
fireChangeEvent(); |
|
242 |
} |
|
243 |
|
|
244 |
/** |
|
245 |
* Returns the data extract order (by row or by column). |
|
246 |
* |
|
247 |
* @return The data extract order (never <code>null</code>). |
|
248 |
*/ |
|
249 |
public TableOrder getDataExtractOrder() { |
|
250 |
return this.dataExtractOrder; |
|
251 |
} |
|
252 |
|
|
253 |
/** |
|
254 |
* Sets the data extract order (by row or by column) and sends a |
|
255 |
* {@link PlotChangeEvent} to all registered listeners. |
|
256 |
* |
|
257 |
* @param order the order (<code>null</code> not permitted). |
|
258 |
*/ |
|
259 |
public void setDataExtractOrder(TableOrder order) { |
|
260 |
ParamChecks.nullNotPermitted(order, "order"); |
|
261 |
this.dataExtractOrder = order; |
|
262 |
fireChangeEvent(); |
|
263 |
} |
|
264 |
|
|
265 |
/** |
|
266 |
* Returns the limit (as a percentage) below which small pie sections are |
|
267 |
* aggregated. |
|
268 |
* |
|
269 |
* @return The limit percentage. |
|
270 |
*/ |
|
271 |
public double getLimit() { |
|
272 |
return this.limit; |
|
273 |
} |
|
274 |
|
|
275 |
/** |
|
276 |
* Sets the limit below which pie sections are aggregated. |
|
277 |
* Set this to 0.0 if you don't want any aggregation to occur. |
|
278 |
* |
|
279 |
* @param limit the limit percent. |
|
280 |
*/ |
|
281 |
public void setLimit(double limit) { |
|
282 |
this.limit = limit; |
|
283 |
fireChangeEvent(); |
|
284 |
} |
|
285 |
|
|
286 |
/** |
|
287 |
* Returns the key for aggregated items in the pie plots, if there are any. |
|
288 |
* The default value is "Other". |
|
289 |
* |
|
290 |
* @return The aggregated items key. |
|
291 |
* |
|
292 |
* @since 1.0.2 |
|
293 |
*/ |
|
294 |
public Comparable getAggregatedItemsKey() { |
|
295 |
return this.aggregatedItemsKey; |
|
296 |
} |
|
297 |
|
|
298 |
/** |
|
299 |
* Sets the key for aggregated items in the pie plots. You must ensure |
|
300 |
* that this doesn't clash with any keys in the dataset. |
|
301 |
* |
|
302 |
* @param key the key (<code>null</code> not permitted). |
|
303 |
* |
|
304 |
* @since 1.0.2 |
|
305 |
*/ |
|
306 |
public void setAggregatedItemsKey(Comparable key) { |
|
307 |
ParamChecks.nullNotPermitted(key, "key"); |
|
308 |
this.aggregatedItemsKey = key; |
|
309 |
fireChangeEvent(); |
|
310 |
} |
|
311 |
|
|
312 |
/** |
|
313 |
* Returns the paint used to draw the pie section representing the |
|
314 |
* aggregated items. The default value is <code>Color.lightGray</code>. |
|
315 |
* |
|
316 |
* @return The paint. |
|
317 |
* |
|
318 |
* @since 1.0.2 |
|
319 |
*/ |
|
320 |
public Paint getAggregatedItemsPaint() { |
|
321 |
return this.aggregatedItemsPaint; |
|
322 |
} |
|
323 |
|
|
324 |
/** |
|
325 |
* Sets the paint used to draw the pie section representing the aggregated |
|
326 |
* items and sends a {@link PlotChangeEvent} to all registered listeners. |
|
327 |
* |
|
328 |
* @param paint the paint (<code>null</code> not permitted). |
|
329 |
* |
|
330 |
* @since 1.0.2 |
|
331 |
*/ |
|
332 |
public void setAggregatedItemsPaint(Paint paint) { |
|
333 |
ParamChecks.nullNotPermitted(paint, "paint"); |
|
334 |
this.aggregatedItemsPaint = paint; |
|
335 |
fireChangeEvent(); |
|
336 |
} |
|
337 |
|
|
338 |
/** |
|
339 |
* Returns a short string describing the type of plot. |
|
340 |
* |
|
341 |
* @return The plot type. |
|
342 |
*/ |
|
343 |
@Override |
|
344 |
public String getPlotType() { |
|
345 |
return "Multiple Pie Plot"; |
|
346 |
// TODO: need to fetch this from localised resources |
|
347 |
} |
|
348 |
|
|
349 |
/** |
|
350 |
* Returns the shape used for legend items. |
|
351 |
* |
|
352 |
* @return The shape (never <code>null</code>). |
|
353 |
* |
|
354 |
* @see #setLegendItemShape(Shape) |
|
355 |
* |
|
356 |
* @since 1.0.12 |
|
357 |
*/ |
|
358 |
public Shape getLegendItemShape() { |
|
359 |
return this.legendItemShape; |
|
360 |
} |
|
361 |
|
|
362 |
/** |
|
363 |
* Sets the shape used for legend items and sends a {@link PlotChangeEvent} |
|
364 |
* to all registered listeners. |
|
365 |
* |
|
366 |
* @param shape the shape (<code>null</code> not permitted). |
|
367 |
* |
|
368 |
* @see #getLegendItemShape() |
|
369 |
* |
|
370 |
* @since 1.0.12 |
|
371 |
*/ |
|
372 |
public void setLegendItemShape(Shape shape) { |
|
373 |
ParamChecks.nullNotPermitted(shape, "shape"); |
|
374 |
this.legendItemShape = shape; |
|
375 |
fireChangeEvent(); |
|
376 |
} |
|
377 |
|
|
378 |
/** |
|
379 |
* Draws the plot on a Java 2D graphics device (such as the screen or a |
|
380 |
* printer). |
|
381 |
* |
|
382 |
* @param g2 the graphics device. |
|
383 |
* @param area the area within which the plot should be drawn. |
|
384 |
* @param anchor the anchor point (<code>null</code> permitted). |
|
385 |
* @param parentState the state from the parent plot, if there is one. |
|
386 |
* @param info collects info about the drawing. |
|
387 |
*/ |
|
388 |
@Override |
|
389 |
public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor, |
|
390 |
PlotState parentState, PlotRenderingInfo info) { |
|
391 |
|
|
392 |
// adjust the drawing area for the plot insets (if any)... |
|
393 |
RectangleInsets insets = getInsets(); |
|
394 |
insets.trim(area); |
|
395 |
drawBackground(g2, area); |
|
396 |
drawOutline(g2, area); |
|
397 |
|
|
398 |
// check that there is some data to display... |
|
399 |
if (DatasetUtilities.isEmptyOrNull(this.dataset)) { |
|
400 |
drawNoDataMessage(g2, area); |
|
401 |
return; |
|
402 |
} |
|
403 |
|
|
404 |
int pieCount; |
|
405 |
if (this.dataExtractOrder == TableOrder.BY_ROW) { |
|
406 |
pieCount = this.dataset.getRowCount(); |
|
407 |
} |
|
408 |
else { |
|
409 |
pieCount = this.dataset.getColumnCount(); |
|
410 |
} |
|
411 |
|
|
412 |
// the columns variable is always >= rows |
|
413 |
int displayCols = (int) Math.ceil(Math.sqrt(pieCount)); |
|
414 |
int displayRows |
|
415 |
= (int) Math.ceil((double) pieCount / (double) displayCols); |
|
416 |
|
|
417 |
// swap rows and columns to match plotArea shape |
|
418 |
if (displayCols > displayRows && area.getWidth() < area.getHeight()) { |
|
419 |
int temp = displayCols; |
|
420 |
displayCols = displayRows; |
|
421 |
displayRows = temp; |
|
422 |
} |
|
423 |
|
|
424 |
prefetchSectionPaints(); |
|
425 |
|
|
426 |
int x = (int) area.getX(); |
|
427 |
int y = (int) area.getY(); |
|
428 |
int width = ((int) area.getWidth()) / displayCols; |
|
429 |
int height = ((int) area.getHeight()) / displayRows; |
|
430 |
int row = 0; |
|
431 |
int column = 0; |
|
432 |
int diff = (displayRows * displayCols) - pieCount; |
|
433 |
int xoffset = 0; |
|
434 |
Rectangle rect = new Rectangle(); |
|
435 |
|
|
436 |
for (int pieIndex = 0; pieIndex < pieCount; pieIndex++) { |
|
437 |
rect.setBounds(x + xoffset + (width * column), y + (height * row), |
|
438 |
width, height); |
|
439 |
|
|
440 |
String title; |
|
441 |
if (this.dataExtractOrder == TableOrder.BY_ROW) { |
|
442 |
title = this.dataset.getRowKey(pieIndex).toString(); |
|
443 |
} |
|
444 |
else { |
|
445 |
title = this.dataset.getColumnKey(pieIndex).toString(); |
|
446 |
} |
|
447 |
this.spiderChart.setTitle(title); |
|
448 |
|
|
449 |
DefaultCategoryDataset piedataset = new DefaultCategoryDataset(); |
|
450 |
for (int irow = 0 ; irow < this.dataset.getRowCount() ; irow++) { |
|
451 |
this.dataset.getValue(irow, pieIndex); |
|
452 |
} |
|
453 |
|
|
454 |
SpiderWebPlot piePlot = (SpiderWebPlot) this.spiderChart.getPlot(); |
|
455 |
piePlot.setDataset(piedataset); |
|
456 |
|
|
457 |
|
|
458 |
ChartRenderingInfo subinfo = null; |
|
459 |
if (info != null) { |
|
460 |
subinfo = new ChartRenderingInfo(); |
|
461 |
} |
|
462 |
this.spiderChart.draw(g2, rect, subinfo); |
|
463 |
if (info != null) { |
|
464 |
assert subinfo != null; |
|
465 |
info.getOwner().getEntityCollection().addAll( |
|
466 |
subinfo.getEntityCollection()); |
|
467 |
info.addSubplotInfo(subinfo.getPlotInfo()); |
|
468 |
} |
|
469 |
|
|
470 |
++column; |
|
471 |
if (column == displayCols) { |
|
472 |
column = 0; |
|
473 |
++row; |
|
474 |
|
|
475 |
if (row == displayRows - 1 && diff != 0) { |
|
476 |
xoffset = (diff * width) / 2; |
|
477 |
} |
|
478 |
} |
|
479 |
} |
|
480 |
|
|
481 |
} |
|
482 |
|
|
483 |
/** |
|
484 |
* For each key in the dataset, check the <code>sectionPaints</code> |
|
485 |
* cache to see if a paint is associated with that key and, if not, |
|
486 |
* fetch one from the drawing supplier. These colors are cached so that |
|
487 |
* the legend and all the subplots use consistent colors. |
|
488 |
*/ |
|
489 |
private void prefetchSectionPaints() { |
|
490 |
|
|
491 |
// // pre-fetch the colors for each key...this is because the subplots |
|
492 |
// // may not display every key, but we need the coloring to be |
|
493 |
// // consistent... |
|
494 |
// |
|
495 |
// SpiderWebPlot piePlot = (SpiderWebPlot) getPieChart().getPlot(); |
|
496 |
// |
|
497 |
// if (this.dataExtractOrder == TableOrder.BY_ROW) { |
|
498 |
// // column keys provide potential keys for individual pies |
|
499 |
// for (int c = 0; c < this.dataset.getColumnCount(); c++) { |
|
500 |
// Comparable key = this.dataset.getColumnKey(c); |
|
501 |
// Paint p = piePlot.getSeriesPaint(key); |
|
502 |
// if (p == null) { |
|
503 |
// p = (Paint) this.sectionPaints.get(key); |
|
504 |
// if (p == null) { |
|
505 |
// p = getDrawingSupplier().getNextPaint(); |
|
506 |
// } |
|
507 |
// } |
|
508 |
// this.sectionPaints.put(key, p); |
|
509 |
// } |
|
510 |
// } |
|
511 |
// else { |
|
512 |
// // row keys provide potential keys for individual pies |
|
513 |
// for (int r = 0; r < this.dataset.getRowCount(); r++) { |
|
514 |
// Comparable key = this.dataset.getRowKey(r); |
|
515 |
// Paint p = piePlot.getSeriesPaint(key); |
|
516 |
// if (p == null) { |
|
517 |
// p = (Paint) this.sectionPaints.get(key); |
|
518 |
// if (p == null) { |
|
519 |
// p = getDrawingSupplier().getNextPaint(); |
|
520 |
// } |
|
521 |
// } |
|
522 |
// this.sectionPaints.put(key, p); |
|
523 |
// } |
|
524 |
// } |
|
525 |
|
|
526 |
} |
|
527 |
|
|
528 |
/** |
|
529 |
* Returns a collection of legend items for the pie chart. |
|
530 |
* |
|
531 |
* @return The legend items. |
|
532 |
*/ |
|
533 |
@Override |
|
534 |
public LegendItemCollection getLegendItems() { |
|
535 |
|
|
536 |
LegendItemCollection result = new LegendItemCollection(); |
|
537 |
if (this.dataset == null) { |
|
538 |
return result; |
|
539 |
} |
|
540 |
|
|
541 |
List keys = null; |
|
542 |
prefetchSectionPaints(); |
|
543 |
if (this.dataExtractOrder == TableOrder.BY_ROW) { |
|
544 |
keys = this.dataset.getColumnKeys(); |
|
545 |
} |
|
546 |
else if (this.dataExtractOrder == TableOrder.BY_COLUMN) { |
|
547 |
keys = this.dataset.getRowKeys(); |
|
548 |
} |
|
549 |
if (keys == null) { |
|
550 |
return result; |
|
551 |
} |
|
552 |
int section = 0; |
|
553 |
Iterator iterator = keys.iterator(); |
|
554 |
while (iterator.hasNext()) { |
|
555 |
Comparable key = (Comparable) iterator.next(); |
|
556 |
String label = key.toString(); // TODO: use a generator here |
|
557 |
String description = label; |
|
558 |
Paint paint = (Paint) this.sectionPaints.get(key); |
|
559 |
LegendItem item = new LegendItem(label, description, null, |
|
560 |
null, getLegendItemShape(), paint, |
|
561 |
Plot.DEFAULT_OUTLINE_STROKE, paint); |
|
562 |
item.setSeriesKey(key); |
|
563 |
item.setSeriesIndex(section); |
|
564 |
item.setDataset(getDataset()); |
|
565 |
result.add(item); |
|
566 |
section++; |
|
567 |
} |
|
568 |
if (this.limit > 0.0) { |
|
569 |
LegendItem a = new LegendItem(this.aggregatedItemsKey.toString(), |
|
570 |
this.aggregatedItemsKey.toString(), null, null, |
|
571 |
getLegendItemShape(), this.aggregatedItemsPaint, |
|
572 |
Plot.DEFAULT_OUTLINE_STROKE, this.aggregatedItemsPaint); |
|
573 |
result.add(a); |
|
574 |
} |
|
575 |
return result; |
|
576 |
} |
|
577 |
|
|
578 |
/** |
|
579 |
* Tests this plot for equality with an arbitrary object. Note that the |
|
580 |
* plot's dataset is not considered in the equality test. |
|
581 |
* |
|
582 |
* @param obj the object (<code>null</code> permitted). |
|
583 |
* |
|
584 |
* @return <code>true</code> if this plot is equal to <code>obj</code>, and |
|
585 |
* <code>false</code> otherwise. |
|
586 |
*/ |
|
587 |
@Override |
|
588 |
public boolean equals(Object obj) { |
|
589 |
if (obj == this) { |
|
590 |
return true; |
|
591 |
} |
|
592 |
if (!(obj instanceof MultipleSpiderWebPlot)) { |
|
593 |
return false; |
|
594 |
} |
|
595 |
MultipleSpiderWebPlot that = (MultipleSpiderWebPlot) obj; |
|
596 |
if (this.dataExtractOrder != that.dataExtractOrder) { |
|
597 |
return false; |
|
598 |
} |
|
599 |
if (this.limit != that.limit) { |
|
600 |
return false; |
|
601 |
} |
|
602 |
if (!this.aggregatedItemsKey.equals(that.aggregatedItemsKey)) { |
|
603 |
return false; |
|
604 |
} |
|
605 |
if (!PaintUtilities.equal(this.aggregatedItemsPaint, |
|
606 |
that.aggregatedItemsPaint)) { |
|
607 |
return false; |
|
608 |
} |
|
609 |
if (!ObjectUtilities.equal(this.spiderChart, that.spiderChart)) { |
|
610 |
return false; |
|
611 |
} |
|
612 |
if (!ShapeUtilities.equal(this.legendItemShape, that.legendItemShape)) { |
|
613 |
return false; |
|
614 |
} |
|
615 |
if (!super.equals(obj)) { |
|
616 |
return false; |
|
617 |
} |
|
618 |
return true; |
|
619 |
} |
|
620 |
|
|
621 |
/** |
|
622 |
* Returns a clone of the plot. |
|
623 |
* |
|
624 |
* @return A clone. |
|
625 |
* |
|
626 |
* @throws CloneNotSupportedException if some component of the plot does |
|
627 |
* not support cloning. |
|
628 |
*/ |
|
629 |
@Override |
|
630 |
public Object clone() throws CloneNotSupportedException { |
|
631 |
MultipleSpiderWebPlot clone = (MultipleSpiderWebPlot) super.clone(); |
|
632 |
clone.spiderChart = (JFreeChart) this.spiderChart.clone(); |
|
633 |
clone.sectionPaints = new HashMap(this.sectionPaints); |
|
634 |
clone.legendItemShape = ShapeUtilities.clone(this.legendItemShape); |
|
635 |
return clone; |
|
636 |
} |
|
637 |
|
|
638 |
/** |
|
639 |
* Provides serialization support. |
|
640 |
* |
|
641 |
* @param stream the output stream. |
|
642 |
* |
|
643 |
* @throws IOException if there is an I/O error. |
|
644 |
*/ |
|
645 |
private void writeObject(ObjectOutputStream stream) throws IOException { |
|
646 |
stream.defaultWriteObject(); |
|
647 |
SerialUtilities.writePaint(this.aggregatedItemsPaint, stream); |
|
648 |
SerialUtilities.writeShape(this.legendItemShape, stream); |
|
649 |
} |
|
650 |
|
|
651 |
/** |
|
652 |
* Provides serialization support. |
|
653 |
* |
|
654 |
* @param stream the input stream. |
|
655 |
* |
|
656 |
* @throws IOException if there is an I/O error. |
|
657 |
* @throws ClassNotFoundException if there is a classpath problem. |
|
658 |
*/ |
|
659 |
private void readObject(ObjectInputStream stream) |
|
660 |
throws IOException, ClassNotFoundException { |
|
661 |
stream.defaultReadObject(); |
|
662 |
this.aggregatedItemsPaint = SerialUtilities.readPaint(stream); |
|
663 |
this.legendItemShape = SerialUtilities.readShape(stream); |
|
664 |
this.sectionPaints = new HashMap(); |
|
665 |
} |
|
666 |
|
|
667 |
} |
|
0 | 668 |
tmp/org.txm.textsbalance.core/src/org/txm/textsbalance/core/chartsengine/jfreechart/JFCBalanceSpiderChartCreator.java (revision 19) | ||
---|---|---|
1 |
package org.txm.textsbalance.core.chartsengine.jfreechart; |
|
2 |
|
|
3 |
import java.util.HashMap; |
|
4 |
import java.util.Iterator; |
|
5 |
import java.util.Set; |
|
6 |
|
|
7 |
import org.jfree.chart.JFreeChart; |
|
8 |
import org.jfree.chart.labels.CategoryToolTipGenerator; |
|
9 |
import org.jfree.chart.plot.SpiderWebPlot; |
|
10 |
import org.jfree.data.category.CategoryDataset; |
|
11 |
import org.jfree.data.category.DefaultCategoryDataset; |
|
12 |
import org.txm.chartsengine.jfreechart.core.JFCChartCreator; |
|
13 |
import org.txm.chartsengine.jfreechart.core.themes.base.Theme; |
|
14 |
import org.txm.textsbalance.core.functions.TextsBalance; |
|
15 |
|
|
16 |
public class JFCBalanceSpiderChartCreator extends JFCChartCreator { |
|
17 |
|
|
18 |
public JFCBalanceSpiderChartCreator() { |
|
19 |
// TODO Auto-generated constructor stub |
|
20 |
} |
|
21 |
|
|
22 |
@Override |
|
23 |
public JFreeChart createChart(Object resultData, String preferencesNode) { |
|
24 |
|
|
25 |
final TextsBalance balance = (TextsBalance) resultData; |
|
26 |
|
|
27 |
HashMap<Integer, Comparable[]> data = balance.getDataset(); |
|
28 |
|
|
29 |
|
|
30 |
JFreeChart chart = null; |
|
31 |
|
|
32 |
DefaultCategoryDataset dataset = new DefaultCategoryDataset(); |
|
33 |
|
|
34 |
Set<Integer> keys = data.keySet(); |
|
35 |
Iterator<Integer> it = keys.iterator(); |
|
36 |
while (it.hasNext()){ |
|
37 |
int key = it.next(); |
|
38 |
Comparable[] value = data.get(key); |
|
39 |
dataset.addValue(key, value[0], value[1]); |
|
40 |
} |
|
41 |
|
|
42 |
|
|
43 |
SpiderWebPlot plot = new SpiderWebPlot(dataset); |
|
44 |
plot.setToolTipGenerator(new CategoryToolTipGenerator() { |
|
45 |
@Override |
|
46 |
public String generateToolTip(CategoryDataset dataset, int row, int col) { |
|
47 |
// FIXME: tests |
|
48 |
// System.out.println("JFCBalanceSpiderChartCreator.createChart(...).new CategoryToolTipGenerator() {...}.generateToolTip() row = " + row + " col = " + col); |
|
49 |
// System.out.println("JFCBalanceSpiderChartCreator.createChart(...).new CategoryToolTipGenerator() {...}.generateToolTip() " + dataset.getValue(row, col)); |
|
50 |
|
|
51 |
// if(balance.getValues().size() > col) { |
|
52 |
// balance.getValues().get(col); |
|
53 |
// } |
|
54 |
// return "error"; |
|
55 |
return String.valueOf(dataset.getValue(row, col).intValue()); |
|
56 |
} |
|
57 |
}); |
|
58 |
|
|
59 |
|
|
60 |
chart = new JFreeChart(plot); |
|
61 |
chart.setTitle("metadata = " + balance.getPropertyName() + ", N = " + balance.getValues().size() + ", fmin = " + balance.getFMin() + ", fmax = " + balance.getFMax()); |
|
62 |
|
|
63 |
// FIXME: tests |
|
64 |
//this.getChartsEngine().getTheme().apply(chart); |
|
65 |
this.getChartsEngine().getTheme().applyThemeToChart(chart, Theme.ITEMS_RENDERING_GRAYSCALE_MODE); |
|
66 |
|
|
67 |
return chart; |
|
68 |
|
|
69 |
} |
|
70 |
|
|
71 |
|
|
72 |
@Override |
|
73 |
public Class getResultDataType() { |
|
74 |
return TextsBalance.class; |
|
75 |
} |
|
76 |
|
|
77 |
|
|
78 |
|
|
79 |
|
|
80 |
|
|
81 |
|
|
82 |
|
|
83 |
} |
|
0 | 84 |
tmp/org.txm.textsbalance.core/src/org/txm/textsbalance/core/chartsengine/r/RBalanceSpiderChartCreator.java (revision 19) | ||
---|---|---|
1 |
package org.txm.textsbalance.core.chartsengine.r; |
|
2 |
|
|
3 |
import java.io.File; |
|
4 |
|
|
5 |
import org.rosuda.REngine.REXPMismatchException; |
|
6 |
import org.txm.chartsengine.core.ChartCreator; |
|
7 |
import org.txm.chartsengine.r.core.RChartsEngine; |
|
8 |
import org.txm.stat.StatException; |
|
9 |
import org.txm.stat.engine.r.RWorkspace; |
|
10 |
import org.txm.stat.engine.r.RWorkspaceException; |
|
11 |
import org.txm.textsbalance.core.functions.TextsBalance; |
|
12 |
|
|
13 |
public class RBalanceSpiderChartCreator extends ChartCreator { |
|
14 |
|
|
15 |
public RBalanceSpiderChartCreator() { |
|
16 |
// TODO Auto-generated constructor stub |
|
17 |
} |
|
18 |
|
|
19 |
@Override |
|
20 |
public Object createChart(Object resultData, String preferencesNode) { |
|
21 |
// TODO Auto-generated method stub |
|
22 |
return null; |
|
23 |
} |
|
24 |
|
|
25 |
@Override |
|
26 |
public File createChartFile(Object resultData, File file, String preferencesNode) { |
|
27 |
|
|
28 |
// try { |
|
29 |
|
|
30 |
|
|
31 |
// RWorkspace rw = RWorkspace.getRWorkspaceInstance(); |
|
32 |
// System.out.println("load wordcloud..."); |
|
33 |
// rw.eval("library(wordcloud)"); //$NON-NLS-1$ |
|
34 |
//System.out.println("tmpfreqs..."); |
|
35 |
// rw.addVectorToWorkspace("tmpfreqs", wordCloud.getFreqs()); //$NON-NLS-1$ |
|
36 |
//System.out.println("tmplabels..."); |
|
37 |
// rw.addVectorToWorkspace("tmplabels", wordCloud.getLabels()); //$NON-NLS-1$ |
|
38 |
|
|
39 |
//wordcloud(words,freq, |
|
40 |
// scale : A vector of length 2 indicating the range of the size of the words. |
|
41 |
// min.freq: words with frequency below min.freq will not be plotted |
|
42 |
// max.words : Maximum number of words to be plotted. least frequent terms dropped |
|
43 |
// random.order : plot words in random order. If false, they will be plotted in decreasing frequency |
|
44 |
// random.color : choose colors randomly from the colors. If false, the color is chosen based on the frequency |
|
45 |
// rot.per : proportion words with 90 degree rotation |
|
46 |
// colors : color words from least to most frequent |
|
47 |
// ordered.colors : if true, then colors are assigned to words in order |
|
48 |
//System.out.println("wordcloud..."); |
|
49 |
|
|
50 |
// FIXME : stars plot tests |
|
51 |
//String cmd = "stars(mtcars[, 1:7], key.loc = c(14, 2), main = \"Motor Trend Cars : stars(*, full = F)\", full = FALSE)"; //$NON-NLS-1$ |
|
52 |
String cmd = "stars(USJudgeRatings, locations = c(0, 0), scale = FALSE, radius = FALSE, col.stars = 1:10, key.loc = c(0, 0), main = \"US Judges rated\")"; |
|
53 |
//String cmd = "stars(cbind(1:16, 10*(16:1)), draw.segments = TRUE, main = \"A Joke -- do *not* use symbols on 2D data!\")"; |
|
54 |
|
|
55 |
|
|
56 |
|
|
57 |
//rw.plot(file, cmd, ((RChartsEngine) this.chartsEngine).getRDevice()); |
|
58 |
|
|
59 |
((RChartsEngine) this.chartsEngine).plot(file, cmd); |
|
60 |
|
|
61 |
//System.out.println("cleaning"); |
|
62 |
// rw.eval("rm(tmplabels)"); //$NON-NLS-1$ |
|
63 |
// rw.eval("rm(tmpfreqs)"); //$NON-NLS-1$ |
|
64 |
// } |
|
65 |
// catch(RWorkspaceException e) { |
|
66 |
// // TODO Auto-generated catch block |
|
67 |
// e.printStackTrace(); |
|
68 |
// } |
|
69 |
// catch(REXPMismatchException e) { |
|
70 |
// // TODO Auto-generated catch block |
|
71 |
// e.printStackTrace(); |
|
72 |
// } |
|
73 |
// catch(StatException e) { |
|
74 |
// // TODO Auto-generated catch block |
|
75 |
// e.printStackTrace(); |
|
76 |
// } |
|
77 |
|
|
78 |
return file; |
|
79 |
} |
|
80 |
|
|
81 |
@Override |
|
82 |
public Class getResultDataType() { |
|
83 |
return TextsBalance.class; |
|
84 |
} |
|
85 |
|
|
86 |
|
|
87 |
|
|
88 |
} |
|
0 | 89 |
tmp/org.txm.textsbalance.core/src/org/txm/textsbalance/core/preferences/TextsBalancePreferences.java (revision 19) | ||
---|---|---|
1 |
package org.txm.textsbalance.core.preferences; |
|
2 |
|
|
3 |
|
|
4 |
import org.eclipse.core.runtime.preferences.DefaultScope; |
|
5 |
import org.osgi.framework.FrameworkUtil; |
|
6 |
import org.osgi.service.prefs.Preferences; |
|
7 |
import org.txm.tbx.preferences.TXMPreferences; |
|
8 |
|
|
9 |
/** |
|
10 |
* Preferences initializer and manager. |
|
11 |
* @author sjacquot |
|
12 |
* |
|
13 |
*/ |
|
14 |
public class TextsBalancePreferences extends TXMPreferences { |
|
15 |
|
|
16 |
|
|
17 |
// auto populate the preference node qualifier from the current bundle id |
|
18 |
public static final String PREFERENCES_NODE = FrameworkUtil.getBundle(TextsBalancePreferences.class).getSymbolicName(); |
|
19 |
|
|
20 |
|
|
21 |
public static final String PREFERENCES_PREFIX = "texts_balance_"; //$NON-NLS-1$ |
|
22 |
|
|
23 |
public static final String GROUP_BY_WORDS = PREFERENCES_PREFIX + "count_by_words"; //$NON-NLS-1$ |
|
24 |
public static final String METHOD = PREFERENCES_PREFIX + "method"; //$NON-NLS-1$ |
|
25 |
|
|
26 |
// local result preferences |
|
27 |
public static final String STRUCTURAL_UNIT = PREFERENCES_PREFIX + "structural_unit"; //$NON-NLS-1$ |
|
28 |
public static final String STRUCTURAL_UNIT_PROPERTY_INDEX = PREFERENCES_PREFIX + "structural_unit_property_index"; //$NON-NLS-1$ |
|
29 |
|
|
30 |
|
|
31 |
public TextsBalancePreferences() { |
|
32 |
// TODO Auto-generated constructor stub |
|
33 |
} |
|
34 |
|
|
35 |
@Override |
|
36 |
public void initializeDefaultPreferences() { |
|
37 |
|
|
38 |
// FIXME: trying to store the preference in the host plugin preference node |
|
39 |
// IPreferencesService service = Platform.getPreferencesService(); |
|
40 |
// service.getRootNode().node(DefaultScope.SCOPE).node(Application.PLUGIN_ID).putBoolean(GROUP_BY_WORDS, true); |
|
41 |
// service.getRootNode().node(DefaultScope.SCOPE).node(Application.PLUGIN_ID).putInt(METHOD, 2); |
|
42 |
// try { |
|
43 |
// service.getRootNode().flush(); |
|
44 |
// } catch (BackingStoreException e) { |
|
45 |
// System.err.println(e); |
|
46 |
// } |
|
47 |
|
|
48 |
Preferences defaultPreferences = DefaultScope.INSTANCE.getNode(PREFERENCES_NODE); |
|
49 |
// //Preferences defaultPreferences = DefaultScope.INSTANCE.getNode(Application.PLUGIN_ID); |
|
50 |
defaultPreferences.putBoolean(GROUP_BY_WORDS, true); |
|
51 |
defaultPreferences.putInt(METHOD, 2); |
|
52 |
|
|
53 |
|
|
54 |
defaultPreferences.put(STRUCTURAL_UNIT, "text"); |
|
55 |
defaultPreferences.putInt(STRUCTURAL_UNIT_PROPERTY_INDEX, 0); |
|
56 |
|
|
57 |
// FIXME: Debug |
|
58 |
// System.err.println("*******************************TextsBalancePreferencesInitializer.initializeDefaultPreferences()"); |
|
59 |
|
|
60 |
} |
|
61 |
|
|
62 |
|
|
63 |
|
|
64 |
} |
|
65 |
|
|
66 |
|
|
0 | 67 |
tmp/org.txm.textsbalance.core/src/org/txm/textsbalance/core/functions/TextsBalance.java (revision 19) | ||
---|---|---|
1 |
/** |
|
2 |
* |
|
3 |
*/ |
|
4 |
package org.txm.textsbalance.core.functions; |
|
5 |
|
|
6 |
import java.io.File; |
|
7 |
import java.util.ArrayList; |
|
8 |
import java.util.Arrays; |
|
9 |
import java.util.Collections; |
|
10 |
import java.util.HashMap; |
|
11 |
import java.util.List; |
|
12 |
|
|
13 |
import org.txm.HasResults; |
|
14 |
import org.txm.Toolbox; |
|
15 |
import org.txm.functions.Function; |
|
16 |
import org.txm.functions.TXMResult; |
|
17 |
import org.txm.searchengine.cqp.AbstractCqiClient; |
|
18 |
import org.txm.searchengine.cqp.NetCqiClient; |
|
19 |
import org.txm.searchengine.cqp.clientExceptions.CqiClientException; |
|
20 |
import org.txm.searchengine.cqp.corpus.Corpus; |
|
21 |
import org.txm.searchengine.cqp.corpus.QueryResult; |
|
22 |
import org.txm.searchengine.cqp.corpus.StructuralUnit; |
|
23 |
import org.txm.searchengine.cqp.corpus.StructuralUnitProperty; |
|
24 |
import org.txm.searchengine.cqp.corpus.query.Match; |
|
25 |
import org.txm.searchengine.cqp.corpus.query.Query; |
|
26 |
import org.txm.utils.logger.Log; |
|
27 |
|
|
28 |
/** |
|
29 |
* @author mdecorde |
|
30 |
* @author sjacquot |
|
31 |
* |
|
32 |
*/ |
|
33 |
public class TextsBalance extends Function implements TXMResult { |
|
34 |
|
|
35 |
|
|
36 |
|
|
37 |
protected Corpus corpus; |
|
38 |
|
|
39 |
|
|
40 |
HashMap<Integer, Comparable[]> dataset; |
|
41 |
|
|
42 |
|
|
43 |
protected String propertyName; |
|
44 |
protected List<String> values; |
|
45 |
protected int fMin; |
|
46 |
protected int fMax; |
|
47 |
|
|
48 |
protected String name; |
|
49 |
|
|
50 |
/** |
|
51 |
* |
|
52 |
*/ |
|
53 |
public TextsBalance(Corpus corpus) { |
|
54 |
this.corpus = corpus; |
|
55 |
|
|
56 |
this.fMin = 999999999; |
|
57 |
this.fMax = 0; |
|
58 |
} |
|
59 |
|
|
60 |
|
|
61 |
/** |
|
62 |
* @param method 1: use CQL to solve matches, 2 uses corpus struct indexes, 2 is faster ! |
|
63 |
* @param method |
|
64 |
* @param su |
|
65 |
* @param suPropertyName |
|
66 |
* @param groupByTexts |
|
67 |
* @throws CqiClientException |
|
68 |
*/ |
|
69 |
public void compute(int method, StructuralUnit su, String suPropertyName, boolean groupByTexts) throws CqiClientException { |
|
70 |
|
|
71 |
this.name = su.getName() + "@" + suPropertyName + " (group by texts = " + groupByTexts + ")"; |
|
72 |
|
|
73 |
Log.warning("Compute balance with metadata propertyName = " + suPropertyName + ", structural unit = " + su.getName() + " and count_texts = " + groupByTexts); |
|
74 |
try { |
|
75 |
if (suPropertyName == null || suPropertyName.length() == 0) return; |
|
76 |
|
|
77 |
|
|
78 |
this.dataset = new HashMap<Integer, Comparable[]>(); |
|
79 |
|
|
80 |
this.propertyName = suPropertyName; |
|
81 |
StructuralUnitProperty p = su.getProperty(suPropertyName); |
|
82 |
this.values = p.getValues(); |
|
83 |
Collections.sort(values); |
|
84 |
|
|
85 |
|
|
86 |
//int method = 2; |
|
87 |
//System.out.println("Method: "+method); |
|
88 |
//long time = System.currentTimeMillis(); |
|
89 |
if (method == 1) { // using CQL to solve matches |
|
90 |
for (String value : values) { |
|
91 |
int v = 0; |
|
92 |
if (groupByTexts) { |
|
93 |
QueryResult r = corpus.query(new Query("<"+p.getFullName()+"=\""+value+"\">[]"), "tmp", false); |
|
94 |
v = r.getNMatch(); |
|
95 |
r.drop(); |
|
96 |
} else { |
|
97 |
QueryResult r = corpus.query(new Query("[_."+p.getFullName()+"=\""+value+"\"] expand to text"), "tmp", false); |
|
98 |
int t = 0; |
|
99 |
for (Match m : r.getMatches()) t += m.getLength(); |
|
100 |
v = t; |
|
101 |
r.drop(); |
|
102 |
} |
|
103 |
if (v < fMin) fMin=v; |
|
104 |
if (v > fMax) fMax=v; |
|
105 |
dataset.put(v, new Comparable[]{p.getName(), value}); |
|
106 |
} |
|
107 |
} else { |
|
108 |
AbstractCqiClient CQI = Toolbox.getCqiClient(); |
|
109 |
if (CQI instanceof NetCqiClient) { |
|
110 |
System.out.println("Error: CQP eval method only available with CQP memory mode"); |
|
111 |
return; |
|
112 |
} |
|
113 |
|
|
114 |
String supqn = p.getQualifiedName(); |
|
115 |
int nsup = CQI.attributeSize(supqn); |
|
116 |
|
|
117 |
ArrayList<Match> sup_limits = new ArrayList<Match>(nsup); |
|
118 |
for (int i = 0 ; i < nsup ; i++) { |
|
119 |
int[] l = CQI.struc2Cpos(supqn, i); |
|
120 |
sup_limits.add(new Match(l[0], l[1])); |
|
121 |
} |
|
122 |
//System.out.println("All sup limits are "+sup_limits); |
|
123 |
List<Match> corpus_matches = corpus.getMatches(); |
|
124 |
//System.out.println("corpus matches: "+corpus_matches); |
|
125 |
ArrayList<Integer> inter = intersect(corpus_matches, sup_limits); |
|
126 |
//System.out.println( "No of $sup that covers $corpus: "+inter); |
|
127 |
int[] structid = new int[inter.size()]; |
|
128 |
for (int i = 0 ; i < structid.length ; i++) structid[i] = inter.get(i); |
|
129 |
|
|
130 |
String[] inter_values = CQI.struc2Str(supqn, structid); |
|
131 |
//System.out.println( " with values: "+Arrays.toString(inter_values)); |
|
132 |
HashMap<String, Integer> inter_uniq = new HashMap<String, Integer>(); |
|
133 |
|
|
134 |
if (groupByTexts) { |
|
135 |
for (String o : inter_values) { |
|
136 |
if (!inter_uniq.containsKey(o)) { |
|
137 |
inter_uniq.put(o, 0); |
|
138 |
} |
|
139 |
inter_uniq.put(o, inter_uniq.get(o) +1); |
|
140 |
} |
|
141 |
} else { |
|
142 |
for (int imatch = 0 ; imatch < inter.size() ; imatch++) { |
|
143 |
String o = inter_values[imatch]; |
|
144 |
if (!inter_uniq.containsKey(o)) { |
|
145 |
inter_uniq.put(o, 0); |
|
146 |
} |
|
147 |
int s = sup_limits.get(inter.get(imatch)).getLength(); |
|
148 |
inter_uniq.put(o, inter_uniq.get(o) + s); |
|
149 |
|
|
150 |
} |
|
151 |
} |
|
152 |
Object[] sortedkeys = inter_uniq.keySet().toArray(); |
|
153 |
Arrays.sort(sortedkeys); |
|
154 |
for (Object k : sortedkeys) { |
|
155 |
int v = inter_uniq.get(k); |
|
156 |
if (v < fMin) fMin=v; |
|
157 |
if (v > fMax) fMax=v; |
|
158 |
dataset.put(v, new Comparable[]{p.getName(), k.toString()}); |
|
159 |
|
|
160 |
} |
|
161 |
} |
|
162 |
} |
|
163 |
catch(Exception e) { |
|
164 |
System.out.println("Error while computing text informations: "+e); |
|
165 |
e.printStackTrace(); |
|
166 |
} |
|
167 |
} |
|
168 |
|
|
169 |
|
|
170 |
/** |
|
171 |
* |
|
172 |
* @param corpus |
|
173 |
* @param structs |
|
174 |
* @return |
|
175 |
*/ |
|
176 |
public static ArrayList<Integer> intersect(List<Match> corpus, List<Match> structs) { |
|
177 |
int ai=0, bi=0; |
|
178 |
ArrayList<Integer> result = new ArrayList<Integer>(); |
|
179 |
|
|
180 |
while (ai < corpus.size() && bi < structs.size() ) { |
|
181 |
if (structs.get(bi).contains(corpus.get(ai))) { |
|
182 |
result.add(bi); |
|
183 |
ai++; |
|
184 |
} else if (corpus.get(ai).contains(structs.get(bi))) { |
|
185 |
result.add(bi); |
|
186 |
bi++; |
|
187 |
} else { |
|
188 |
if (structs.get(bi).getStart() < corpus.get(ai).getStart()) { |
|
189 |
bi++; |
|
190 |
} else { |
|
191 |
ai++; |
|
192 |
} |
|
193 |
} |
|
194 |
} |
|
195 |
|
|
196 |
return result; |
|
197 |
} |
|
198 |
|
|
199 |
|
|
200 |
/** |
|
201 |
* @return the dataset |
|
202 |
*/ |
|
203 |
public HashMap<Integer, Comparable[]> getDataset() { |
|
204 |
return dataset; |
|
205 |
} |
|
206 |
|
|
207 |
|
|
208 |
/** |
|
209 |
* @return the corpus |
|
210 |
*/ |
|
211 |
public Corpus getCorpus() { |
|
212 |
return corpus; |
|
213 |
} |
|
214 |
|
|
215 |
|
|
216 |
/** |
|
217 |
* @return the propertyName |
|
218 |
*/ |
|
219 |
public String getPropertyName() { |
|
220 |
return propertyName; |
|
221 |
} |
|
222 |
|
|
223 |
|
|
224 |
/** |
|
225 |
* @return the values |
|
226 |
*/ |
|
227 |
public List<String> getValues() { |
|
228 |
return values; |
|
229 |
} |
|
230 |
|
|
231 |
|
|
232 |
/** |
|
233 |
* @return the fMin |
|
234 |
*/ |
|
235 |
public int getFMin() { |
|
236 |
return fMin; |
|
237 |
} |
|
238 |
|
|
239 |
|
|
240 |
/** |
|
241 |
* @return the fMax |
|
242 |
*/ |
|
243 |
public int getFMax() { |
|
244 |
return fMax; |
|
245 |
} |
|
246 |
|
|
247 |
|
|
248 |
@Override |
|
249 |
public boolean toTxt(File outfile, String encoding, String colseparator, String txtseparator) throws Exception { |
|
250 |
// TODO Auto-generated method stub |
|
251 |
return false; |
|
252 |
} |
|
253 |
|
|
254 |
|
|
255 |
@Override |
|
256 |
public void clean() { |
|
257 |
// TODO Auto-generated method stub |
|
258 |
|
|
259 |
} |
|
260 |
|
|
261 |
|
|
262 |
@Override |
|
263 |
public boolean delete() { |
|
264 |
return this.corpus.removeResult(this); |
|
265 |
} |
|
266 |
|
|
267 |
|
|
268 |
@Override |
|
269 |
public HasResults getParent() { |
|
270 |
return this.corpus; |
|
271 |
} |
|
272 |
|
|
273 |
|
|
274 |
/** |
|
275 |
* @return the name |
|
276 |
*/ |
|
277 |
public String getName() { |
|
278 |
return name; |
|
279 |
} |
|
280 |
|
|
281 |
|
|
282 |
} |
|
0 | 283 |
Formats disponibles : Unified diff