[Schmitzm-commits] r277 - in trunk/src/schmitzm: geotools/feature jfree/chart/style jfree/feature/style
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Sat Aug 1 21:55:42 CEST 2009
Author: mojays
Date: 2009-08-01 21:55:40 +0200 (Sat, 01 Aug 2009)
New Revision: 277
Modified:
trunk/src/schmitzm/geotools/feature/FeatureUtil.java
trunk/src/schmitzm/jfree/chart/style/AbstractChartStyle.java
trunk/src/schmitzm/jfree/feature/style/FeatureBasicChartStyle.java
trunk/src/schmitzm/jfree/feature/style/FeatureChartUtil.java
trunk/src/schmitzm/jfree/feature/style/FeatureScatterChartStyle.java
Log:
support of category datasets
Modified: trunk/src/schmitzm/geotools/feature/FeatureUtil.java
===================================================================
--- trunk/src/schmitzm/geotools/feature/FeatureUtil.java 2009-08-01 18:26:53 UTC (rev 276)
+++ trunk/src/schmitzm/geotools/feature/FeatureUtil.java 2009-08-01 19:55:40 UTC (rev 277)
@@ -538,11 +538,15 @@
*/
public static Vector<Feature> sortFeatures(FeatureIterator fi, String attrName) {
// First create a SortedMap with CollisionList
- SortedMap<Number, Vector<Feature>> sortedFeatureLists = new TreeMap<Number, Vector<Feature>>();
+ SortedMap<Comparable, Vector<Feature>> sortedFeatureLists = new TreeMap<Comparable, Vector<Feature>>();
for (;fi.hasNext();) {
Feature f = fi.next();
+ // Check whether attribute value is Comparable
+ Object attrValue = f.getAttribute(attrName);
+ if ( attrValue != null && !(attrValue instanceof Comparable) )
+ throw new UnsupportedOperationException("Feature sort only supported for Comparable attributes: "+LangUtil.getSimpleClassName(attrValue));
// Determine X value as sort attribute (NULL not permitted for XYDateset!)
- Number xValue = (Number)f.getAttribute(attrName);
+ Comparable xValue = (Comparable)attrValue;
if ( xValue == null )
continue;
Modified: trunk/src/schmitzm/jfree/chart/style/AbstractChartStyle.java
===================================================================
--- trunk/src/schmitzm/jfree/chart/style/AbstractChartStyle.java 2009-08-01 18:26:53 UTC (rev 276)
+++ trunk/src/schmitzm/jfree/chart/style/AbstractChartStyle.java 2009-08-01 19:55:40 UTC (rev 277)
@@ -383,6 +383,7 @@
plot.getRenderer().setURLGenerator( hasURLs() ? URLGEN_XY : null );
if ( getOrientation() != null )
plot.setOrientation( getOrientation() );
+
// style renderer
for (int i=0; i<plot.getRendererCount(); i++) {
XYItemRenderer renderer = plot.getRenderer(i);
@@ -396,6 +397,10 @@
plot.getRenderer().setBaseItemURLGenerator( hasURLs() ? URLGEN_CAT : null );
if ( getOrientation() != null )
plot.setOrientation( getOrientation() );
+
+// DEBUG!! ///
+// plot.setOrientation(PlotOrientation.VERTICAL);
+/////////////
// style renderer
for (int i=0; i<plot.getRendererCount(); i++) {
CategoryItemRenderer renderer = plot.getRenderer(i);
@@ -405,41 +410,6 @@
}
}
-// // style the legend (by the series properties of ChartRendererStyle!!)
-// LegendTitle legend = chart.getLegend();
-// if ( legend != null && legend.getSources().length > 0 ) {
-// final LegendItemSource[] legendSource = legend.getSources();
-// final LegendItemCollection oldLegend = legendSource[0].getLegendItems();
-// // redefine the primary legend
-// legendSource[0] = new LegendItemSource() {
-// public LegendItemCollection getLegendItems() {
-// LegendItemCollection lic = new LegendItemCollection();
-// for (int i=0 ; i<oldLegend.getItemCount(); i++ ) {
-// // create a changeable copy of the legend item
-// LegendItem legendItem = oldLegend.get(i);
-// ChangableLegendItem changeableItem = null;
-// if ( legendItem instanceof ChangableLegendItem )
-// changeableItem = (ChangableLegendItem)legendItem;
-// else
-// changeableItem = new ChangableLegendItem( legendItem );
-//
-// // restyle the legend item according to the renderer style
-// int rendererIdx = newItem.getDatasetIndex();
-// int seriesIdx = newItem.getSeriesIndex();
-// ChartRendererStyle rendStyle = getRendererStyle(rendererIdx);
-// if ( rendStyle != null ) {
-// if ( rendStyle.getSeriesLegendLabel(seriesIdx) != null )
-// newItem.setLabel(rendStyle.getSeriesLegendLabel(seriesIdx).getLabel());
-// if ( rendStyle.getSeriesLegendTooltip(seriesIdx) != null )
-// newItem.setToolTipText(rendStyle.getSeriesLegendTooltip(seriesIdx).getLabel());
-// }
-// lic.add(newItem);
-// }
-// return lic;
-// }
-// }
-// }
-
// style plot
if ( getPlotStyle() != null )
getPlotStyle().applyToPlot(chart.getPlot());
Modified: trunk/src/schmitzm/jfree/feature/style/FeatureBasicChartStyle.java
===================================================================
--- trunk/src/schmitzm/jfree/feature/style/FeatureBasicChartStyle.java 2009-08-01 18:26:53 UTC (rev 276)
+++ trunk/src/schmitzm/jfree/feature/style/FeatureBasicChartStyle.java 2009-08-01 19:55:40 UTC (rev 277)
@@ -181,16 +181,10 @@
* Creates an appropriate {@link Dataset} for the attributes defined
* by this style (according to the attributes types in the given
* {@link FeatureCollection}) and calls {@link #applyToDataset(Dataset)}.
- * @see schmitzm.jfree.feature.style.FeatureChartStyle#applyToFeatureCollection(org.geotools.feature.FeatureCollection)
*/
@Override
public JFreeChart applyToFeatureCollection(FeatureCollection fc) {
- final XYSeriesCollection dataset = FeatureChartUtil.createXYDataset(
- fc,
- this
- );
- JFreeChart chart = applyToDataset(dataset);
-
- return chart;
+ Dataset dataset = FeatureChartUtil.createDataset(fc,this);
+ return applyToDataset(dataset);
}
}
Modified: trunk/src/schmitzm/jfree/feature/style/FeatureChartUtil.java
===================================================================
--- trunk/src/schmitzm/jfree/feature/style/FeatureChartUtil.java 2009-08-01 18:26:53 UTC (rev 276)
+++ trunk/src/schmitzm/jfree/feature/style/FeatureChartUtil.java 2009-08-01 19:55:40 UTC (rev 277)
@@ -45,6 +45,7 @@
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.category.CategoryDataset;
+import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.Dataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
@@ -123,7 +124,8 @@
* @param yAttr feature attribute(s) used for the Y-value (at least one; for each a
* series is created in the dataset)
*/
- public static Dataset createDataset(FeatureCollection fc, boolean forceCat, boolean sort, String xAttr, String... yAttr) {
+ public static Dataset createDataset(FeatureCollection fc, FeatureChartStyle style) {
+ String xAttr = style.getAttributeName(0);
// Check the X attribute to differ between XY- and CategoryDataset
AttributeType xType = fc.getSchema().getAttributeType(xAttr);
if ( xType == null )
@@ -131,29 +133,31 @@
// If domain attribute is numeric (and category not forced) create
// a XYDataset
- if ( !forceCat && Number.class.isAssignableFrom(xType.getBinding()) )
- ;//sdsd
+ if ( !style.isForceCategories() && Number.class.isAssignableFrom(xType.getBinding()) )
+ return createXYDataset(fc, style);
else
- ;//
-
- return null;
+ return createCategoryDataset(fc, style);
}
/**
- * Checks whether an attribute exists and whether it is numeric.
+ * Checks whether an attribute exists and whether it is of
+ * a specific type.
* Otherwise an {@link IllegalArgumentException} is thrown.
- * @param fType a feature type
- * @param aName the attribute name checked for numeric type
+ * @param fType a feature type
+ * @param aName the attribute name checked for numeric type
+ * @param typeToCheck the type the attribute must support (if {@code null}
+ * only the attribute existing is checked!)
*/
- private static void checkAttributeNumeric(FeatureType fType, String aName, String... errDesc) {
+ private static void checkAttributeType(FeatureType fType, String aName, Class typeToCheck, String... errDesc) {
+ AttributeType aType = fType.getAttributeType(aName);
+ if ( aType == null )
+ throw new UnsupportedOperationException("Unknown attribute: "+aName);
+
String attrDesc = errDesc.length > 0 ? errDesc[0] : "Attribute";
String datasetDesc = errDesc.length > 1 ? errDesc[1] : "Dataset";
- AttributeType aType = fType.getAttributeType(aName);
- if ( aType == null )
- throw new UnsupportedOperationException("Unknown attribute: "+aName);
- if ( !Number.class.isAssignableFrom(aType.getBinding()) )
- throw new UnsupportedOperationException(attrDesc+" must be numeric for "+datasetDesc+": "+aName);
+ if ( typeToCheck != null && !typeToCheck.isAssignableFrom(aType.getBinding()) )
+ throw new UnsupportedOperationException(attrDesc+" must be "+typeToCheck.getSimpleName()+" for "+datasetDesc+": "+aName);
}
/**
@@ -171,10 +175,10 @@
throw new IllegalArgumentException("FeatureChartStyle must define at least 2 attributes to create XYDataset: "+attrCount);
String xAttrName = chartStyle.getAttributeName(0);
// check data types of X attribute
- checkAttributeNumeric(fc.getSchema(), xAttrName, "Domain attribute", "XYDataset");
+ checkAttributeType(fc.getSchema(), xAttrName, Number.class, "Domain attribute", "XYDataset");
// check data types of Y attribute
for (int i=1; i<attrCount; i++)
- checkAttributeNumeric(fc.getSchema(), chartStyle.getAttributeName(i), "Range attribute", "XYDataset");
+ checkAttributeType(fc.getSchema(), chartStyle.getAttributeName(i), Number.class, "Range attribute", "XYDataset");
// Create a series for each range attribute (note: the 0
// array element useless, but it is more comfortable to
@@ -237,4 +241,71 @@
}
return dataset;
}
+
+ /**
+ * Creates a {@link XYDataset} for 2 (or more) attributes of a {@link FeatureCollection}.
+ * XYDateset can only be created for <b>numeric</b> attributes.
+ * @param fc a {@link FeatureCollection}
+ * @param style defines the attributes used to create the dataset from, as well
+ * as the sorting and normalization properties
+ * @throws IllegalArgumentException if less then 2 attributes are specified
+ * @throws UnsupportedOperationException if attributes are not numeric
+ */
+ public static DefaultCategoryDataset createCategoryDataset(FeatureCollection fc, FeatureChartStyle chartStyle) {
+ int attrCount = chartStyle.getAttributeCount();
+ if ( attrCount < 2 )
+ throw new IllegalArgumentException("FeatureChartStyle must define at least 2 attributes to create CategoryDataset: "+attrCount);
+ String xAttrName = chartStyle.getAttributeName(0);
+ // only check whether X attribute exists (numeric and not-numeric allowed)
+ checkAttributeType(fc.getSchema(), xAttrName, Comparable.class, "Domain attribute", "CategoryDataset");
+ // check data types of Y attribute (only numeric allowed)
+ for (int i=1; i<attrCount; i++)
+ checkAttributeType(fc.getSchema(), chartStyle.getAttributeName(i), Number.class, "Range attribute", "CategoryDataset");
+
+ // Create a new dataset and insert the series
+ DefaultCategoryDataset dataset = new DefaultCategoryDataset();
+// TODO: Mapping for CategoryDataset!! (CategoryDataset is no SeriesDataset!)
+// Feature2SeriesDatasetMapping mapping = new Feature2SeriesDatasetMapping(fc,dataset);
+// dataset.setGroup( new FeatureDatasetMetaData(mapping) );
+
+ // If dataset should be sorted, the features must be sorted first
+ // according to the domain attribute. CategoryDataset has no
+ // "autoSort", and this - at all - would not work (see createXYDataset(..))
+ Iterator<Feature> fi = null;
+ if ( chartStyle.isSortDomainAxis() ) {
+ Vector<Feature> sortedFeatures = FeatureUtil.sortFeatures(fc.features(), xAttrName);
+ // Create an Iterator for the sorted Features
+ fi = sortedFeatures.iterator();
+ } else
+ fi = new PipedFeatureIterator( fc.features() );
+
+ // Iterate the FeatureCollection and fill the series
+ for (int fIdx=0; fi.hasNext(); fIdx++) {
+ Feature f = fi.next();
+ // Determine the category (NULL not permitted!)
+ Comparable catValue = (Comparable)f.getAttribute(xAttrName);
+ if ( catValue == null )
+ continue;
+ // Determine the Y values and fill the dataset
+ for (int attrIdx=1; attrIdx<attrCount; attrIdx++) {
+ String yAttrName = chartStyle.getAttributeName(attrIdx);
+ Number yValue = (Number)f.getAttribute(yAttrName);
+// // TODO: here maybe filtering the several NULL aliases
+// if ( yValue is a NULL alias )
+// yValue = null;
+// // TODO: her maybe ignore NULL values completely
+// if ( yValue == null )
+// continue;
+
+ // Add data to dataset
+ dataset.addValue(yValue, xAttrName, yAttrName);
+
+//TODO: Implement the Mapping for CategoryDataset
+// // Mapping between FID and data index in series
+// mapping.setMapping(f.getID(), yAttrName, fIdx);
+ }
+
+ }
+ return dataset;
+ }
}
Modified: trunk/src/schmitzm/jfree/feature/style/FeatureScatterChartStyle.java
===================================================================
--- trunk/src/schmitzm/jfree/feature/style/FeatureScatterChartStyle.java 2009-08-01 18:26:53 UTC (rev 276)
+++ trunk/src/schmitzm/jfree/feature/style/FeatureScatterChartStyle.java 2009-08-01 19:55:40 UTC (rev 277)
@@ -183,16 +183,10 @@
* Creates an appropriate {@link Dataset} for the attributes defined
* by this style (according to the attributes types in the given
* {@link FeatureCollection}) and calls {@link #applyToDataset(Dataset)}.
- * @see schmitzm.jfree.feature.style.FeatureChartStyle#applyToFeatureCollection(org.geotools.feature.FeatureCollection)
*/
@Override
public JFreeChart applyToFeatureCollection(FeatureCollection fc) {
- // TODO: Check the attribute data and create a CategoryDataset if
- // a non-numeric column is specified
- Dataset dataset = FeatureChartUtil.createXYDataset(
- fc,
- this
- );
+ Dataset dataset = FeatureChartUtil.createDataset(fc,this);
return applyToDataset(dataset);
}
}
More information about the Schmitzm-commits
mailing list