[Schmitzm-commits] r283 - in trunk/src/schmitzm: geotools/feature geotools/gui jfree jfree/chart jfree/chart/renderer jfree/chart/selection jfree/chart/style jfree/feature
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Mon Aug 3 01:16:15 CEST 2009
Author: mojays
Date: 2009-08-03 01:16:13 +0200 (Mon, 03 Aug 2009)
New Revision: 283
Added:
trunk/src/schmitzm/jfree/chart/renderer/PointSelectionXYRenderer.java
trunk/src/schmitzm/jfree/feature/FeatureChartPanel.java
Modified:
trunk/src/schmitzm/geotools/feature/FeatureUtil.java
trunk/src/schmitzm/geotools/gui/MouseSelectionTracker.java
trunk/src/schmitzm/jfree/JFreeChartUtil.java
trunk/src/schmitzm/jfree/chart/ChartMouseSelectionTracker.java
trunk/src/schmitzm/jfree/chart/SelectableChartPanel.java
trunk/src/schmitzm/jfree/chart/renderer/SelectionXYLineAndShapeRenderer.java
trunk/src/schmitzm/jfree/chart/selection/DatasetSelectionModelProvider.java
trunk/src/schmitzm/jfree/chart/style/AbstractChartStyle.java
trunk/src/schmitzm/jfree/chart/style/BasicChartStyle.java
Log:
Chart selection via single click.
Subtitle applied from ChartStyle.
Highlight rendering of selected chart data re-structured (special highlight datasets in plot).
Modified: trunk/src/schmitzm/geotools/feature/FeatureUtil.java
===================================================================
--- trunk/src/schmitzm/geotools/feature/FeatureUtil.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/geotools/feature/FeatureUtil.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -538,7 +538,7 @@
*/
public static Vector<Feature> sortFeatures(FeatureIterator fi, String attrName) {
// First create a SortedMap with CollisionList
- SortedMap<Comparable, Vector<Feature>> sortedFeatureLists = new TreeMap<Comparable, 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
@@ -546,7 +546,7 @@
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!)
- Comparable xValue = (Comparable)attrValue;
+ Comparable<?> xValue = (Comparable<?>)attrValue;
if ( xValue == null )
continue;
@@ -590,7 +590,7 @@
FeatureIterator fi = fc.features();
// Array fuer die Attribut-Werte eines Features
Object[] fValues = new Object[resultType.getAttributeCount()];
- for ( Feature f = null; fi.hasNext(); ) {
+ for ( ; fi.hasNext(); ) {
// Werte der alten Attribute in Array schreiben
fi.next().getAttributes(fValues);
// Default-Werte der neuen Attribute in Array schreiben
Modified: trunk/src/schmitzm/geotools/gui/MouseSelectionTracker.java
===================================================================
--- trunk/src/schmitzm/geotools/gui/MouseSelectionTracker.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/geotools/gui/MouseSelectionTracker.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -35,14 +35,49 @@
/**
* Extends the geotools {@link org.geotools.gui.swing.MouseSelectionTracker} with an
- * enable/disable functionality.
+ * enable/disable functionality. Furthermore the tracker (optionally)
+ * also reacts on single clicks.
+ * @see #setSelectionMode(SelectionMode)
* @author <a href="mailto:Martin.Schmitz at koeln.de">Martin Schmitz</a>
*/
public abstract class MouseSelectionTracker extends MouseSelectionTracker_Public {
+ /** Selection events the tracker reacts on. */
+ public enum SelectionMode {
+ /** Tracker reacts on single clicks as well as on
+ * window selections. */
+ ALL,
+ /** Tracker reacts only on single clicks. Window selections
+ * are ignored. */
+ ONLY_SINGLE_CLICK,
+ /** Tracker reacts only on window selection. Single clicks
+ * are ignored. */
+ ONLY_WINDOW_SELECTION
+ }
+
/** Indicates whether the tracker reacts on mouse events. */
protected boolean enabled = true;
+ /** Specifies the selection events the tracker reacts on. */
+ protected SelectionMode selectionMode = null;
/**
+ * Creates a new tracker, which reacts only on window
+ * selection events (default geotools behavior for
+ * {@link org.geotools.gui.swing.MouseSelectionTracker}).
+ */
+ public MouseSelectionTracker() {
+ this(SelectionMode.ONLY_WINDOW_SELECTION);
+ }
+
+ /**
+ * Creates a new tracker.
+ * @param mode specifies the selection events the tracker reacts on
+ */
+ public MouseSelectionTracker(SelectionMode mode) {
+ super();
+ setSelectionMode(mode);
+ }
+
+ /**
* Returns whether the tracker reacts on mouse events or not.
*/
public boolean isEnabled() {
@@ -57,15 +92,36 @@
}
/**
- * Ignores the event if tracker is disabled. Otherwise the
- * super method is called.
+ * Sets the selection events the tracker reacts on.
+ * @param mode the mode to set
*/
+ public void setSelectionMode(SelectionMode mode) {
+ this.selectionMode = mode;
+ }
+
+ /**
+ * Returns the selection events the tracker reacts on.
+ */
+ public SelectionMode getSelectionMode() {
+ return selectionMode;
+ }
+
+ /**
+ * Ignores the event if tracker is disabled or selection mode
+ * is {@link SelectionMode#ONLY_WINDOW_SELECTION}. Otherwise
+ * {@link #selectionPerformed(int, int, int, int)} is called for
+ * the selected point.
+ */
@Override
public void mouseClicked(MouseEvent e) {
- if ( !isEnabled() )
+ if ( SelectionMode.ONLY_WINDOW_SELECTION.equals(getSelectionMode()) ||
+ !isEnabled() || e.getButton() != MouseEvent.BUTTON1 )
return;
super.mouseClicked(e);
- }
+
+ int clickX = e.getX();
+ int clickY = e.getY();
+ selectionPerformed(clickX, clickY, clickX, clickY);}
/**
* Ignores the event if tracker is disabled. Otherwise the
@@ -112,12 +168,14 @@
}
/**
- * Ignores the event if tracker is disabled. Otherwise the
- * super method is called.
+ * Ignores the event if tracker is disabled or selection mode
+ * is {@link SelectionMode#ONLY_SINGLE_CLICK}, so that the
+ * dragging rectangle is not drawn.
*/
@Override
public void mouseDragged(MouseEvent e) {
- if ( !isEnabled() )
+ if ( SelectionMode.ONLY_SINGLE_CLICK.equals( getSelectionMode() ) ||
+ !isEnabled() )
return;
super.mouseDragged(e);
}
Modified: trunk/src/schmitzm/jfree/JFreeChartUtil.java
===================================================================
--- trunk/src/schmitzm/jfree/JFreeChartUtil.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/jfree/JFreeChartUtil.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -30,7 +30,10 @@
package schmitzm.jfree;
import java.awt.Color;
+import java.util.HashMap;
import java.util.Locale;
+import java.util.Map;
+import java.util.Vector;
import org.apache.log4j.Logger;
import org.jfree.chart.JFreeChart;
@@ -41,6 +44,7 @@
import org.jfree.chart.event.RendererChangeListener;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.labels.XYToolTipGenerator;
+import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
@@ -66,12 +70,15 @@
import org.jfree.chart.urls.XYURLGenerator;
import org.jfree.data.function.Function2D;
import org.jfree.data.function.LineFunction2D;
+import org.jfree.data.general.Dataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.statistics.Regression;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeriesCollection;
+import schmitzm.jfree.chart.renderer.SelectionRenderer;
import schmitzm.jfree.chart.renderer.SelectionXYLineAndShapeRenderer;
+import schmitzm.jfree.chart.selection.DatasetSelectionModel;
import schmitzm.jfree.chart.style.BasicChartStyle;
import schmitzm.jfree.chart.style.ChartStyle;
import schmitzm.jfree.chart.style.ChartStyleXMLFactory;
@@ -164,7 +171,7 @@
if ( stepped )
return new XYStepRenderer();
// normal line renderer
- return new SelectionXYLineAndShapeRenderer(true, false);
+ return new XYLineAndShapeRenderer(true, false);
case AREA: // Apply stacked
if ( stacked ) {
// "stacked" and "stepped" can not be applied the same time
@@ -237,8 +244,172 @@
throw new UnsupportedOperationException("CategoryItemRenderer could not be created for chart type: "+type);
}
+ /**
+ * Returns the renderer for the {@code i}-th dataset of a plot.
+ * @param plot a plot
+ * @param index the dataset index
+ * @return the primary renderer if no specific renderer is
+ * set for dataset {@code i}
+ */
+ public static Object getRendererForDataset(Plot plot, int i) {
+ Object renderer = null;
+ if ( plot instanceof XYPlot ) {
+ renderer = ((XYPlot)plot).getRenderer(i);
+ if ( renderer == null )
+ renderer = ((XYPlot)plot).getRenderer();
+ }
+
+ if ( plot instanceof CategoryPlot ) {
+ renderer = ((CategoryPlot)plot).getRenderer(i);
+ if ( renderer == null )
+ renderer = ((CategoryPlot)plot).getRenderer();
+ }
+
+ return renderer;
+ }
+
+ /**
+ * Searchs the renderers of a plot for {@link SelectionRenderer} for
+ * a {@link Dataset}.
+ * @param plot the plot to check for renderer
+ * @param dataset the dataset a {@link SelectionRenderer} is
+ * searched for
+ * @return {@code null} if there is no {@link SelectionRenderer} defined
+ * for the dataset
+ */
+ public static SelectionRenderer<?> getSelectionRendererForDataset(Plot plot, Dataset dataset) {
+ if ( plot instanceof XYPlot ) {
+ XYPlot xyPlot = (XYPlot)plot;
+ for (int i=0; i<xyPlot.getDatasetCount(); i++) {
+ Dataset d = xyPlot.getDataset(i);
+ if ( d != dataset )
+ continue;
+ // determine renderer for dataset (if no renderer is set,
+ // take the primary renderer)
+ XYItemRenderer r = xyPlot.getRenderer(i);
+ if ( r == null )
+ r = xyPlot.getRenderer();
+ // stop search, if renderer is a SelectionRenderer
+ if ( r instanceof SelectionRenderer<?> )
+ return (SelectionRenderer<?>)r;
+ }
+ }
+
+ if ( plot instanceof CategoryPlot ) {
+ CategoryPlot catPlot = (CategoryPlot)plot;
+ for (int i=0; i<catPlot.getDatasetCount(); i++) {
+ Dataset d = catPlot.getDataset(i);
+ if ( d != dataset )
+ continue;
+ // determine renderer for dataset (if no renderer is set,
+ // take the primary renderer)
+ CategoryItemRenderer r = catPlot.getRenderer(i);
+ if ( r == null )
+ r = catPlot.getRenderer();
+ // stop search, if renderer is a SelectionRenderer
+ if ( r instanceof SelectionRenderer<?> )
+ return (SelectionRenderer<?>)r;
+ }
+ }
+
+ return null;
+ }
/**
+ * Searchs the renderers of a plot for {@link SelectionRenderer} for
+ * a {@link Dataset} and returns its {@link DatasetSelectionModel}.
+ * @param plot the plot to check for renderer
+ * @param dataset the dataset a {@link SelectionRenderer} is
+ * searched for
+ * @return {@code null} if there is no {@link SelectionRenderer} defined
+ * for the dataset
+ */
+ public static DatasetSelectionModel<?> getSelectionModelForDataset(Plot plot, Dataset dataset) {
+ SelectionRenderer<?> selRenderer = getSelectionRendererForDataset(plot, dataset);
+ if ( selRenderer != null )
+ return selRenderer.getSelectionModel();
+ return null;
+ }
+
+ /**
+ * Returns all {@link SelectionRenderer} for a {@link Plot}.
+ * @param plot the plot to check for renderer
+ * @return never {@code null}
+ */
+ public static Map<Integer,SelectionRenderer<?>> getSelectionRenderer(Plot plot) {
+ Map<Integer,SelectionRenderer<?>> selRenderer = new HashMap<Integer,SelectionRenderer<?>>();
+
+ if ( plot instanceof XYPlot ) {
+ XYPlot xyPlot = (XYPlot)plot;
+ for (int i=0; i<xyPlot.getRendererCount(); i++) {
+ XYItemRenderer r = xyPlot.getRenderer(i);
+ if ( r instanceof SelectionRenderer<?> )
+ selRenderer.put(i, (SelectionRenderer<?>)r);
+ }
+ }
+
+ if ( plot instanceof CategoryPlot ) {
+ CategoryPlot catPlot = (CategoryPlot)plot;
+ for (int i=0; i<catPlot.getRendererCount(); i++) {
+ CategoryItemRenderer r = catPlot.getRenderer(i);
+ if ( r instanceof SelectionRenderer<?> )
+ selRenderer.put(i, (SelectionRenderer<?>)r);
+ }
+ }
+
+ return selRenderer;
+ }
+
+ /**
+ * Searchs the renderers of a plot for all {@link SelectionRenderer}
+ * and returns their {@link DatasetSelectionModel DatasetSelectionModels}.
+ * @param plot the plot to check for renderer
+ * @return never {@code null}
+ */
+ public static Map<Integer,DatasetSelectionModel<?>> getSelectionModels(Plot plot) {
+ Map<Integer,SelectionRenderer<?>> selRenderer = getSelectionRenderer(plot);
+ Map<Integer,DatasetSelectionModel<?>> selModels = new HashMap<Integer, DatasetSelectionModel<?>>();
+ for (int dataset : selRenderer.keySet())
+ selModels.put(dataset, selRenderer.get(dataset).getSelectionModel());
+ return selModels;
+ }
+
+ /**
+ * Returns the (first) dataset of a {@link Plot} which is rendererd
+ * by a renderer.
+ * @param plot the plot which holds the datasets and renderer
+ * @param renderer the renderer a dataset is seached for
+ * @return {@code null} if there is no dataset which is rendered
+ * by the given renderer
+ */
+ public static Dataset getDatasetForRenderer(Plot plot, Object renderer) {
+ if ( plot instanceof XYPlot ) {
+ XYPlot xyPlot = (XYPlot)plot;
+ for (int i=0; i<xyPlot.getRendererCount(); i++)
+ if ( xyPlot.getRenderer(i) == renderer )
+ return xyPlot.getDataset(i);
+ }
+
+ if ( plot instanceof CategoryPlot ) {
+ CategoryPlot catPlot = (CategoryPlot)plot;
+ for (int i=0; i<catPlot.getRendererCount(); i++)
+ if ( catPlot.getRenderer(i) == renderer )
+ return catPlot.getDataset(i);
+ }
+
+ return null;
+ }
+
+ /**
+ * Applies general dataset properties to a {@link Dataset}.
+ * @param dataset dataset the properties are applied to
+ * @param sample dataset the properties are taken from
+ */
+ public static void applyDatasetProperties(Dataset dataset, Dataset sample) {
+ dataset.setGroup( sample.getGroup() );
+ }
+
+ /**
* Creates a {@link JFreeChart} which shows a point for each data iten and
* a the appropriate regression line.
* @param dataset the data
@@ -259,12 +430,7 @@
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
XYToolTipGenerator toolTipGenerator = new StandardXYToolTipGenerator();
XYURLGenerator urlGenerator = new StandardXYURLGenerator();
- XYItemRenderer renderer = new SelectionXYLineAndShapeRenderer(false, true) {
- @Override
- public FeatureSeriesDatasetSelectionModel createSelectionModel(XYDataset dataset) {
- return new FeatureSeriesDatasetSelectionModel(dataset);
- }
- };
+ XYItemRenderer renderer = new XYLineAndShapeRenderer(false, true);
renderer.setBaseToolTipGenerator(toolTipGenerator);
renderer.setURLGenerator(urlGenerator);
@@ -289,7 +455,7 @@
* @param seriesKey the key for the created dataset
* @param sampleCnt count of created samples
*/
- public static XYDataset createRegressionLineDataset(XYSeriesCollection dataset, int series, Comparable seriesKey, int sampleCount) {
+ public static XYDataset createRegressionLineDataset(XYSeriesCollection dataset, int series, Comparable<?> seriesKey, int sampleCount) {
double minX = dataset.getSeries(0).getMinX();
double maxX = dataset.getSeries(0).getMaxX();
return createRegressionLineDataset(dataset,series,seriesKey,minX,maxX,sampleCount);
@@ -304,7 +470,7 @@
* @param endX the last value the sample data is created for
* @param sampleCnt count of created samples
*/
- public static XYDataset createRegressionLineDataset(XYDataset dataset, int series, Comparable seriesKey, double startX, double endX, int sampleCount) {
+ public static XYDataset createRegressionLineDataset(XYDataset dataset, int series, Comparable<?> seriesKey, double startX, double endX, int sampleCount) {
double[] coefficients = Regression.getOLSRegression(dataset, series);
Function2D curve = new LineFunction2D(coefficients[0], coefficients[1]);
return DatasetUtilities.sampleFunction2D(curve, startX, endX, 2, seriesKey);
@@ -327,6 +493,7 @@
}
+
//###################
// BISHER NUR WILDE TESTS
//###################
Modified: trunk/src/schmitzm/jfree/chart/ChartMouseSelectionTracker.java
===================================================================
--- trunk/src/schmitzm/jfree/chart/ChartMouseSelectionTracker.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/jfree/chart/ChartMouseSelectionTracker.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -29,6 +29,7 @@
******************************************************************************/
package schmitzm.jfree.chart;
+import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.HashSet;
import java.util.Set;
@@ -41,7 +42,9 @@
import schmitzm.geotools.gui.MouseSelectionTracker;
/**
- * This tracker listens to mouse window selections on a {@link ChartPanel}.
+ * This tracker listens to mouse window selections and single mouse
+ * clicks on a {@link ChartPanel}. It determines all selected
+ * {@link XYItemEntity XYItemEntities}.<b>
* @author <a href="mailto:Martin.Schmitz at koeln.de">Martin Schmitz</a>
*/
public abstract class ChartMouseSelectionTracker extends MouseSelectionTracker {
@@ -52,10 +55,21 @@
* Creates a new listener.
* @param panel the chart panel connected to the listener (used to
* determine the {@link EntityCollection})
+ * @param mode specifies the selection events the tracker reacts on
*/
+ public ChartMouseSelectionTracker(ChartPanel panel, SelectionMode mode) {
+ super(mode);
+ this.chartPanel = panel;
+ }
+
+ /**
+ * Creates a new listener which reacts on single clicks as well
+ * as on window selection events.
+ * @param panel the chart panel connected to the listener (used to
+ * determine the {@link EntityCollection})
+ */
public ChartMouseSelectionTracker(ChartPanel panel) {
- super();
- this.chartPanel = panel;
+ this(panel, SelectionMode.ALL);
}
/**
@@ -66,20 +80,34 @@
protected void selectionPerformed(int ox, int oy, int px, int py) {
// Create rectangle for selection window
Rectangle2D selectedArea = new Rectangle2D.Double(
- Math.min(ox,px),
- Math.min(oy,py),
- Math.abs(ox-px),
- Math.abs(oy-py) );
+ Math.min(ox,px),
+ Math.min(oy,py),
+ Math.abs(ox-px),
+ Math.abs(oy-py) );
+ // If not a window is selected, but a point, create also
+ // an point object for the click location
+ Point2D selectedPoint = null;
+ if ( ox == px && oy == py )
+ selectedPoint = new Point2D.Double(ox,oy);
+
+ // ignore window selection if ONLY_SINGLE_CLICK is set
+ if ( selectedPoint == null &&
+ SelectionMode.ONLY_SINGLE_CLICK.equals(getSelectionMode()) )
+ return;
// Check every chart data points if the selection area
- // contains it
+ // contains it (or it contains the selected point)
HashSet<XYItemEntity> selectedEntities = new HashSet<XYItemEntity>();
for( Object entityObj : chartPanel.getChartRenderingInfo().getEntityCollection().getEntities() ) {
ChartEntity entity = (ChartEntity)entityObj;
// ignore all non-data entities
if ( !(entity instanceof XYItemEntity) )
continue;
- if ( entity.getArea().intersects(selectedArea) )
+
+ // on point click, check whether point is inside the
+ // entity area, otherwise check intersection
+ if ( selectedPoint != null && entity.getArea().contains(selectedPoint) ||
+ selectedPoint == null && entity.getArea().intersects(selectedArea) )
selectedEntities.add( (XYItemEntity)entity );
}
selectionPerformed(selectedArea, selectedEntities);
Modified: trunk/src/schmitzm/jfree/chart/SelectableChartPanel.java
===================================================================
--- trunk/src/schmitzm/jfree/chart/SelectableChartPanel.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/jfree/chart/SelectableChartPanel.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -38,15 +38,26 @@
import org.apache.log4j.Logger;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.entity.XYItemEntity;
+import org.jfree.chart.event.ChartChangeEvent;
+import org.jfree.chart.event.ChartChangeEventType;
+import org.jfree.chart.plot.CategoryPlot;
+import org.jfree.chart.plot.DatasetRenderingOrder;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.AbstractRenderer;
+import org.jfree.chart.renderer.category.AbstractCategoryItemRenderer;
+import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
+import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.Dataset;
import org.jfree.data.xy.XYDataset;
+import schmitzm.jfree.JFreeChartUtil;
+import schmitzm.jfree.chart.renderer.PointSelectionXYRenderer;
+import schmitzm.jfree.chart.renderer.SelectionRenderer;
import schmitzm.jfree.chart.selection.DatasetSelectionModel;
-import schmitzm.jfree.chart.selection.DatasetSelectionModelProvider;
import schmitzm.jfree.chart.selection.SeriesDatasetSelectionModel;
+import schmitzm.jfree.feature.FeatureSeriesDatasetSelectionModel;
import schmitzm.lang.LangUtil;
/**
@@ -62,7 +73,7 @@
*/
public class SelectableChartPanel extends org.jfree.chart.ChartPanel {
/** Used for log and debug messages. */
- protected Logger LOGGER = LangUtil.createLogger(this);
+ private static Logger LOGGER = LangUtil.createLogger(SelectableChartPanel.class);
/**
* Types of window selection on chart panel.
@@ -152,47 +163,51 @@
Set<XYItemEntity> selectedEntities) {
LOGGER.debug(selectedEntities.size() + " objects selected");
+ Plot plot = getChart().getPlot();
+
// remember all changed selection models to reset
- // "valueAdjusting"
- // property at the end
+ // "valueAdjusting" property at the end
Set<DatasetSelectionModel<?>> changedModels = new HashSet<DatasetSelectionModel<?>>();
- Plot plot = getChart().getPlot();
+ // if selection mode is SELECT_SET all models change
+ // (also these which are not in the selectedEntities
+ // anymore!), because they must be cleared
+ if ( windowSelectionMode == WindowSelectionMode.SELECT_SET ) {
+ for ( DatasetSelectionModel<?> selModel : JFreeChartUtil.getSelectionModels(plot).values() ) {
+ changedModels.add(selModel);
+ selModel.setValueIsAdjusting(true);
+ selModel.clearSelection();
+ }
+ }
+
for (Iterator<XYItemEntity> i = selectedEntities.iterator(); i
.hasNext();) {
XYItemEntity e = i.next();
Dataset dataset = e.getDataset();
- DatasetSelectionModel<?> selModel = null;
- if (plot instanceof XYPlot) {
- XYItemRenderer renderer = ((XYPlot) plot)
- .getRendererForDataset((XYDataset) dataset);
- if (renderer instanceof DatasetSelectionModelProvider)
- selModel = ((DatasetSelectionModelProvider<?>) renderer)
- .getSelectionModel();
- }
-
+ DatasetSelectionModel<?> selModel = JFreeChartUtil.getSelectionModelForDataset(
+ plot, dataset);
// set "valueAdjusting" property for selection model and
// remember the
// model to reset the property at the end
if (selModel != null) {
selModel.setValueIsAdjusting(true);
- /*
- * If we do a SELCTION_SET and this is the first time we
- * change this selection model, let's clear it before
- * adding all the selected object.
- */
- if (!changedModels.contains(selModel)
- && windowSelectionMode == WindowSelectionMode.SELECT_SET){
- selModel.clearSelection();
- }
+//MS: now done above!
+// /*
+// * If we do a SELCTION_SET and this is the first time we
+// * change this selection model, let's clear it before
+// * adding all the selected object.
+// */
+// if (!changedModels.contains(selModel)
+// && windowSelectionMode == WindowSelectionMode.SELECT_SET){
+// selModel.clearSelection();
+// }
changedModels.add(selModel);
}
// perform the selection change
if (selModel instanceof SeriesDatasetSelectionModel) {
int series = e.getSeriesIndex();
- Comparable seriesKey = e.getDataset().getSeriesKey(
- series);
+ Comparable<?> seriesKey = e.getDataset().getSeriesKey(series);
int item = e.getItem();
final SeriesDatasetSelectionModel seriesDatasetSelectionModel = (SeriesDatasetSelectionModel) selModel;
@@ -244,50 +259,6 @@
};
addMouseListener(selectionTracker);
setWindowSelectionMode(WindowSelectionMode.ZOOM_IN_CHART);
-
- // XYPlot p = (XYPlot)getChart().getPlot();
- // XYLineAndShapeRenderer r = (XYLineAndShapeRenderer)p.getRenderer();
-
- //
- // XYItemRenderer r2 = new
- // XYLineAndShapeRenderer(r.getBaseLinesVisible(),
- // r.getBaseShapesVisible()) {
- // public void drawItem(Graphics2D g, XYItemRendererState state,
- // Rectangle2D dataArea,
- // PlotRenderingInfo info,
- // XYPlot plot,
- // ValueAxis domainAxis,
- // ValueAxis rangeAxis,
- // XYDataset dataset,
- // int series,
- // int item,
- // CrosshairState crosshairState,
- // int pass) {
- // if ( !selectedIdx.contains(item) )
- // return;
- //
- // super.drawItem(g, state, dataArea, info, plot, domainAxis, rangeAxis,
- // dataset, series, item, crosshairState, pass);
- // }
- // };
- // r.setBasePaint(Color.gray);
- // r2.setBasePaint(Color.YELLOW);
- // int datasetCount = p.getDatasetCount();
- // p.setDataset(datasetCount, p.getDataset());
- // p.setRenderer(datasetCount, r2);
- // p.setSeriesRenderingOrder(SeriesRenderingOrder.REVERSE);
-
- // addChartMouseListener( new ChartMouseListener() {
- // @Override
- // public void chartMouseClicked(ChartMouseEvent e) {
- // System.err.println("MouseClicked: "+e.getEntity());
- // }
- // @Override
- // public void chartMouseMoved(ChartMouseEvent e) {
- // System.err.println("MouseMoved: "+e.getEntity());
- // }
- // });
-
}
/**
@@ -298,7 +269,24 @@
repaint();
}
- /**
+ /**
+ * Sets the behavior of the chart panel on window selections via mouse.
+ * @param mode new selection mode
+ */
+ public void setWindowSelectionMode(WindowSelectionMode mode) {
+ this.windowSelectionMode = mode;
+ updateStatesForWindowSelectionMode();
+ }
+
+ /**
+ * Returns the behavior of the chart panel on window selections via mouse.
+ * @param selectionMode new selection mode
+ */
+ public WindowSelectionMode getWindowSelectionMode() {
+ return this.windowSelectionMode;
+ }
+
+ /**
* After setting a new chart the zoom relevant properties are reset
* according to the new chart. After calling the super-method, this methods
* resets the properties according to the current
@@ -312,6 +300,9 @@
// chart properties!
// But we do not want them changed, so reset the states.
updateStatesForWindowSelectionMode();
+
+ // create renderers to highlight the selected items
+ updateSelectionRenderers();
}
/**
@@ -324,32 +315,132 @@
getFillZoomRectangle());
// enable/disable the selection functionality
if (selectionTracker != null)
- selectionTracker
- .setEnabled(windowSelectionMode != WindowSelectionMode.ZOOM_IN_CHART);
+ selectionTracker.setEnabled(windowSelectionMode != WindowSelectionMode.ZOOM_IN_CHART);
}
-
+
/**
- * Sets the behavior of the chart panel on window selections via mouse.
- *
- * @param mode
- * new selection mode
+ * This methods creates a {@link SelectionRenderer} for each {@link Dataset}
+ * in the plot to realize the highlight of the selected items.
*/
- public void setWindowSelectionMode(WindowSelectionMode mode) {
- this.windowSelectionMode = mode;
- updateStatesForWindowSelectionMode();
-
+ protected void updateSelectionRenderers() {
+ if ( getChart() == null || getChart().getPlot() == null )
+ return;
+ Plot plot = getChart().getPlot();
+
+ if ( plot instanceof XYPlot ) {
+ XYPlot xyPlot = (XYPlot)plot;
+ // remove all existing SelectionRenderer
+ for (int i=0; i<xyPlot.getRendererCount(); i++)
+ if ( xyPlot.getRenderer(i) instanceof SelectionRenderer ) {
+ xyPlot.setDataset(i, null);
+ xyPlot.setRenderer(i, null, false);
+ }
+ // add an SelectionRenderer for every "normal" renderer
+ int baseDatasetCount = xyPlot.getDatasetCount();
+ for (int i=0; i<baseDatasetCount; i++) {
+ XYDataset dataset = xyPlot.getDataset(i);
+ XYItemRenderer datasetRenderer = (XYItemRenderer)JFreeChartUtil.getRendererForDataset(xyPlot, i);
+ // Create SelectionRenderer
+ XYItemRenderer selRenderer = (XYItemRenderer)createSelectionRenderer(dataset);
+ int selRendererIdx = baseDatasetCount+i;
+ // Add the new SelectionRenderer with the original dataset
+ xyPlot.setDataset(selRendererIdx, dataset);
+ xyPlot.setRenderer(selRendererIdx, selRenderer, false);
+ applyRendererPropertiesToSelectionRenderer(dataset,(AbstractRenderer)datasetRenderer,(AbstractRenderer)selRenderer);
+ }
+ // revert the rendering order (0 to X) so that the SelectionRenderers
+ // are rendered last and the selected items are shown in foreground
+ xyPlot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
+ }
+
+ if ( plot instanceof CategoryPlot ) {
+ CategoryPlot catPlot = (CategoryPlot)plot;
+ // remove all existing SelectionRenderer
+ for (int i=0; i<catPlot.getRendererCount(); i++)
+ if ( catPlot.getRenderer(i) instanceof SelectionRenderer ) {
+ catPlot.setDataset(i, null);
+ catPlot.setRenderer(i, null, false);
+ }
+ // add an SelectionRenderer for every "normal" renderer
+ int baseDatasetCount = catPlot.getDatasetCount();
+ for (int i=0; i<baseDatasetCount; i++) {
+ CategoryDataset dataset = catPlot.getDataset(i);
+ CategoryItemRenderer datasetRenderer = (CategoryItemRenderer)JFreeChartUtil.getRendererForDataset(catPlot, i);
+ // Create SelectionRenderer
+ CategoryItemRenderer selRenderer = (CategoryItemRenderer)createSelectionRenderer(dataset);
+ int selRendererIdx = baseDatasetCount+i;
+ // Add the new SelectionRenderer with the original dataset
+ catPlot.setDataset(selRendererIdx, dataset);
+ catPlot.setRenderer(selRendererIdx, selRenderer, false);
+ applyRendererPropertiesToSelectionRenderer(dataset,(AbstractRenderer)datasetRenderer,(AbstractRenderer)selRenderer);
+ }
+ // revert the rendering order (0 to X) so that the SelectionRenderers
+ // are rendered last and the selected items are shown in foreground
+ catPlot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
+ }
+
+ // fire event about the renderer changes
+ JFreeChartUtil.fireChangeEvent(plot);
}
- /**
- * Returns the behavior of the chart panel on window selections via mouse.
- *
- * @param mode
- * new selection mode
- */
- public WindowSelectionMode getWindowSelectionMode() {
- return this.windowSelectionMode;
- }
+ /**
+ * Creates an adequate selection renderer for a dataset. This implementation
+ * returns a renderer which draws only the data points. Sub-classes can
+ * override this method to create different renderers or renderers with
+ * different selection models (e.g. {@link FeatureSeriesDatasetSelectionModel})
+ * for special purposes.
+ * @param dataset a dataset
+ * @return besides {@link SelectionRenderer} the returned object must be
+ * an {@link AbstractRenderer}
+ */
+ protected SelectionRenderer<?> createSelectionRenderer(Dataset dataset) {
+ if ( dataset instanceof XYDataset )
+ return new PointSelectionXYRenderer();
+ LOGGER.warn("No selection renderer provided for dataset: "+LangUtil.getSimpleClassName(dataset));
+ return null;
+ }
+
+ /**
+ * Applies some rendering properties to the (new) selection renderer.
+ * This methods simply sets the series shape of the selection renderer
+ * to the shape of the origin renderer, so that the highlighted data
+ * items are drawn the same way as the origin data items.
+ * @param dataset the dataset for the selection renderer
+ * @param originRenderer the origin renderer for the dataset (should not
+ * be changed!)
+ * @param selRenderer the selection renderer to apply the properties to
+ */
+ protected <E> void applyRendererPropertiesToSelectionRenderer(Dataset dataset, AbstractRenderer originRenderer, AbstractRenderer selRenderer) {
+ if ( selRenderer == null || originRenderer == null )
+ return;
+
+ selRenderer.setBaseShape( originRenderer.lookupSeriesShape(0) );
+ selRenderer.setBaseStroke( originRenderer.lookupSeriesStroke(0) );
+
+ if ( dataset instanceof XYDataset ) {
+ for (int i=0; i<((XYDataset)dataset).getSeriesCount(); i++) {
+ selRenderer.setSeriesShape(i, originRenderer.lookupSeriesShape(i));
+ selRenderer.setSeriesStroke(i, originRenderer.lookupSeriesStroke(i));
+ }
+ }
+ if ( dataset instanceof CategoryDataset ) {
+// for (int i=0; i<((CategoryDataset)dataset).getSeriesCount(); i++)
+// if ( ((CategoryItemRenderer)originRenderer).getSeriesShape(i) != null )
+// ((CategoryItemRenderer)selRenderer).setSeriesShape(i, ((CategoryItemRenderer)originRenderer).getSeriesShape(i));
+ }
+ }
+ /**
+ * If a new dataset is added this method updates the selection
+ * renderers.
+ */
+ @Override
+ public void chartChanged(ChartChangeEvent e) {
+ super.chartChanged(e);
+ if ( ChartChangeEventType.NEW_DATASET.equals( e.getType() ) )
+ updateSelectionRenderers();
+ }
+
/**
* Ignores the event if the window selection mode is not
* {@link WindowSelectionMode#ZOOM_IN_CHART}, to avoid conflicts between the two
@@ -373,5 +464,5 @@
return;
super.mouseMoved(e);
}
-
+
}
Added: trunk/src/schmitzm/jfree/chart/renderer/PointSelectionXYRenderer.java
===================================================================
--- trunk/src/schmitzm/jfree/chart/renderer/PointSelectionXYRenderer.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/jfree/chart/renderer/PointSelectionXYRenderer.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ *
+ * This file is part of the SCHMITZM library - a collection of utility
+ * classes based on Java 1.6, focusing (not only) on Java Swing
+ * and the Geotools library.
+ *
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ *
+ * Contributors:
+ * Martin O. J. Schmitz - initial API and implementation
+ * Stefan A. Krüger - additional utility classes
+ ******************************************************************************/
+package schmitzm.jfree.chart.renderer;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.geom.Rectangle2D;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.axis.ValueAxis;
+import org.jfree.chart.plot.CrosshairState;
+import org.jfree.chart.plot.Plot;
+import org.jfree.chart.plot.PlotRenderingInfo;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYItemRendererState;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.general.Dataset;
+import org.jfree.data.xy.XYDataset;
+
+import schmitzm.jfree.JFreeChartUtil;
+import schmitzm.jfree.chart.selection.SeriesDatasetSelectionModel;
+import schmitzm.lang.LangUtil;
+
+/**
+ * Extends the {@link XYLineAndShapeRenderer} with the
+ * {@link SelectionRenderer} functionality. Additionally redefines
+ * the {@link #drawItem(Graphics2D, XYItemRendererState, Rectangle2D, PlotRenderingInfo, XYPlot, ValueAxis, ValueAxis, XYDataset, int, int, CrosshairState, int)}
+ * method to realize the highlight rendering of the selected
+ * items. <b>Only the selected data points are rendered. No lines
+ * ore areas!</b><br>
+ * <b>Note:</b><br>
+ * An adequate {@link SeriesDatasetSelectionModel} is automatically
+ * created when a new {@link Plot} is set. Manually calling {@link #setSelectionModel(SeriesDatasetSelectionModel)}
+ * is usually not necessary. Overwrite {@link #createAndSetSelectionModel()} to
+ * avoid this behavior.<br>
+ * If no selection model is set, the behavior of this renderer is exactly
+ * like the super class.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ */
+public class PointSelectionXYRenderer extends XYLineAndShapeRenderer implements SelectionRenderer<SeriesDatasetSelectionModel> {
+ /** Used for log and debug messages. */
+ protected Logger LOGGER = LangUtil.createLogger(this);
+
+ /** Holds the selection model, the renderer uses to determine whether a
+ * data item is selected or not. */
+ protected SeriesDatasetSelectionModel selectionModel = null;
+
+ /** Holds the selection color for each series. */
+ protected Map<Integer,Paint> selectionPaint = new HashMap<Integer, Paint>();
+
+ /**
+ * Creates a new renderer.
+ */
+ public PointSelectionXYRenderer() {
+ super(false,true);
+ init();
+ }
+
+ /**
+ * Called by every constructor to initialize the extensions
+ * of this renderer.
+ */
+ protected void init() {
+ // set a default highlight color for the primary series
+ setSelectionPaint(Color.YELLOW);
+ }
+
+ /**
+ * Returns always {@code false}, so that no series of the selection
+ * renderer is visible in the legend.
+ */
+ @Override
+ public boolean isSeriesVisibleInLegend(int series) {
+ return false;
+ }
+
+ /**
+ * Sets the selection model the renderer uses to determine whether
+ * a data item is selected or not.
+ * @param model the selection model
+ */
+ public void setSelectionModel(SeriesDatasetSelectionModel model) {
+ this.selectionModel = model;
+ }
+
+ /**
+ * Returns the selection model the renderer uses to determine whether
+ * a data item is selected or not.
+ */
+ public SeriesDatasetSelectionModel getSelectionModel() {
+ return selectionModel;
+ }
+
+ /**
+ * Creates and sets an adequate {@link SeriesDatasetSelectionModel}
+ * according to the {@link Dataset} of the current {@link Plot}. Automatically
+ * called by {@link #setPlot(XYPlot)}.<br>
+ * Sets the selection model to {@code null} if the renderer is not
+ * connected to a plot or the plot contains no dataset.
+ * @see #createSelectionModel(XYDataset)
+ */
+ public void createAndSetSelectionModel() {
+ XYPlot plot = getPlot();
+ Dataset newDataset = JFreeChartUtil.getDatasetForRenderer(plot,this);
+ if ( getSelectionModel() == null || getSelectionModel().getDataset() != newDataset )
+ setSelectionModel( newDataset != null ? createSelectionModel(newDataset) : null );
+ }
+
+ /**
+ * Creates an adequate {@link SeriesDatasetSelectionModel}
+ * according to the given {@link Dataset}. Subclasses can overwrite this
+ * method to create an alternative {@link SeriesDatasetSelectionModel}.
+ * @param dataset must be a {@link XYDataset}
+ * @throws IllegalArgumentException if {@code dataset} is no {@link XYDataset}
+ */
+ public SeriesDatasetSelectionModel createSelectionModel(Dataset dataset) {
+ if ( !(dataset instanceof XYDataset) )
+ throw new IllegalArgumentException(LangUtil.getSimpleClassName(this)+".createSelectionModel(.) can only be applied for XYDataset: "+LangUtil.getSimpleClassName(dataset));
+ return new SeriesDatasetSelectionModel((XYDataset)dataset);
+ }
+
+ /**
+ * Returns the color, the selected data <b>of the primary series</b>
+ * is rendered with.
+ * @return {@code null} if no selection color is defined
+ * for the series
+ */
+ public Paint getSelectionPaint() {
+ return getSelectionPaint(0);
+ }
+
+ /**
+ * Sets the color, the selected data <b>of the primary series</b>
+ * is rendered with.
+ * @param paint color for the selected data
+ */
+ public void setSelectionPaint(Paint paint) {
+ setSelectionPaint(0, paint);
+ }
+
+ /**
+ * Returns the color, the selected data is rendered with.
+ * @param series the data series
+ * @return {@code null} if no selection color is defined
+ * for the series
+ */
+ public Paint getSelectionPaint(int series) {
+ return selectionPaint.get(series);
+ }
+
+ /**
+ * Sets the color, the selected data is rendered with.
+ * @param series the data series
+ * @param paint color for the selected data
+ */
+ public void setSelectionPaint(int series, Paint paint) {
+ selectionPaint.put(series, paint);
+ }
+
+ /**
+ * Creates and sets a new {@link SeriesDatasetSelectionModel}, if no selection model
+ * is set yet, or the selection model's dataset differs from the dataset of the
+ * new plot.
+ * @param plot the plot rendered by this renderer
+ */
+ public void setPlot(XYPlot plot) {
+ super.setPlot(plot);
+ createAndSetSelectionModel();
+ }
+
+ /**
+ * Sets the rendering color (temporary for the rendering process) to the
+ * {@linkplain #getSelectionPaint(int) highlight color}, if the item is
+ * defined as selected (by the {@linkplain #getSelectionModel() selection model}).
+ */
+ public void drawItem(Graphics2D g,
+ XYItemRendererState state,
+ Rectangle2D dataArea,
+ PlotRenderingInfo info,
+ XYPlot plot,
+ ValueAxis domainAxis,
+ ValueAxis rangeAxis,
+ XYDataset dataset,
+ int series,
+ int item,
+ CrosshairState crosshairState,
+ int pass) {
+
+ // if selection model and color is set and the item is selected
+ // the highlighting selection color is set for the rendering
+ // process; otherwise the item is ignored for rendering!!
+ if ( getSelectionModel() != null ) {
+ Paint selPaint = getSelectionPaint(series);
+ if ( selPaint != null ) {
+ Comparable<?> seriesKey = dataset.getSeriesKey(series);
+ if ( selectionModel.isItemSelected(seriesKey, item) ) {
+ setSeriesPaint( series, selPaint, false );
+ super.drawItem(g, state, dataArea, info, plot, domainAxis, rangeAxis, dataset, series, item, crosshairState, pass);
+ }
+ } else
+ LOGGER.warn("No selection paint set for series "+series+". Series is rendererd normally.");
+ } else
+ LOGGER.debug("No selection model set for renderer. All series rendererd normally.");
+ }
+}
Modified: trunk/src/schmitzm/jfree/chart/renderer/SelectionXYLineAndShapeRenderer.java
===================================================================
--- trunk/src/schmitzm/jfree/chart/renderer/SelectionXYLineAndShapeRenderer.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/jfree/chart/renderer/SelectionXYLineAndShapeRenderer.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -47,6 +47,7 @@
import org.jfree.data.general.Dataset;
import org.jfree.data.xy.XYDataset;
+import schmitzm.jfree.chart.SelectableChartPanel;
import schmitzm.jfree.chart.selection.SeriesDatasetSelectionModel;
import schmitzm.lang.LangUtil;
@@ -64,6 +65,11 @@
* If no selection model is set, the behavior of this renderer is exactly
* like the super class.
* @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ * @deprecated This class is not used anymore because the selection rendering
+ * is no longer realized by the origin dataset renderer (e.g. because
+ * the selected data items should be rendered in the foregound!).
+ * Instead the {@link SelectableChartPanel} inserts explicit
+ * renderers to the plot to draw only the selected data items highlighted.
*/
public class SelectionXYLineAndShapeRenderer extends XYLineAndShapeRenderer implements SelectionRenderer<SeriesDatasetSelectionModel> {
/** Used for log and debug messages. */
@@ -140,8 +146,10 @@
* according to the given {@link Dataset}. Subclasses can overwrite this
* method to create an alternative {@link SeriesDatasetSelectionModel}.
*/
- public SeriesDatasetSelectionModel createSelectionModel(XYDataset dataset) {
- return new SeriesDatasetSelectionModel(dataset);
+ public SeriesDatasetSelectionModel createSelectionModel(Dataset dataset) {
+ if ( !(dataset instanceof XYDataset) )
+ throw new IllegalArgumentException(LangUtil.getSimpleClassName(this)+".createSelectionModel(.) can only be applied for XYDataset: "+LangUtil.getSimpleClassName(dataset));
+ return new SeriesDatasetSelectionModel((XYDataset)dataset);
}
/**
Modified: trunk/src/schmitzm/jfree/chart/selection/DatasetSelectionModelProvider.java
===================================================================
--- trunk/src/schmitzm/jfree/chart/selection/DatasetSelectionModelProvider.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/jfree/chart/selection/DatasetSelectionModelProvider.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -49,10 +49,9 @@
*/
public void setSelectionModel(E model);
-// /**
-// * Creates an adequate selection model for a dataset. An implementation should
-// * simply call {@link DatasetSelectionModel#createInstanceFor(Dataset)}.
-// * @param dataset a dataset
-// */
-// public E createSelectionModel(Dataset dataset);
+ /**
+ * Creates an adequate selection model for a dataset.
+ * @param dataset a dataset
+ */
+ public E createSelectionModel(Dataset dataset);
}
Modified: trunk/src/schmitzm/jfree/chart/style/AbstractChartStyle.java
===================================================================
--- trunk/src/schmitzm/jfree/chart/style/AbstractChartStyle.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/jfree/chart/style/AbstractChartStyle.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -420,12 +420,22 @@
title = new TextTitle();
chart.setTitle( title );
}
-
if ( getTitleStyle().getLabel() != null )
title.setText( getTitleStyle().getLabel() );
if ( getTitleStyle().getPaint() != null )
title.setPaint( getTitleStyle().getPaint() );
+ // Style the chart sub title with chart description
+ if ( getDescStyle() != null ) {
+ if ( chart.getSubtitleCount() == 0 || !(chart.getSubtitle(0) instanceof TextTitle) )
+ chart.addSubtitle(0, new TextTitle());
+ TextTitle subTitle = (TextTitle)chart.getSubtitle(0);
+ if ( getDescStyle().getLabel() != null )
+ subTitle.setText( getDescStyle().getLabel() );
+ if ( getDescStyle().getPaint() != null )
+ subTitle.setPaint( getDescStyle().getPaint() );
+ }
+
// Style the chart axis
Vector<Axis> chartAxis = new Vector<Axis>();
if ( chart.getPlot() instanceof XYPlot ) {
Modified: trunk/src/schmitzm/jfree/chart/style/BasicChartStyle.java
===================================================================
--- trunk/src/schmitzm/jfree/chart/style/BasicChartStyle.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/jfree/chart/style/BasicChartStyle.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -309,9 +309,18 @@
JFreeChart chart = null;
// XYDataset -> XYBarChart
if (dataset instanceof XYDataset) {
+ IntervalXYDataset barDataset = null;
+ if ( dataset instanceof TableXYDataset )
+ barDataset = (IntervalXYDataset)dataset;
+ else {
+ barDataset = new XYBarDataset((XYDataset)dataset, 0.5d);
+ // copy properties to new dataset
+ JFreeChartUtil.applyDatasetProperties(barDataset,dataset);
+ }
+
chart = ChartFactory.createXYBarChart(
null,null,false,null, // Title and axis will be configured in applyToChart(..)
- (IntervalXYDataset)(dataset instanceof TableXYDataset ? (TableXYDataset)dataset : new XYBarDataset( (XYDataset) dataset, 0.5d)),
+ barDataset,
PlotOrientation.VERTICAL,
true,
true,
Added: trunk/src/schmitzm/jfree/feature/FeatureChartPanel.java
===================================================================
--- trunk/src/schmitzm/jfree/feature/FeatureChartPanel.java 2009-08-01 21:27:39 UTC (rev 282)
+++ trunk/src/schmitzm/jfree/feature/FeatureChartPanel.java 2009-08-02 23:16:13 UTC (rev 283)
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ *
+ * This file is part of the SCHMITZM library - a collection of utility
+ * classes based on Java 1.6, focusing (not only) on Java Swing
+ * and the Geotools library.
+ *
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ *
+ * Contributors:
+ * Martin O. J. Schmitz - initial API and implementation
+ * Stefan A. Krüger - additional utility classes
+ ******************************************************************************/
+
+package schmitzm.jfree.feature;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.JFreeChart;
+import org.jfree.data.general.Dataset;
+import org.jfree.data.xy.XYDataset;
+
+import schmitzm.jfree.chart.SelectableChartPanel;
+import schmitzm.jfree.chart.renderer.PointSelectionXYRenderer;
+import schmitzm.jfree.chart.renderer.SelectionRenderer;
+import schmitzm.jfree.chart.selection.DatasetSelectionModel;
+import schmitzm.lang.LangUtil;
+
+/**
+ * This panel is a special {@link SelectableChartPanel} which uses
+ * special {@link DatasetSelectionModel DatasetSelectionModels} to
+ * connect the chart data with features.
+ * @author <a href="mailto:Martin.Schmitz at koeln.de">Martin Schmitz</a>
+ * @version 1.0
+ */
+public class FeatureChartPanel extends SelectableChartPanel {
+ /** Used for log and debug messages. */
+ private static Logger LOGGER = LangUtil.createLogger(FeatureChartPanel.class);
+
+ /**
+ * Creates a new chart panel.
+ */
+ public FeatureChartPanel(JFreeChart chart) {
+ super(chart);
+ }
+
+ /**
+ * Creates a new chart panel.
+ */
+ public FeatureChartPanel(JFreeChart chart, boolean useBuffer) {
+ super(chart, useBuffer);
+ }
+
+ /**
+ * Creates a new chart panel.
+ */
+ public FeatureChartPanel(JFreeChart chart, boolean properties,
+ boolean save, boolean print, boolean zoom, boolean tooltips) {
+ super(chart, properties, save, print, zoom, tooltips);
+ }
+
+ /**
+ * Creates a new chart panel.
+ */
+ public FeatureChartPanel(JFreeChart chart, int width, int height,
+ int minimumDrawWidth, int minimumDrawHeight, int maximumDrawWidth,
+ int maximumDrawHeight, boolean useBuffer, boolean properties,
+ boolean save, boolean print, boolean zoom, boolean tooltips) {
+ super(chart, width, height, minimumDrawWidth, minimumDrawHeight,
+ maximumDrawWidth, maximumDrawHeight, useBuffer, properties,
+ save, print, zoom, tooltips);
+ }
+
+ /**
+ * Creates an adequate selection renderer for a dataset. If provided this
+ * method returns a renderer which uses a {@link FeatureDatasetSelectionModel}
+ * for the dataset. Otherwise the super method is used.
+ * @param dataset a dataset
+ */
+ protected SelectionRenderer<?> createSelectionRenderer(Dataset dataset) {
+ // check whether dataset provides a Feature2DatasetMapping
+ // if not: create a "normal" SelectionRenderer by super-class
+ // method (without "Feature-Synchronizing" functionality)
+ if ( dataset.getGroup() instanceof FeatureDatasetMetaData &&
+ ((FeatureDatasetMetaData)dataset.getGroup()).getMapping() != null ) {
+
+ if ( dataset instanceof XYDataset )
+ return new PointSelectionXYRenderer() {
+ @Override
+ public FeatureSeriesDatasetSelectionModel createSelectionModel(Dataset dataset) {
+ if ( !(dataset instanceof XYDataset) )
+ throw new IllegalArgumentException(LangUtil.getSimpleClassName(this)+".createSelectionModel(.) can only be applied for XYDataset: "+LangUtil.getSimpleClassName(dataset));
+ return new FeatureSeriesDatasetSelectionModel((XYDataset)dataset);
+ }
+ };
+
+ }
+ LOGGER.warn("No Feature2DatasetMapping provided for dataset: "+LangUtil.getSimpleClassName(dataset));
+
+ return super.createSelectionRenderer(dataset);
+ }
+}
More information about the Schmitzm-commits
mailing list