Revision 11704 trunk/applications/appgvSIG/src/com/iver/cit/gvsig/project/documents/view/legend/gui/DotDensity.java
DotDensity.java | ||
---|---|---|
43 | 43 |
* |
44 | 44 |
* $Id$ |
45 | 45 |
* $Log$ |
46 |
* Revision 1.7 2007-05-10 09:46:45 jaume |
|
46 |
* Revision 1.8 2007-05-17 09:32:37 jaume |
|
47 |
* *** empty log message *** |
|
48 |
* |
|
49 |
* Revision 1.7 2007/05/10 09:46:45 jaume |
|
47 | 50 |
* Refactored legend interface names |
48 | 51 |
* |
49 | 52 |
* Revision 1.6 2007/05/08 15:45:31 jaume |
... | ... | |
91 | 94 |
|
92 | 95 |
import java.awt.BorderLayout; |
93 | 96 |
import java.awt.Color; |
97 |
import java.awt.Component; |
|
94 | 98 |
import java.awt.ComponentOrientation; |
95 | 99 |
import java.awt.Dimension; |
96 | 100 |
import java.awt.FlowLayout; |
... | ... | |
119 | 123 |
|
120 | 124 |
import org.gvsig.gui.beans.swing.GridBagLayoutPanel; |
121 | 125 |
|
126 |
import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
|
122 | 127 |
import com.hardcode.gdbms.engine.data.DataSource; |
123 | 128 |
import com.hardcode.gdbms.engine.data.DataSourceFactory; |
124 | 129 |
import com.hardcode.gdbms.engine.values.NumericValue; |
... | ... | |
145 | 150 |
* |
146 | 151 |
*/ |
147 | 152 |
public class DotDensity extends JPanel implements ILegendPanel { |
153 |
private static final int MAX_VALUE_COUNT = 300; |
|
148 | 154 |
private FLyrVect layer; |
149 | 155 |
private JPanel northPanel = null; |
150 | 156 |
private GridBagLayoutPanel densityButtonsPanel = null; |
... | ... | |
154 | 160 |
private JRadioButton rdBtnMedium = null; |
155 | 161 |
private JRadioButton rdBtnLow = null; |
156 | 162 |
private IncrementalNumberField numDotSize = null; |
157 |
private double max, min, mean; |
|
163 |
|
|
158 | 164 |
private IncrementalNumberField nmbrDotValue = null; |
159 | 165 |
private JLabel lblLabellingField = null; |
160 | 166 |
private DotDensityLegend legend; |
161 | 167 |
private String fieldName; |
162 | 168 |
private boolean initializing; |
169 |
private double max; |
|
170 |
private double b, a; // regression function params where: y = bx + a |
|
171 |
private int valueCount; |
|
163 | 172 |
|
164 |
private MyListener cmbAction = new MyListener(); |
|
165 |
NumberFormat nf = NumberFormat.getInstance(); |
|
166 |
|
|
173 |
private NumberFormat nf = NumberFormat.getInstance(); |
|
167 | 174 |
{ |
168 | 175 |
nf.setMaximumFractionDigits(3); |
169 | 176 |
} |
177 |
private MyListener cmbAction = new MyListener(); |
|
170 | 178 |
|
171 | 179 |
private class MyListener implements ItemListener, ActionListener { |
172 |
|
|
173 |
|
|
174 | 180 |
public void itemStateChanged(ItemEvent e) { |
175 | 181 |
if (!initializing) |
176 | 182 |
doIt(); |
... | ... | |
192 | 198 |
fieldName = (String) cmbLegendField.getItemAt(0); |
193 | 199 |
} |
194 | 200 |
|
195 |
String sql = "select "+fieldName+" from '"+sds.getName()+"';";
|
|
201 |
int fieldIndex = sds.getFieldIndexByName(fieldName);
|
|
196 | 202 |
|
197 |
DataSource recordset = sds.getDataSourceFactory().executeSQL(sql, DataSourceFactory.AUTOMATIC_OPENING ); |
|
198 |
// TODO implement MAX() and MIN() functions in GDBMS!!!!! |
|
199 |
max = Double.NEGATIVE_INFINITY; |
|
200 |
min = Double.MAX_VALUE; |
|
201 |
for (int i = 0; i < sds.getRowCount(); i++) { |
|
202 |
double value = ((NumericValue) recordset.getFieldValue(i,0)).doubleValue(); |
|
203 |
max = Math.max(max, value); |
|
204 |
min = Math.min(min, value); |
|
203 |
// will extract a "Minimum Square Adjustment" regression function. |
|
204 |
long rowCount = sds.getRowCount(); |
|
205 |
valueCount = (rowCount > MAX_VALUE_COUNT) ? MAX_VALUE_COUNT : (int) rowCount; |
|
206 |
|
|
207 |
double sumx = 0, sumy = 0, sumxx = 0, sumyy = 0, sumxy = 0; |
|
208 |
double Sxx, Sxy; |
|
209 |
|
|
210 |
for (int i = 0; i < valueCount; i++) { |
|
211 |
double value = ((NumericValue) sds.getFieldValue(i,fieldIndex)).doubleValue(); |
|
212 |
sumx += i; |
|
213 |
sumy += value; |
|
214 |
sumxx += i*i; |
|
215 |
sumyy += value*value; |
|
216 |
sumxy += i*value; |
|
205 | 217 |
} |
206 |
mean = (max+min) /2; |
|
218 |
|
|
219 |
// start regression |
|
220 |
double n = (double) valueCount; |
|
221 |
Sxx = sumxx-sumx*sumx/n; |
|
222 |
Sxy = sumxy-sumx*sumy/n; |
|
223 |
b = Sxy/Sxx; |
|
224 |
a = (sumy-b*sumx)/n; |
|
225 |
|
|
207 | 226 |
buttonsListener.actionPerformed(null); |
208 | 227 |
|
209 | 228 |
} catch (Exception ex) { |
... | ... | |
229 | 248 |
|
230 | 249 |
public void stateChanged(ChangeEvent e) { |
231 | 250 |
|
232 |
// This is my messy statistic aggregation function |
|
233 |
// TODO if I can, I'll have a look to my statistic books to figure out one better |
|
234 |
int quantileIndex = getSldDensity().getValue(); |
|
235 |
final int topLimit = 98; |
|
236 |
if (quantileIndex > topLimit) |
|
237 |
quantileIndex = topLimit; |
|
238 |
double quantileAmount = (max-min)/100; |
|
239 |
// nmbrDotValue.setText(nf.format(3*quantileAmount/Math.log(quantileIndex))); |
|
240 |
nmbrDotValue.setDouble(3*quantileAmount/Math.log(quantileIndex)); |
|
251 |
int quantileIndex = (MAX_VALUE_COUNT*getSldDensity().getValue())/100; |
|
252 |
nmbrDotValue.setDouble((b*quantileIndex+a)/50); |
|
253 |
|
|
241 | 254 |
} |
242 | 255 |
|
243 | 256 |
}; |
... | ... | |
245 | 258 |
private ColorChooserPanel outlineColorChooserPanel; |
246 | 259 |
private ILegend oldLegend; |
247 | 260 |
private JSymbolPreviewButton btnOutline; |
261 |
private ColorChooserPanel jccBackground; |
|
248 | 262 |
|
249 | 263 |
public DotDensity() { |
250 | 264 |
super(); |
... | ... | |
278 | 292 |
} |
279 | 293 |
if (!(legend instanceof DotDensityLegend)) { |
280 | 294 |
legend = new DotDensityLegend(); |
281 |
((DotDensityLegend) legend).setFieldName((String) cmbLegendField.getItemAt(0)); |
|
295 |
((DotDensityLegend) legend).setFieldNames( |
|
296 |
new String[] {(String) cmbLegendField.getItemAt(0)}); |
|
282 | 297 |
} |
283 | 298 |
|
284 | 299 |
DotDensityLegend theLegend = (DotDensityLegend) legend; |
285 | 300 |
|
286 | 301 |
initializing = false; // enables events to the combo box |
287 | 302 |
|
288 |
cmbLegendField.setSelectedItem(theLegend.getFieldName());
|
|
303 |
cmbLegendField.setSelectedItem(theLegend.getFieldNames()[0]);
|
|
289 | 304 |
try { |
290 | 305 |
getDotColorChooserPanel().setColor(theLegend.getDotColor()); |
291 | 306 |
} catch (NullPointerException npEx) { |
292 | 307 |
getDotColorChooserPanel().setColor(Color.RED); |
293 | 308 |
} |
309 |
try { |
|
310 |
getBackgroundColorChooserPanel().setColor(theLegend.getBGColor()); |
|
311 |
} catch (NullPointerException npEx) { |
|
312 |
getDotColorChooserPanel().setColor(Color.WHITE); |
|
313 |
} |
|
314 |
|
|
294 | 315 |
getBtnOutline().setSymbol(theLegend.getOutline()); |
295 | 316 |
try { |
296 | 317 |
double dotValue = theLegend.getDotValue(); |
297 | 318 |
if (dotValue <= 0) |
298 | 319 |
dotValue = 100; |
299 | 320 |
getNmbrDotValue().setDouble(dotValue); |
321 |
|
|
300 | 322 |
} catch (NullPointerException npEx) { |
301 | 323 |
getNmbrDotValue().setDouble(max); |
302 | 324 |
} |
... | ... | |
383 | 405 |
|
384 | 406 |
// create a simple-fill symbol over which the dot density will be drawn |
385 | 407 |
SimpleFillSymbol fillSymbol = new SimpleFillSymbol(); |
386 |
fillSymbol.setFillColor(Color.WHITE);
|
|
408 |
fillSymbol.setFillColor(getBackgroundColorChooserPanel().getColor());
|
|
387 | 409 |
fillSymbol.setOutline((ILineSymbol) getBtnOutline().getSymbol()); |
388 | 410 |
|
389 | 411 |
// combine both the DotDensitySymbol and the SimpleFillSymbol in |
... | ... | |
399 | 421 |
legend.addSymbol(ValueFactory.createValue("theSymbol"), symbol); |
400 | 422 |
legend.setDefaultSymbol(symbol); |
401 | 423 |
legend.setDotValue(dotValue); |
402 |
legend.setFieldName(fieldName);
|
|
424 |
legend.setFieldNames(new String[] {fieldName});
|
|
403 | 425 |
|
404 | 426 |
|
405 | 427 |
} catch (Exception e) { |
... | ... | |
456 | 478 |
densityButtonsPanel.addComponent( |
457 | 479 |
PluginServices.getText(this, "color"), aux); |
458 | 480 |
aux = new JPanel(layout); |
481 |
aux.add(getBackgroundColorChooserPanel()); |
|
482 |
densityButtonsPanel.addComponent( |
|
483 |
PluginServices.getText(this, "background_color"), aux); |
|
484 |
aux = new JPanel(layout); |
|
459 | 485 |
aux.add(getBtnOutline()); |
460 | 486 |
densityButtonsPanel.addComponent( |
461 |
PluginServices.getText(this, "outline_color"), aux);
|
|
487 |
PluginServices.getText(this, "outline"), aux); |
|
462 | 488 |
} |
463 | 489 |
return densityButtonsPanel; |
464 | 490 |
} |
465 | 491 |
|
492 |
private ColorChooserPanel getBackgroundColorChooserPanel() { |
|
493 |
if (jccBackground == null) { |
|
494 |
jccBackground = new ColorChooserPanel() ; |
|
495 |
jccBackground.setColor(Color.WHITE); |
|
496 |
jccBackground.setAlpha(255); |
|
497 |
} |
|
498 |
return jccBackground; |
|
499 |
} |
|
500 |
|
|
466 | 501 |
private JSymbolPreviewButton getBtnOutline() { |
467 | 502 |
if (btnOutline == null) { |
468 | 503 |
btnOutline = new JSymbolPreviewButton(FShape.LINE); |
... | ... | |
648 | 683 |
return DotDensityLegend.class; |
649 | 684 |
} |
650 | 685 |
|
686 |
public boolean isSuitableFor(FLayer layer) { |
|
687 |
if (layer instanceof FLyrVect) { |
|
688 |
try { |
|
689 |
FLyrVect lyr = (FLyrVect) layer; |
|
690 |
|
|
691 |
if (lyr.getShapeType() != FShape.POLYGON) |
|
692 |
return false; |
|
693 |
|
|
694 |
SelectableDataSource sds; |
|
695 |
sds = lyr.getRecordset(); |
|
696 |
String[] fNames = sds.getFieldNames(); |
|
697 |
for (int i = 0; i < fNames.length; i++) { |
|
698 |
if (isNumericField(sds.getFieldType(i))) { |
|
699 |
return true; |
|
700 |
} |
|
701 |
} |
|
702 |
} catch (ReadDriverException e) { |
|
703 |
return false; |
|
704 |
} |
|
705 |
} |
|
706 |
return false; |
|
707 |
} |
|
708 |
|
|
651 | 709 |
} // @jve:decl-index=0:visual-constraint="10,10" |
Also available in: Unified diff