diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/visualization')
73 files changed, 777 insertions, 520 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java b/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java index 187b2473..39d6e359 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java @@ -40,7 +40,6 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.VisFactory; * @apiviz.has SVGPlot * @apiviz.has VisFactory * @apiviz.has Projection oneway - 0:1 - * @apiviz.has Visualization oneway */ public class VisualizationTask extends AnyMap<String> implements Cloneable, Result, Comparable<VisualizationTask> { /** diff --git a/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java b/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java index 663670e0..c4e6c839 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java @@ -64,11 +64,13 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerUtil; * TODO: remove this class * * @apiviz.landmark - * @apiviz.uses ContextChangedEvent oneway - - «emit» * @apiviz.composedOf StyleLibrary * @apiviz.composedOf SelectionResult * @apiviz.composedOf ResultHierarchy * @apiviz.composedOf EventListenerList + * @apiviz.composedOf StyleResult + * @apiviz.composedOf ProjectorFactory + * @apiviz.composedOf VisFactory */ public class VisualizerContext implements DataStoreListener, Result { /** diff --git a/src/de/lmu/ifi/dbs/elki/visualization/VisualizerParameterizer.java b/src/de/lmu/ifi/dbs/elki/visualization/VisualizerParameterizer.java index 8e0be062..36bbb823 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/VisualizerParameterizer.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/VisualizerParameterizer.java @@ -26,7 +26,6 @@ package de.lmu.ifi.dbs.elki.visualization; import java.io.File; import java.util.ArrayList; import java.util.Collection; -import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.regex.Pattern; @@ -165,12 +164,10 @@ public class VisualizerParameterizer implements Parameterizable { * @return New context */ public VisualizerContext newContext(HierarchicalResult result) { - VisualizerContext context = new VisualizerContext(result, stylelib, projectors, factories); if(samplesize > 0) { - Iterator<Relation<?>> iter = ResultUtil.filteredResults(result, Relation.class); - while(iter.hasNext()) { - Relation<?> rel = iter.next(); - if(ResultUtil.filteredResults(rel, SamplingResult.class).hasNext()) { + Collection<Relation<?>> rels = ResultUtil.filterResults(result, Relation.class); + for(Relation<?> rel : rels) { + if(!ResultUtil.filterResults(rel, SamplingResult.class).isEmpty()) { continue; } int size = rel.size(); @@ -181,6 +178,7 @@ public class VisualizerParameterizer implements Parameterizable { } } } + VisualizerContext context = new VisualizerContext(result, stylelib, projectors, factories); return context; } diff --git a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/CloneInlineImages.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/CloneInlineImages.java index a1dd3ba1..30456ba9 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/CloneInlineImages.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/CloneInlineImages.java @@ -46,7 +46,6 @@ import de.lmu.ifi.dbs.elki.visualization.svg.SVGCloneVisible; * Clone an SVG document, inlining temporary and in-memory linked images. * * @author Erich Schubert - * */ public class CloneInlineImages extends SVGCloneVisible { @Override diff --git a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeAppendChild.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeAppendChild.java index 380d2cbf..a5396732 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeAppendChild.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/NodeAppendChild.java @@ -30,8 +30,7 @@ import de.lmu.ifi.dbs.elki.visualization.svg.SVGPlot; /** * Runnable wrapper for appending XML-Elements to existing Elements. * - * @author Remigius Wojdanowski. - * + * @author Remigius Wojdanowski */ public class NodeAppendChild implements Runnable { /** @@ -45,7 +44,7 @@ public class NodeAppendChild implements Runnable { protected Element child; /** - * The plot (for ID updates). May be {code null}. + * The plot (for ID updates). May be {@code null}. */ protected SVGPlot plot; diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/SelectionTableWindow.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/SelectionTableWindow.java index 0c8e7500..754779fe 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/gui/SelectionTableWindow.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/SelectionTableWindow.java @@ -44,6 +44,7 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreEvent; import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener;
import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
@@ -227,8 +228,8 @@ public class SelectionTableWindow extends JFrame implements DataStoreListener, R // Unselect first ...
context.setSelection(new DBIDSelection(remain));
// Now delete them.
- for(DBID id : todel) {
- upd.delete(id);
+ for(DBIDIter iter = todel.iter(); iter.valid(); iter.advance()) {
+ upd.delete(iter.getDBID());
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java index 8b6f4892..3e1348ac 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java @@ -149,6 +149,9 @@ public class DetailView extends SVGPlot implements ResultListener { if(VisualizerUtil.isVisible(task)) { try { Visualization v = task.getFactory().makeVisualization(task.clone(this, context, visi.proj, width, height)); + if (VisualizerUtil.isNoExport(task)) { + v.getLayer().setAttribute(NO_EXPORT_ATTRIBUTE, NO_EXPORT_ATTRIBUTE); + } layers.add(v); layermap.put(task, v); } @@ -291,10 +294,14 @@ public class DetailView extends SVGPlot implements ResultListener { if(VisualizerUtil.isVisible(task)) { // LoggingUtil.warning("Need to recreate a missing layer for " + v); vis = task.getFactory().makeVisualization(task.clone(this, context, visi.proj, width, height)); + if (VisualizerUtil.isNoExport(task)) { + vis.getLayer().setAttribute(NO_EXPORT_ATTRIBUTE, NO_EXPORT_ATTRIBUTE); + } layermap.put(task, vis); this.scheduleUpdate(new InsertVisualization(vis)); } } + // FIXME: ensure layers are ordered correctly! } @Override diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/LayerMap.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/LayerMap.java index c3575e43..36851b85 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/LayerMap.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/LayerMap.java @@ -33,6 +33,9 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; * Class to help keeping track of the materialized layers of the different visualizations. * * @author Erich Schubert + * + * @apiviz.has PlotItem + * @apiviz.has VisualizationTask */ public class LayerMap { /** diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java index 56d6ce32..92ddb0b8 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java @@ -66,9 +66,9 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerUtil; * @apiviz.landmark * @apiviz.has VisualizerContext * @apiviz.composedOf RectangleArranger + * @apiviz.composedOf LayerMap * @apiviz.has DetailViewSelectedEvent * @apiviz.uses DetailView - * @apiviz.uses Projector */ // FIXME: there still is a synchronization issue, that causes the initialization // to be run twice in parallel. @@ -322,6 +322,9 @@ public class OverviewPlot extends SVGPlot implements ResultListener { LoggingUtil.warning("Visualization returned empty layer: " + vis); } else { + if (VisualizerUtil.isNoExport(task)) { + vis.getLayer().setAttribute(NO_EXPORT_ATTRIBUTE, NO_EXPORT_ATTRIBUTE); + } parent.appendChild(vis.getLayer()); } return vis; diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/PlotItem.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/PlotItem.java index cbe5a4be..73ee797e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/PlotItem.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/PlotItem.java @@ -40,6 +40,8 @@ import de.lmu.ifi.dbs.elki.visualization.projections.Projection; * @author Erich Schubert * * @apiviz.composedOf Projection + * @apiviz.composedOf VisualizationTask + * @apiviz.composedOf PlotItem */ public class PlotItem { /** diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/RectangleArranger.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/RectangleArranger.java index 77825a5f..a70393a5 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/RectangleArranger.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/RectangleArranger.java @@ -302,6 +302,10 @@ public class RectangleArranger<T> { } protected void splitRow(int bestey, double besthi) { + assert(bestey < heights.size()); + if (heights.get(bestey) - besthi <= Double.MIN_NORMAL) { + return; + } logger.debugFine("Split row " + bestey); heights.add(bestey + 1, besthi); heights.set(bestey, heights.get(bestey) - besthi); @@ -310,6 +314,10 @@ public class RectangleArranger<T> { } protected void splitCol(int bestex, double bestwi) { + assert(bestex < widths.size()); + if (widths.get(bestex) - bestwi <= Double.MIN_NORMAL) { + return; + } final int rows = heights.size(); logger.debugFine("Split column " + bestex); widths.add(bestex + 1, bestwi); @@ -371,7 +379,7 @@ public class RectangleArranger<T> { { double wsum = 0.0; for(int x = 0; x < cols; x++) { - assert (widths.get(x) > 0) : "Negative width: "+widths.get(x); + assert (widths.get(x) > 0) : "Non-positive width: "+widths.get(x); wsum += widths.get(x); } assert (Math.abs(wsum - twidth) < 1E-10); @@ -379,7 +387,7 @@ public class RectangleArranger<T> { { double hsum = 0.0; for(int y = 0; y < rows; y++) { - assert (heights.get(y) > 0) : "Negative height: "+heights.get(y); + assert (heights.get(y) > 0) : "Non-positive height: "+heights.get(y); hsum += heights.get(y); } assert (Math.abs(hsum - theight) < 1E-10); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java index 95105895..030ea954 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java @@ -45,7 +45,8 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.LabelVisFactory; * * @author Erich Schubert * - * @apiviz.has LinearScale + * @apiviz.uses ScalesResult + * @apiviz.uses Projection1D * * @param <V> Vector type */ diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotFactory.java index 6dcb6271..8b110967 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ParallelPlotFactory.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.projector; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.Iterator;
+import java.util.Collection;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
@@ -49,9 +49,8 @@ public class ParallelPlotFactory implements ProjectorFactory { @Override
public void processNewResult(HierarchicalResult baseResult, Result newResult) {
- Iterator<Relation<?>> rels = ResultUtil.filteredResults(newResult, Relation.class);
- while (rels.hasNext()) {
- Relation<?> rel = rels.next();
+ Collection<Relation<?>> rels = ResultUtil.filterResults(newResult, Relation.class);
+ for(Relation<?> rel : rels) {
// TODO: multi-relational parallel plots
if(TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(rel.getDataTypeInformation())) {
@SuppressWarnings("unchecked")
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java index 755b6fd2..f251733e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java @@ -47,7 +47,8 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.LabelVisFactory; * * @author Erich Schubert * - * @apiviz.has LinearScale + * @apiviz.uses ScalesResult + * @apiviz.uses Projection2D * * @param <V> Vector type */ diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/ClassStylingPolicy.java b/src/de/lmu/ifi/dbs/elki/visualization/style/ClassStylingPolicy.java index 5468a764..82000e42 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/style/ClassStylingPolicy.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/ClassStylingPolicy.java @@ -23,9 +23,8 @@ package de.lmu.ifi.dbs.elki.visualization.style; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.Iterator; - -import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; /** * Styling policy that is based on <em>classes</em>, for example clusters or @@ -41,7 +40,7 @@ public interface ClassStylingPolicy extends StylingPolicy { * @param id Object ID * @return Style number */ - public int getStyleForDBID(DBID id); + public int getStyleForDBID(DBIDRef id); /** * Get the minimum style in use. @@ -63,5 +62,5 @@ public interface ClassStylingPolicy extends StylingPolicy { * @param cnum Class number * @return Iterator over object IDs */ - public Iterator<DBID> iterateClass(int cnum); + public DBIDIter iterateClass(int cnum); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/ClusterStylingPolicy.java b/src/de/lmu/ifi/dbs/elki/visualization/style/ClusterStylingPolicy.java index 9680ec1f..1d329736 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/style/ClusterStylingPolicy.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/ClusterStylingPolicy.java @@ -32,7 +32,8 @@ import java.util.List; import de.lmu.ifi.dbs.elki.data.Cluster; import de.lmu.ifi.dbs.elki.data.Clustering; -import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; @@ -92,7 +93,7 @@ public class ClusterStylingPolicy implements ClassStylingPolicy { } @Override - public int getStyleForDBID(DBID id) { + public int getStyleForDBID(DBIDRef id) { for(int i = 0; i < ids.size(); i++) { if(ids.get(i).contains(id)) { return i; @@ -102,7 +103,7 @@ public class ClusterStylingPolicy implements ClassStylingPolicy { } @Override - public int getColorForDBID(DBID id) { + public int getColorForDBID(DBIDRef id) { for(int i = 0; i < ids.size(); i++) { if(ids.get(i).contains(id)) { return colors.get(i); @@ -122,8 +123,8 @@ public class ClusterStylingPolicy implements ClassStylingPolicy { } @Override - public Iterator<DBID> iterateClass(int cnum) { - return ids.get(cnum).iterator(); + public DBIDIter iterateClass(int cnum) { + return ids.get(cnum).iter(); } /** diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/StyleLibrary.java b/src/de/lmu/ifi/dbs/elki/visualization/style/StyleLibrary.java index 3de935a2..588c0bc8 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/style/StyleLibrary.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/StyleLibrary.java @@ -182,6 +182,11 @@ public interface StyleLibrary { final static String OPACITY = "opacity"; /** + * XY curve styling. + */ + static final String XYCURVE = "xycurve"; + + /** * Retrieve a color for an item * * @param name Reference name diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/StyleResult.java b/src/de/lmu/ifi/dbs/elki/visualization/style/StyleResult.java index c617bea6..fe8a73ce 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/style/StyleResult.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/StyleResult.java @@ -28,6 +28,9 @@ import de.lmu.ifi.dbs.elki.result.Result; * Result to encapsulate active styling rules. * * @author Erich Schubert + * + * @apiviz.landmark + * @apiviz.composedOf StylingPolicy */ // TODO: pull style library etc. from VisualizerContext here? public class StyleResult implements Result { diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/StylingPolicy.java b/src/de/lmu/ifi/dbs/elki/visualization/style/StylingPolicy.java index a46d7c98..d2390ea0 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/style/StylingPolicy.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/StylingPolicy.java @@ -1,7 +1,5 @@ package de.lmu.ifi.dbs.elki.visualization.style; -import de.lmu.ifi.dbs.elki.database.ids.DBID; - /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures @@ -25,6 +23,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBID; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; + /** * Styling policy. * @@ -43,5 +43,5 @@ public interface StylingPolicy { * @param id Object ID * @return Color value */ - public int getColorForDBID(DBID id); + public int getColorForDBID(DBIDRef id); } diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/classic.properties b/src/de/lmu/ifi/dbs/elki/visualization/style/classic.properties index ea1758e7..fe9f3e96 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/style/classic.properties +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/classic.properties @@ -68,7 +68,7 @@ plot.polygons.line-width=0.001 plot.polygons.color=grey ## Curve vis (ROC curves) labels: -curve.labels.text-size=0.04 +xycurve.text-size=0.03 # Text size in overview plot overview.labels.text-size=0.08 diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/default.properties b/src/de/lmu/ifi/dbs/elki/visualization/style/default.properties index 1dd9a9c7..ca892a6e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/style/default.properties +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/default.properties @@ -64,7 +64,7 @@ plot.polygons.line-width=0.001 plot.polygons.color=grey ## Curve vis (ROC curves) labels: -curve.labels.text-size=0.04 +xycurve.text-size=0.03 # Text size in overview plot overview.labels.text-size=0.08 diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/greyscale.properties b/src/de/lmu/ifi/dbs/elki/visualization/style/greyscale.properties index d31e6ec4..0e7c96e0 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/style/greyscale.properties +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/greyscale.properties @@ -68,7 +68,7 @@ plot.polygons.line-width=0.001 plot.polygons.color=dimgrey ## Curve vis (ROC curves) labels: -curve.labels.text-size=0.04 +xycurve.text-size=0.03 # Text size in overview plot overview.labels.text-size=0.08 diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/neon.properties b/src/de/lmu/ifi/dbs/elki/visualization/style/neon.properties index 311f0884..81515031 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/style/neon.properties +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/neon.properties @@ -68,7 +68,7 @@ plot.polygons.line-width=0.001 plot.polygons.color=grey ## Curve vis (ROC curves) labels: -curve.labels.text-size=0.04 +xycurve.text-size=0.03 # Text size in overview plot overview.labels.text-size=0.08 diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/presentation.properties b/src/de/lmu/ifi/dbs/elki/visualization/style/presentation.properties index 31c2b569..8c597066 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/style/presentation.properties +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/presentation.properties @@ -68,7 +68,7 @@ plot.polygons.line-width=0.001 plot.polygons.color=grey ## Curve vis (ROC curves) labels: -curve.labels.text-size=0.06 +xycurve.text-size=0.04 # Text size in overview plot overview.labels.text-size=0.08 diff --git a/src/de/lmu/ifi/dbs/elki/visualization/style/print.properties b/src/de/lmu/ifi/dbs/elki/visualization/style/print.properties new file mode 100644 index 00000000..930a8d1c --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/style/print.properties @@ -0,0 +1,85 @@ +## Libraries +lines-library = SolidLineStyleLibrary +marker-library = PrettyMarkers + +## Default foreground color +color=black +## Default font family +font-family='Times New Roman', serif +## Default background color +background-color=white +## Default line width +line-width=0.01 +## Text font size scale +text-size=0.03 +## Text color +text-color=black +## Default margin (relative) +margin.size=0.10 + +## Named color for the page background +page.background-color=white +## Background color for plot area +plot.background-color=none + +## Named color for a typical axis +axis.color=black +## Named color for a typical axis tick mark +axis.tick.color=grey +## Named color for a typical axis tick mark +axis.tick.minor.color=silver +## Named color for a typical axis label +axis.label.color=black +## Axis line width +axis.line-width=0.004 +## Axis tick width +axis.tick.line-width=0.004 +## Axis label font size +axis.label.text-size=0.03 + +## Named color for the background of the key box +key.background-color=none +## Named color for a label in the key part +key.label.color=black + +## A list of color names for data lines +# We stick to primary colors first to have the least issues +# The first two colors are red and blue to help red-green blind people. +# Yellow usually offers bad contrast, therefore comes late. +# Magenta often shows up too similar to red, cyan too similar to blue in print. +colorset=black,#ed420e,#fdca19,#4548a5,#7ebd3a,#a81e51,#00748b,#fa8116,#512d85,#008a7a,#fea918,#019d60,#cfde3d,#015a9c,#7b1760 +## Line width scaling (for graphs) +plot.line-width=0.005 +## For the cluster order +plot.clusterorder.line-width=0.003 +## Bubble sizes (relative) +plot.bubble.size=0.10 +## Marker size (relative) +plot.marker.size=0.01 +## Greyed out color +plot.grey=grey +## Dot size +plot.dot.size=0.004 +## Reference points +plot.referencepoints.size=0.006 +plot.referencepoints.color=red +## Polygons +plot.polygons.line-width=0.001 +plot.polygons.color=grey + +## Curve vis (ROC curves) labels: +xycurve.text-size=0.04 + +# Text size in overview plot +overview.labels.text-size=0.08 + +## Selection colors +plot.selection.color=darkblue +plot.selection.opacity=0.4 +plot.selection.size=0.015 + +## Circle segment colors. Will be interpolated to produce extra classes. +segments.border.color=#FF0073 +segments.hover.color=#73ff00 +segments.cluster.first.color=#404050 +segments.cluster.second.color=#D0D0F0
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPlot.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPlot.java index 81299b10..e45c7b5a 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPlot.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGPlot.java @@ -50,8 +50,10 @@ import org.apache.batik.transcoder.image.JPEGTranscoder; import org.apache.batik.transcoder.image.PNGTranscoder; import org.apache.batik.util.SVGConstants; import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; import org.w3c.dom.DocumentType; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.w3c.dom.events.Event; import org.w3c.dom.svg.SVGDocument; import org.w3c.dom.svg.SVGPoint; @@ -84,6 +86,11 @@ public class SVGPlot { public static final double DEFAULT_QUALITY = 0.85; /** + * Attribute to block export of element. + */ + public static final String NO_EXPORT_ATTRIBUTE = "noexport"; + + /** * SVG document we plot to. */ private SVGDocument document; @@ -295,7 +302,7 @@ public class SVGPlot { cssman.addClass(cls); } catch(CSSNamingConflict e) { - //de.lmu.ifi.dbs.elki.logging.LoggingUtil.exception(e); + // de.lmu.ifi.dbs.elki.logging.LoggingUtil.exception(e); } } @@ -366,7 +373,7 @@ public class SVGPlot { * @return cloned document */ protected SVGDocument cloneDocument() { - return (SVGDocument) new CloneInlineImages().cloneDocument(SVGDOMImplementation.getDOMImplementation(), document); + return (SVGDocument) new CloneNoExport().cloneDocument(SVGDOMImplementation.getDOMImplementation(), document); } /** @@ -640,4 +647,26 @@ public class SVGPlot { public void setDisableInteractions(boolean disable) { disableInteractions = disable; } + + /** + * Class to skip nodes during cloning that have the "noexport" attribute set. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + protected class CloneNoExport extends CloneInlineImages { + @Override + public Node cloneNode(Document doc, Node eold) { + // Skip elements with noexport attribute set + if(eold instanceof Element) { + Element eeold = (Element) eold; + String vis = eeold.getAttribute(NO_EXPORT_ATTRIBUTE); + if(vis != null && vis.length() > 0) { + return null; + } + } + return super.cloneNode(doc, eold); + } + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGScoreBar.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGScoreBar.java index 185a6061..ac352169 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGScoreBar.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGScoreBar.java @@ -1,5 +1,28 @@ package de.lmu.ifi.dbs.elki.visualization.svg; +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2012 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + import java.text.NumberFormat; import org.apache.batik.util.SVGConstants; @@ -89,20 +112,21 @@ public class SVGScoreBar { bar.setAttribute(SVGConstants.SVG_FILL_ATTRIBUTE, "#a0a0a0"); bar.setAttribute(SVGConstants.SVG_STROKE_ATTRIBUTE, "#a0a0a0"); bar.setAttribute(SVGConstants.SVG_STROKE_WIDTH_ATTRIBUTE, "" + height * 0.01); - - double fpos = (fill / size) * (width - (0.04 * height)); - Element chart = svgp.svgRect(x + 0.02 * height, y + 0.02 * height, fpos, height - 0.04 * height); - chart.setAttribute(SVGConstants.SVG_FILL_ATTRIBUTE, "#d4e4f1"); - chart.setAttribute(SVGConstants.SVG_STROKE_ATTRIBUTE, "#a0a0a0"); - chart.setAttribute(SVGConstants.SVG_STROKE_WIDTH_ATTRIBUTE, "" + height * 0.01); - - barchart = svgp.svgElement(SVGConstants.SVG_G_TAG); barchart.appendChild(bar); - barchart.appendChild(chart); + + if(fill >= 0 && fill <= size + 1) { + double fpos = (fill / size) * (width - (0.04 * height)); + Element chart = svgp.svgRect(x + 0.02 * height, y + 0.02 * height, fpos, height - 0.04 * height); + chart.setAttribute(SVGConstants.SVG_FILL_ATTRIBUTE, "#d4e4f1"); + chart.setAttribute(SVGConstants.SVG_STROKE_ATTRIBUTE, "#a0a0a0"); + chart.setAttribute(SVGConstants.SVG_STROKE_WIDTH_ATTRIBUTE, "" + height * 0.01); + barchart.appendChild(chart); + } // Draw the values: if(format != null) { - Element lbl = svgp.svgText(x + 0.05 * width, y + 0.75 * height, FormatUtil.format(fill, format)); + String num = Double.isNaN(fill) ? "NaN" : FormatUtil.format(fill, format); + Element lbl = svgp.svgText(x + 0.05 * width, y + 0.75 * height, num); lbl.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: " + 0.75 * height + "; font-weight: bold"); barchart.appendChild(lbl); } diff --git a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGSimpleLinearAxis.java b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGSimpleLinearAxis.java index 9a676c38..987915b7 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGSimpleLinearAxis.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/svg/SVGSimpleLinearAxis.java @@ -41,7 +41,6 @@ import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; * @apiviz.uses CSSClassManager * @apiviz.uses LinearScale * @apiviz.uses StyleLibrary - * @apiviz.uses STYLE * @apiviz.uses Element oneway - - «create» */ public class SVGSimpleLinearAxis { @@ -51,14 +50,14 @@ public class SVGSimpleLinearAxis { * * @apiviz.exclude */ - private enum ALIGNMENT { + private enum Alignment { LL, RL, LC, RC, LR, RR } /** * Labeling style: left-handed, right-handed, no ticks, labels at ends * - * @author Erich Schubert + * @apiviz.exclude */ public enum LabelStyle { LEFTHAND, RIGHTHAND, NOLABELS, NOTHING, ENDLABEL @@ -128,11 +127,11 @@ public class SVGSimpleLinearAxis { SVGUtil.setCSSClass(line, CSS_AXIS); parent.appendChild(line); - double tx = x2 - x1; - double ty = y2 - y1; + final double tx = x2 - x1; + final double ty = y2 - y1; // ticks are orthogonal - double tw = ty * 0.01; - double th = -tx * 0.01; + final double tw = ty * 0.01; + final double th = -tx * 0.01; // choose where to print labels. final boolean labels, ticks; @@ -152,24 +151,24 @@ public class SVGSimpleLinearAxis { labels = false; ticks = false; } - ALIGNMENT pos = ALIGNMENT.LL; + Alignment pos = Alignment.LL; if(labels) { double angle = Math.atan2(ty, tx); // System.err.println(tx + " " + (-ty) + " " + angle); if(angle > 2.6) { // pi .. 2.6 = 180 .. 150 - pos = labelstyle == LabelStyle.RIGHTHAND ? ALIGNMENT.RC : ALIGNMENT.LC; + pos = labelstyle == LabelStyle.RIGHTHAND ? Alignment.RC : Alignment.LC; } else if(angle > 0.5) { // 2.3 .. 0.7 = 130 .. 40 - pos = labelstyle == LabelStyle.RIGHTHAND ? ALIGNMENT.RR : ALIGNMENT.LL; + pos = labelstyle == LabelStyle.RIGHTHAND ? Alignment.RR : Alignment.LL; } else if(angle > -0.5) { // 0.5 .. -0.5 = 30 .. -30 - pos = labelstyle == LabelStyle.RIGHTHAND ? ALIGNMENT.RC : ALIGNMENT.LC; + pos = labelstyle == LabelStyle.RIGHTHAND ? Alignment.RC : Alignment.LC; } else if(angle > -2.6) { // -0.5 .. -2.6 = -30 .. -150 - pos = labelstyle == LabelStyle.RIGHTHAND ? ALIGNMENT.RL : ALIGNMENT.LR; + pos = labelstyle == LabelStyle.RIGHTHAND ? Alignment.RL : Alignment.LR; } else { // -2.6 .. -pi = -150 .. -180 - pos = labelstyle == LabelStyle.RIGHTHAND ? ALIGNMENT.RC : ALIGNMENT.LC; + pos = labelstyle == LabelStyle.RIGHTHAND ? Alignment.RC : Alignment.LC; } } // vertical text offset; align approximately with middle instead of @@ -178,7 +177,28 @@ public class SVGSimpleLinearAxis { // draw ticks on x axis if(ticks || labels) { - for(double tick = scale.getMin(); tick <= scale.getMax() + scale.getRes() / 10; tick += scale.getRes()) { + int sw = 1; + { // Compute how many ticks to draw + int numticks = (int) ((scale.getMax() - scale.getMin()) / scale.getRes()); + double tlen = Math.sqrt(tx * tx + ty * ty); + double minl = 10 * style.getLineWidth(StyleLibrary.AXIS_TICK); + // Try proper divisors first. + if(sw * tlen / numticks < minl) { + for(int i = 2; i <= (numticks >> 1); i++) { + if(numticks % i == 0) { + if(i * tlen / numticks >= minl) { + sw = i; + break; + } + } + } + } + // Otherwise, also allow non-divisors. + if(sw * tlen / numticks < minl) { + sw = (int)Math.floor(minl * numticks / tlen); + } + } + for(double tick = scale.getMin(); tick <= scale.getMax() + scale.getRes() / 10; tick += sw * scale.getRes()) { double x = x1 + tx * scale.getScaled(tick); double y = y1 + ty * scale.getScaled(tick); if(ticks) { diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisualizerUtil.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisualizerUtil.java index a3b0e3f4..1bc9b332 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisualizerUtil.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisualizerUtil.java @@ -24,6 +24,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers; */ import java.util.Iterator; +import java.util.List; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation; @@ -34,7 +35,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.utilities.iterator.AbstractFilteredIterator; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; @@ -53,9 +53,9 @@ public final class VisualizerUtil { * @return Visualizer context */ public static VisualizerContext getContext(HierarchicalResult baseResult) { - IterableIterator<VisualizerContext> iter = ResultUtil.filteredResults(baseResult, VisualizerContext.class); - if(iter.hasNext()) { - return iter.next(); + List<VisualizerContext> contexts = ResultUtil.filterResults(baseResult, VisualizerContext.class); + if(!contexts.isEmpty()) { + return contexts.get(0); } else { return null; @@ -106,7 +106,7 @@ public final class VisualizerUtil { public static void setVisible(VisualizerContext context, VisualizationTask task, boolean visibility) { // Hide other tools if(visibility && VisualizerUtil.isTool(task)) { - final Iterable<VisualizationTask> visualizers = ResultUtil.filteredResults(context.getResult(), VisualizationTask.class); + final List<VisualizationTask> visualizers = ResultUtil.filterResults(context.getResult(), VisualizationTask.class); for(VisualizationTask other : visualizers) { if(other != task && VisualizerUtil.isTool(other) && VisualizerUtil.isVisible(other)) { other.put(VisualizationTask.META_VISIBLE, false); @@ -131,6 +131,18 @@ public final class VisualizerUtil { } /** + * Utility function to test for a visualizer being "no export". + * + * @param vis Visualizer to test + * @return true when not to export + */ + public static boolean isNoExport(VisualizationTask vis) { + // Currently enabled? + Boolean noexport = vis.getGenerics(VisualizationTask.META_NOEXPORT, Boolean.class); + return (noexport != null) && noexport; + } + + /** * Utility function to test for a visualizer having options. * * @param vis Visualizer to test @@ -149,9 +161,9 @@ public final class VisualizerUtil { * @return Iterator over suitable representations */ // TODO: move to DatabaseUtil? - public static IterableIterator<Relation<? extends NumberVector<?, ?>>> iterateVectorFieldRepresentations(final Result result) { - Iterator<Relation<?>> parent = ResultUtil.filteredResults(result, Relation.class); - return new VectorspaceIterator(parent); + public static Iterator<Relation<? extends NumberVector<?, ?>>> iterateVectorFieldRepresentations(final Result result) { + List<Relation<?>> parent = ResultUtil.filterResults(result, Relation.class); + return new VectorspaceIterator(parent.iterator()); } /** @@ -161,7 +173,7 @@ public final class VisualizerUtil { * * @apiviz.exclude */ - private static class VectorspaceIterator extends AbstractFilteredIterator<Relation<?>, Relation<? extends NumberVector<?, ?>>> implements IterableIterator<Relation<? extends NumberVector<?, ?>>> { + private static class VectorspaceIterator extends AbstractFilteredIterator<Relation<?>, Relation<? extends NumberVector<?, ?>>> { /** Parent iterator */ private Iterator<Relation<?>> parent; @@ -187,11 +199,6 @@ public final class VisualizerUtil { } return (Relation<? extends NumberVector<?, ?>>) nextobj; } - - @Override - public Iterator<Relation<? extends NumberVector<?, ?>>> iterator() { - return this; - } }; /** diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/ColoredHistogramVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/ColoredHistogramVisualizer.java index d518d0cf..e300a3c4 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/ColoredHistogramVisualizer.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/ColoredHistogramVisualizer.java @@ -23,13 +23,13 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.histogram; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.Iterator; +import java.util.Collection; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; import de.lmu.ifi.dbs.elki.data.NumberVector; -import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; import de.lmu.ifi.dbs.elki.math.DoubleMinMax; @@ -39,9 +39,9 @@ import de.lmu.ifi.dbs.elki.math.scales.LinearScale; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; +import de.lmu.ifi.dbs.elki.result.SamplingResult; import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; import de.lmu.ifi.dbs.elki.utilities.exceptions.ObjectNotFoundException; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterEqualConstraint; @@ -111,6 +111,11 @@ public class ColoredHistogramVisualizer<NV extends NumberVector<NV, ?>> extends private StyleResult style; /** + * Sampling result + */ + private SamplingResult sample; + + /** * Constructor. * * @param task Visualization task @@ -123,6 +128,7 @@ public class ColoredHistogramVisualizer<NV extends NumberVector<NV, ?>> extends this.bins = bins; this.relation = task.getRelation(); this.style = task.getResult(); + this.sample = ResultUtil.getSamplingResult(relation); context.addResultListener(this); } @@ -180,10 +186,12 @@ public class ColoredHistogramVisualizer<NV extends NumberVector<NV, ?>> extends double[] inc = new double[cols]; inc[0] = frac; inc[snum + 1] = frac; - for(Iterator<DBID> iter = cspol.iterateClass(snum + off); iter.hasNext();) { - DBID id = iter.next(); + for(DBIDIter iter = cspol.iterateClass(snum + off); iter.valid(); iter.advance()) { + if(!sample.getSample().contains(iter)) { + continue; // TODO: can we test more efficiently than this? + } try { - double pos = proj.fastProjectDataToRenderSpace(relation.get(id)) / Projection.SCALE; + double pos = proj.fastProjectDataToRenderSpace(relation.get(iter)) / Projection.SCALE; histogram.aggregate(pos, inc); } catch(ObjectNotFoundException e) { @@ -196,8 +204,8 @@ public class ColoredHistogramVisualizer<NV extends NumberVector<NV, ?>> extends // Actual data distribution. double[] inc = new double[cols]; inc[0] = frac; - for(DBID id : relation.iterDBIDs()) { - double pos = proj.fastProjectDataToRenderSpace(relation.get(id)) / Projection.SCALE; + for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { + double pos = proj.fastProjectDataToRenderSpace(relation.get(iditer)) / Projection.SCALE; histogram.aggregate(pos, inc); } } @@ -332,7 +340,7 @@ public class ColoredHistogramVisualizer<NV extends NumberVector<NV, ?>> extends * @author Erich Schubert * * @apiviz.stereotype factory - * @apiviz.uses P1DHistogramVisualizer oneway - - «create» + * @apiviz.uses ColoredHistogramVisualizer oneway - - «create» * * @param <NV> Number vector type */ @@ -391,9 +399,9 @@ public class ColoredHistogramVisualizer<NV extends NumberVector<NV, ?>> extends @Override public void processNewResult(HierarchicalResult baseResult, Result result) { // Find a style result to visualize: - IterableIterator<StyleResult> styleres = ResultUtil.filteredResults(result, StyleResult.class); + Collection<StyleResult> styleres = ResultUtil.filterResults(result, StyleResult.class); for(StyleResult c : styleres) { - IterableIterator<HistogramProjector<?>> ps = ResultUtil.filteredResults(baseResult, HistogramProjector.class); + Collection<HistogramProjector<?>> ps = ResultUtil.filterResults(baseResult, HistogramProjector.class); for(HistogramProjector<?> p : ps) { // register self final VisualizationTask task = new VisualizationTask(CNAME, c, p.getRelation(), this); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java index f69bdc59..2369588b 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java @@ -23,8 +23,10 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.Iterator; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; @@ -38,8 +40,8 @@ import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; +import de.lmu.ifi.dbs.elki.visualization.colors.ColorLibrary; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; import de.lmu.ifi.dbs.elki.visualization.projector.OPTICSProjector; import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; @@ -103,9 +105,8 @@ public class OPTICSClusterVisualization<D extends Distance<D>> extends AbstractO */ @SuppressWarnings("unchecked") protected static Clustering<OPTICSModel> findOPTICSClustering(Result result) { - Iterator<Clustering<?>> cs = ResultUtil.filteredResults(result, Clustering.class); - while (cs.hasNext()) { - Clustering<?> clus = cs.next(); + Collection<Clustering<?>> cs = ResultUtil.filterResults(result, Clustering.class); + for(Clustering<?> clus : cs) { if(clus.getToplevelClusters().size() == 0) { continue; } @@ -126,7 +127,15 @@ public class OPTICSClusterVisualization<D extends Distance<D>> extends AbstractO protected void redraw() { makeLayerElement(); addCSSClasses(); - drawClusters(clus.getToplevelClusters(), 1); + + ColorLibrary colors = context.getStyleLibrary().getColorSet(StyleLibrary.PLOT); + HashMap<Cluster<?>, String> colormap = new HashMap<Cluster<?>, String>(); + int cnum = 0; + for (Cluster<?> c : clus.getAllClusters()) { + colormap.put(c, colors.getColor(cnum)); + cnum++; + } + drawClusters(clus.getToplevelClusters(), 1, colormap); } /** @@ -134,9 +143,11 @@ public class OPTICSClusterVisualization<D extends Distance<D>> extends AbstractO * * @param clusters Current set of clusters * @param depth Recursion depth + * @param colormap Color mapping */ - private void drawClusters(List<Cluster<OPTICSModel>> clusters, int depth) { + private void drawClusters(List<Cluster<OPTICSModel>> clusters, int depth, Map<Cluster<?>,String> colormap) { final double scale = StyleLibrary.SCALE; + for(Cluster<OPTICSModel> cluster : clusters) { try { OPTICSModel model = cluster.getModel(); @@ -145,6 +156,10 @@ public class OPTICSClusterVisualization<D extends Distance<D>> extends AbstractO final double y = plotheight + depth * scale * 0.01; Element e = svgp.svgLine(x1, y, x2, y); SVGUtil.addCSSClass(e, CSS_BRACKET); + String color = colormap.get(cluster); + if (color != null) { + SVGUtil.setAtt(e, SVGConstants.SVG_STYLE_ATTRIBUTE, SVGConstants.CSS_STROKE_PROPERTY+":"+color); + } layer.appendChild(e); } catch(ClassCastException e) { @@ -153,7 +168,7 @@ public class OPTICSClusterVisualization<D extends Distance<D>> extends AbstractO // Descend final List<Cluster<OPTICSModel>> children = cluster.getChildren(); if(children != null) { - drawClusters(children, depth + 1); + drawClusters(children, depth + 1, colormap); } } } @@ -190,7 +205,7 @@ public class OPTICSClusterVisualization<D extends Distance<D>> extends AbstractO @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - IterableIterator<OPTICSProjector<?>> ops = ResultUtil.filteredResults(result, OPTICSProjector.class); + Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class); for(OPTICSProjector<?> p : ops) { final Clustering<OPTICSModel> ocl = findOPTICSClustering(baseResult); if(ocl != null) { diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java index 58cd9af3..2bd5c63a 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java @@ -23,6 +23,8 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Collection;
+
import org.apache.batik.util.SVG12Constants;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
@@ -38,7 +40,6 @@ import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
@@ -275,7 +276,7 @@ public class OPTICSPlotCutVisualization<D extends Distance<D>> extends AbstractO @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- IterableIterator<OPTICSProjector<?>> ops = ResultUtil.filteredResults(result, OPTICSProjector.class);
+ Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class);
for(OPTICSProjector<?> p : ops) {
final VisualizationTask task = new VisualizationTask(NAME, p, null, this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java index f8f30317..87b24df2 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java @@ -23,6 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Collection;
import java.util.List;
import org.apache.batik.dom.events.DOMMouseEvent;
@@ -44,7 +45,6 @@ import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
@@ -349,7 +349,7 @@ public class OPTICSPlotSelectionVisualization<D extends Distance<D>> extends Abs @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- IterableIterator<OPTICSProjector<?>> ops = ResultUtil.filteredResults(result, OPTICSProjector.class);
+ Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class);
for(OPTICSProjector<?> p : ops) {
final VisualizationTask task = new VisualizationTask(NAME, p, null, this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java index da287252..d93c98cb 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java @@ -23,6 +23,8 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.util.Collection; + import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; @@ -32,7 +34,6 @@ import de.lmu.ifi.dbs.elki.logging.LoggingUtil; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.css.CSSClassManager.CSSNamingConflict; import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot; @@ -110,7 +111,7 @@ public class OPTICSPlotVisualizer<D extends Distance<D>> extends AbstractOPTICSV @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - IterableIterator<OPTICSProjector<?>> ops = ResultUtil.filteredResults(result, OPTICSProjector.class); + Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class); for(OPTICSProjector<?> p : ops) { // Add plots, attach visualizer final VisualizationTask task = new VisualizationTask(NAME, p, null, this); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java index 95b3d53b..4e557a74 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java @@ -24,6 +24,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics; */ import java.awt.Color; +import java.util.Collection; import java.util.List; import org.apache.batik.util.SVGConstants; @@ -40,7 +41,6 @@ import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.result.SelectionResult; import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry; import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSDistanceAdapter; @@ -195,7 +195,7 @@ public class OPTICSSteepAreaVisualization<D extends Distance<D>> extends Abstrac @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - IterableIterator<OPTICSProjector<?>> ops = ResultUtil.filteredResults(result, OPTICSProjector.class); + Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class); for(OPTICSProjector<?> p : ops) { final SteepAreaResult steep = findSteepAreaResult(p.getResult()); if(steep != null) { diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/CircleSegmentsVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/CircleSegmentsVisualizer.java index 360197ab..f0655ab6 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/CircleSegmentsVisualizer.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/CircleSegmentsVisualizer.java @@ -58,6 +58,7 @@ import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil; import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisFactory; import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization; import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; +import de.lmu.ifi.dbs.elki.visualization.visualizers.thumbs.ThumbnailVisualization; /** * Visualizer to draw circle segments of clusterings and enable interactive @@ -74,6 +75,11 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; * * @author Sascha Goldhofer * @author Erich Schubert + * + * @apiviz.landmark + * + * @apiviz.uses Segments + * @apiviz.has SegmentsStylingPolicy */ @Reference(title = "Evaluation of Clusterings – Metrics and Visual Support", authors = "Elke Achtert, Sascha Goldhofer, Hans-Peter Kriegel, Erich Schubert, Arthur Zimek", booktitle = "Proc. 28th International Conference on Data Engineering (ICDE) 2012", url = "http://elki.dbs.ifi.lmu.de/wiki/PairSegments") public class CircleSegmentsVisualizer extends AbstractVisualization implements ResultListener { @@ -190,8 +196,10 @@ public class CircleSegmentsVisualizer extends AbstractVisualization implements R */ public CircleSegmentsVisualizer(VisualizationTask task) { super(task); - segments = task.getResult(); - policy = new SegmentsStylingPolicy(segments, context.getStyleLibrary()); + policy = task.getResult(); + segments = policy.segments; + // FIXME: handle this more generally. + policy.setStyleLibrary(context.getStyleLibrary()); // Listen for result changes (Selection changed) context.addResultListener(this); } @@ -612,6 +620,8 @@ public class CircleSegmentsVisualizer extends AbstractVisualization implements R * Proxy element to connect signals. * * @author Erich Schubert + * + * @apiviz.exclude */ private class SegmentListenerProxy implements EventListener { /** @@ -684,6 +694,7 @@ public class CircleSegmentsVisualizer extends AbstractVisualization implements R */ public Factory() { super(); + this.thumbmask |= ThumbnailVisualization.ON_STYLE; } @Override @@ -696,8 +707,16 @@ public class CircleSegmentsVisualizer extends AbstractVisualization implements R // If no comparison result found abort List<Segments> segments = ResultUtil.filterResults(result, Segments.class); for(Segments segmentResult : segments) { + SegmentsStylingPolicy policy; + List<SegmentsStylingPolicy> styles = ResultUtil.filterResults(segmentResult, SegmentsStylingPolicy.class); + if (!styles.isEmpty()) { + policy = styles.get(0); + } else { + policy = new SegmentsStylingPolicy(segmentResult); + baseResult.getHierarchy().add(segmentResult, policy); + } // create task for visualization - final VisualizationTask task = new VisualizationTask(NAME, segmentResult, null, this); + final VisualizationTask task = new VisualizationTask(NAME, policy, null, this); task.width = 2.0; task.height = 2.0; task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/SegmentsStylingPolicy.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/SegmentsStylingPolicy.java index 99ecf081..0ea700c8 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/SegmentsStylingPolicy.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/SegmentsStylingPolicy.java @@ -28,12 +28,14 @@ import java.util.Iterator; import java.util.Map.Entry; import java.util.TreeMap; -import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; import de.lmu.ifi.dbs.elki.database.ids.DBIDs; import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs; import de.lmu.ifi.dbs.elki.evaluation.clustering.pairsegments.Segment; import de.lmu.ifi.dbs.elki.evaluation.clustering.pairsegments.Segments; +import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.visualization.colors.ColorLibrary; import de.lmu.ifi.dbs.elki.visualization.style.ClassStylingPolicy; import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; @@ -45,7 +47,7 @@ import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil; * @author Sascha Goldhofer * @author Erich Schubert */ -public class SegmentsStylingPolicy implements ClassStylingPolicy { +public class SegmentsStylingPolicy implements ClassStylingPolicy, Result { /** * The segments we use for visualization */ @@ -70,17 +72,16 @@ public class SegmentsStylingPolicy implements ClassStylingPolicy { * Color library (only used in compatibility mode) */ // TODO: move to abstract super class? - ColorLibrary colorset; + ColorLibrary colorset = null; /** * Constructor. * * @param segments Segments */ - public SegmentsStylingPolicy(Segments segments, StyleLibrary style) { + public SegmentsStylingPolicy(Segments segments) { super(); this.segments = segments; - this.colorset = style.getColorSet(StyleLibrary.PLOT); // get all selectable segments for(Segment segment : segments) { @@ -95,6 +96,17 @@ public class SegmentsStylingPolicy implements ClassStylingPolicy { } /** + * Assign the style library, for compatibility color styling. + * + * FIXME: handle this more generally + * + * @param style Style library + */ + public void setStyleLibrary(StyleLibrary style) { + this.colorset = style.getColorSet(StyleLibrary.PLOT); + } + + /** * Test whether a segment is selected. * * @param segment Segment to test @@ -105,7 +117,7 @@ public class SegmentsStylingPolicy implements ClassStylingPolicy { } @Override - public int getStyleForDBID(DBID id) { + public int getStyleForDBID(DBIDRef id) { Iterator<Segment> s = selectedSegments.iterator(); for(int i = 0; s.hasNext(); i++) { Segment seg = s.next(); @@ -118,10 +130,14 @@ public class SegmentsStylingPolicy implements ClassStylingPolicy { } @Override - public int getColorForDBID(DBID id) { + public int getColorForDBID(DBIDRef id) { int style = getStyleForDBID(id); - // FIXME: slow - return SVGUtil.stringToColor(colorset.getColor(style)).getRGB(); + if (colorset != null) { + // FIXME: add caching + return SVGUtil.stringToColor(colorset.getColor(style)).getRGB(); + } else { + return 0; + } } @Override @@ -136,17 +152,17 @@ public class SegmentsStylingPolicy implements ClassStylingPolicy { } @Override - public Iterator<DBID> iterateClass(int cnum) { + public DBIDIter iterateClass(int cnum) { // unselected if(cnum == -2) { - return unselectedObjects.iterator(); + return unselectedObjects.iter(); } else if(cnum == -1) { - return DBIDUtil.EMPTYDBIDS.iterator(); + return DBIDUtil.EMPTYDBIDS.iter(); } // colors DBIDs ids = selectedSegments.get(cnum).getDBIDs(); - return (ids != null) ? ids.iterator() : DBIDUtil.EMPTYDBIDS.iterator(); + return (ids != null) ? ids.iter() : DBIDUtil.EMPTYDBIDS.iter(); } /** @@ -284,4 +300,14 @@ public class SegmentsStylingPolicy implements ClassStylingPolicy { public int indexOfSegment(Segment segment) { return selectedSegments.indexOf(segment); } + + @Override + public String getLongName() { + return "Pair segments styling policy"; + } + + @Override + public String getShortName() { + return "pairsegments-styling"; + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/LineVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/LineVisualization.java index 3a2c7c1d..8269d8fe 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/LineVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/LineVisualization.java @@ -23,19 +23,18 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.Iterator;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SamplingResult;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
import de.lmu.ifi.dbs.elki.visualization.projector.ParallelPlotProjector;
@@ -99,21 +98,20 @@ public class LineVisualization extends AbstractParallelVisualization<NumberVecto StylingPolicy sp = context.getStyleResult().getStylingPolicy();
addCSSClasses(svgp, sp);
- Iterator<DBID> ids = sample.getSample().iterator();
- if(ids == null || !ids.hasNext()) {
+ DBIDIter ids = sample.getSample().iter();
+ if(ids == null || !ids.valid()) {
ids = relation.iterDBIDs();
}
if(sp instanceof ClassStylingPolicy) {
ClassStylingPolicy csp = (ClassStylingPolicy) sp;
for(int c = csp.getMinStyle(); c < csp.getMaxStyle(); c++) {
String key = DATALINE + "_" + c;
- for(Iterator<DBID> iter = csp.iterateClass(c); iter.hasNext();) {
- DBID id = iter.next();
- if(!sample.getSample().contains(id)) {
+ for(DBIDIter iter = csp.iterateClass(c); iter.valid(); iter.advance()) {
+ if(!sample.getSample().contains(iter)) {
continue; // TODO: can we test more efficiently than this?
}
SVGPath path = new SVGPath();
- double[] yPos = proj.fastProjectDataToRenderSpace(relation.get(id));
+ double[] yPos = proj.fastProjectDataToRenderSpace(relation.get(iter));
for(int i = 0; i < yPos.length; i++) {
path.drawTo(getVisibleAxisX(i), yPos[i]);
}
@@ -124,17 +122,16 @@ public class LineVisualization extends AbstractParallelVisualization<NumberVecto }
}
else {
- while(ids.hasNext()) {
- DBID id = ids.next();
+ for(; ids.valid(); ids.advance()) {
SVGPath path = new SVGPath();
- double[] yPos = proj.fastProjectDataToRenderSpace(relation.get(id));
+ double[] yPos = proj.fastProjectDataToRenderSpace(relation.get(ids));
for(int i = 0; i < yPos.length; i++) {
path.drawTo(getVisibleAxisX(i), yPos[i]);
}
Element line = path.makeElement(svgp);
SVGUtil.addCSSClass(line, DATALINE);
// assign color
- line.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, SVGConstants.CSS_STROKE_PROPERTY + ":" + SVGUtil.colorToString(sp.getColorForDBID(id)));
+ line.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, SVGConstants.CSS_STROKE_PROPERTY + ":" + SVGUtil.colorToString(sp.getColorForDBID(ids)));
layer.appendChild(line);
}
}
@@ -207,7 +204,7 @@ public class LineVisualization extends AbstractParallelVisualization<NumberVecto @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- IterableIterator<ParallelPlotProjector<?>> ps = ResultUtil.filteredResults(result, ParallelPlotProjector.class);
+ Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(result, ParallelPlotProjector.class);
for(ParallelPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, p.getRelation(), p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/ParallelAxisVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/ParallelAxisVisualization.java index a47ea734..6209db6b 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/ParallelAxisVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/ParallelAxisVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.Iterator;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
@@ -178,9 +178,8 @@ public class ParallelAxisVisualization extends AbstractParallelVisualization<Num @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- Iterator<ParallelPlotProjector<?>> ps = ResultUtil.filteredResults(result, ParallelPlotProjector.class);
- while(ps.hasNext()) {
- ParallelPlotProjector<?> p = ps.next();
+ Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(result, ParallelPlotProjector.class);
+ for(ParallelPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, p, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_BACKGROUND);
baseResult.getHierarchy().add(p, task);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterOutlineVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterOutlineVisualization.java index 821ca2a5..f34b7514 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterOutlineVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterOutlineVisualization.java @@ -23,6 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel.cluster; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Collection;
import java.util.Iterator;
import org.apache.batik.util.SVGConstants;
@@ -38,7 +39,6 @@ import de.lmu.ifi.dbs.elki.math.DoubleMinMax; import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.colors.ColorLibrary;
@@ -234,11 +234,10 @@ public class ClusterOutlineVisualization extends AbstractParallelVisualization<N @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
// Find clusterings we can visualize:
- Iterator<Clustering<?>> clusterings = ResultUtil.filteredResults(result, Clustering.class);
- while(clusterings.hasNext()) {
- Clustering<?> c = clusterings.next();
+ Collection<Clustering<?>> clusterings = ResultUtil.filterResults(result, Clustering.class);
+ for(Clustering<?> c : clusterings) {
if(c.getAllClusters().size() > 0) {
- IterableIterator<ParallelPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ParallelPlotProjector.class);
+ Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
for(ParallelPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, c, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA - 1);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterParallelMeanVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterParallelMeanVisualization.java index df731ac2..1808c241 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterParallelMeanVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/ClusterParallelMeanVisualization.java @@ -23,6 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel.cluster; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Collection;
import java.util.Iterator;
import org.apache.batik.util.SVGConstants;
@@ -172,16 +173,14 @@ public class ClusterParallelMeanVisualization extends AbstractParallelVisualizat @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
// Find clusterings we can visualize:
- Iterator<Clustering<?>> clusterings = ResultUtil.filteredResults(result, Clustering.class);
- while(clusterings.hasNext()) {
- Clustering<?> c = clusterings.next();
+ Collection<Clustering<?>> clusterings = ResultUtil.filterResults(result, Clustering.class);
+ for(Clustering<?> c : clusterings) {
if(c.getAllClusters().size() > 0) {
// Does the cluster have a model with cluster means?
Clustering<MeanModel<? extends NumberVector<?, ?>>> mcls = findMeanModel(c);
if(mcls != null) {
- Iterator<ParallelPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ParallelPlotProjector.class);
- while(ps.hasNext()) {
- ParallelPlotProjector<?> p = ps.next();
+ Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
+ for (ParallelPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, c, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA + 1);
baseResult.getHierarchy().add(c, task);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/RTreeParallelVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/RTreeParallelVisualization.java index c36dff0c..499d14a5 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/RTreeParallelVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/RTreeParallelVisualization.java @@ -23,6 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel.index; */
import java.util.ArrayList;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
@@ -37,7 +38,6 @@ import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeNode; import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
@@ -227,7 +227,7 @@ public class RTreeParallelVisualization<N extends AbstractRStarTreeNode<N, E>, E ArrayList<AbstractRStarTree<RStarTreeNode, SpatialEntry>> trees = ResultUtil.filterResults(result, AbstractRStarTree.class);
for(AbstractRStarTree<RStarTreeNode, SpatialEntry> tree : trees) {
if(tree instanceof Result) {
- IterableIterator<ParallelPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ParallelPlotProjector.class);
+ Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
for(ParallelPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, (Result) tree, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_BACKGROUND + 2);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionAxisRangeVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionAxisRangeVisualization.java index cb8ee645..b894a87b 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionAxisRangeVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionAxisRangeVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel.selection; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
@@ -35,7 +35,6 @@ import de.lmu.ifi.dbs.elki.result.RangeSelection; import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
@@ -169,9 +168,9 @@ public class SelectionAxisRangeVisualization extends AbstractParallelVisualizati @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- final ArrayList<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
+ Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
for(SelectionResult selres : selectionResults) {
- IterableIterator<ParallelPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ParallelPlotProjector.class);
+ Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
for(ParallelPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA - 1);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionLineVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionLineVisualization.java index f6de4133..b9a9ac48 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionLineVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionLineVisualization.java @@ -23,21 +23,20 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel.selection; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.result.DBIDSelection;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
import de.lmu.ifi.dbs.elki.visualization.projector.ParallelPlotProjector;
@@ -94,8 +93,8 @@ public class SelectionLineVisualization extends AbstractParallelVisualization<Nu if(selContext != null) {
DBIDs selection = selContext.getSelectedIds();
- for(DBID objId : selection) {
- double[] yPos = proj.fastProjectDataToRenderSpace(relation.get(objId));
+ for(DBIDIter iter = selection.iter(); iter.valid(); iter.advance()) {
+ double[] yPos = proj.fastProjectDataToRenderSpace(relation.get(iter));
SVGPath path = new SVGPath();
for(int i = 0; i < proj.getVisibleDimensions(); i++) {
@@ -152,9 +151,9 @@ public class SelectionLineVisualization extends AbstractParallelVisualization<Nu @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- final ArrayList<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
+ Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
for(SelectionResult selres : selectionResults) {
- IterableIterator<ParallelPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ParallelPlotProjector.class);
+ Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
for(ParallelPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA -1);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolAxisRangeVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolAxisRangeVisualization.java index ead8e5ce..2f3c6778 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolAxisRangeVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolAxisRangeVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel.selection; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
@@ -31,7 +31,7 @@ import org.w3c.dom.events.Event; import org.w3c.dom.svg.SVGPoint;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -41,7 +41,6 @@ import de.lmu.ifi.dbs.elki.result.RangeSelection; import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
@@ -167,8 +166,8 @@ public class SelectionToolAxisRangeVisualization extends AbstractParallelVisuali for(int i = minaxis; i < maxaxis; i++) {
double v1 = proj.fastProjectRenderToDataSpace(z1, i);
double v2 = proj.fastProjectRenderToDataSpace(z2, i);
- if (logger.isDebugging()) {
- logger.debug("Axis "+i+" dimension "+proj.getDimForVisibleAxis(i)+" "+v1+" to "+v2);
+ if(logger.isDebugging()) {
+ logger.debug("Axis " + i + " dimension " + proj.getDimForVisibleAxis(i) + " " + v1 + " to " + v2);
}
ranges[proj.getDimForVisibleAxis(i)] = new DoubleDoublePair(Math.min(v1, v2), Math.max(v1, v2));
}
@@ -236,21 +235,17 @@ public class SelectionToolAxisRangeVisualization extends AbstractParallelVisuali updateSelectionRectKoordinates(x1, x2, y1, y2, ranges);
selection.clear();
- boolean idIn = true;
- for(DBID id : relation.iterDBIDs()) {
- NumberVector<?, ?> dbTupel = relation.get(id);
- idIn = true;
+
+ candidates: for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ NumberVector<?, ?> dbTupel = relation.get(iditer);
for(int i = 0; i < dim; i++) {
if(ranges != null && ranges[i] != null) {
if(dbTupel.doubleValue(i + 1) < ranges[i].first || dbTupel.doubleValue(i + 1) > ranges[i].second) {
- idIn = false;
- break;
+ continue candidates;
}
}
}
- if(idIn == true) {
- selection.add(id);
- }
+ selection.add(iditer);
}
context.setSelection(new RangeSelection(selection, ranges));
}
@@ -297,9 +292,9 @@ public class SelectionToolAxisRangeVisualization extends AbstractParallelVisuali @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- final ArrayList<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
+ Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
for(SelectionResult selres : selectionResults) {
- IterableIterator<ParallelPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ParallelPlotProjector.class);
+ Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
for(ParallelPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolLineVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolLineVisualization.java index 966e754a..3e66b4cd 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolLineVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/SelectionToolLineVisualization.java @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel.selection; */
import java.awt.geom.Line2D;
-import java.util.ArrayList;
+import java.util.Collection;
import org.apache.batik.dom.events.DOMMouseEvent;
import org.apache.batik.util.SVGConstants;
@@ -33,7 +33,7 @@ import org.w3c.dom.events.Event; import org.w3c.dom.svg.SVGPoint;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
@@ -42,7 +42,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
@@ -195,23 +194,23 @@ public class SelectionToolLineVisualization extends AbstractParallelVisualizatio selection = DBIDUtil.newHashSet(selContext.getSelectedIds());
}
int[] axisrange = getAxisRange(Math.min(p1.getX(), p2.getX()), Math.max(p1.getX(), p2.getX()));
- DBIDs objIds = ResultUtil.getSamplingResult(relation).getSample();
- for(DBID objId : objIds){
- double[] yPos = proj.fastProjectDataToRenderSpace(relation.get(objId));
+ DBIDs ids = ResultUtil.getSamplingResult(relation).getSample();
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ double[] yPos = proj.fastProjectDataToRenderSpace(relation.get(iter));
if(checkSelected(axisrange, yPos, Math.max(p1.getX(), p2.getX()), Math.min(p1.getX(), p2.getX()), Math.max(p1.getY(), p2.getY()), Math.min(p1.getY(), p2.getY()))) {
if(mode == Mode.INVERT) {
- if(!selection.contains(objId)) {
- selection.add(objId);
+ if(!selection.contains(iter)) {
+ selection.add(iter);
}
else {
- selection.remove(objId);
+ selection.remove(iter);
}
}
else {
// In REPLACE and ADD, add objects.
// The difference was done before by not re-using the selection.
// Since we are using a set, we can just add in any case.
- selection.add(objId);
+ selection.add(iter);
}
}
}
@@ -312,9 +311,9 @@ public class SelectionToolLineVisualization extends AbstractParallelVisualizatio @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- final ArrayList<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
+ Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
for(SelectionResult selres : selectionResults) {
- IterableIterator<ParallelPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ParallelPlotProjector.class);
+ Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
for(ParallelPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AxisVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AxisVisualization.java index a8f7fdca..4173084d 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AxisVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AxisVisualization.java @@ -23,6 +23,8 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.util.Collection; + import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; @@ -30,7 +32,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; import de.lmu.ifi.dbs.elki.visualization.css.CSSClassManager.CSSNamingConflict; @@ -141,7 +142,7 @@ public class AxisVisualization extends AbstractScatterplotVisualization { @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(result, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(result, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME, p, p.getRelation(), this); task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_BACKGROUND); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/MarkerVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/MarkerVisualization.java index 7672ee93..c98ca83b 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/MarkerVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/MarkerVisualization.java @@ -23,19 +23,18 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.Iterator; +import java.util.Collection; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener; -import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.utilities.exceptions.ObjectNotFoundException; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.projector.ScatterPlotProjector; import de.lmu.ifi.dbs.elki.visualization.style.ClassStylingPolicy; @@ -97,10 +96,12 @@ public class MarkerVisualization extends AbstractScatterplotVisualization implem if(spol instanceof ClassStylingPolicy) { ClassStylingPolicy cspol = (ClassStylingPolicy) spol; for(int cnum = cspol.getMinStyle(); cnum < cspol.getMaxStyle(); cnum++) { - for(Iterator<DBID> iter = cspol.iterateClass(cnum); iter.hasNext();) { - DBID cur = iter.next(); + for(DBIDIter iter = cspol.iterateClass(cnum); iter.valid(); iter.advance()) { + if(!sample.getSample().contains(iter)) { + continue; // TODO: can we test more efficiently than this? + } try { - final NumberVector<?, ?> vec = rel.get(cur); + final NumberVector<?, ?> vec = rel.get(iter); double[] v = proj.fastProjectDataToRenderSpace(vec); ml.useMarker(svgp, layer, v[0], v[1], cnum, marker_size); } @@ -113,12 +114,12 @@ public class MarkerVisualization extends AbstractScatterplotVisualization implem else { final String FILL = SVGConstants.CSS_FILL_PROPERTY + ":"; // Color-based styling. Fall back to dots - for(DBID id : sample.getSample()) { + for(DBIDIter iter = sample.getSample().iter(); iter.valid(); iter.advance()) { try { - double[] v = proj.fastProjectDataToRenderSpace(rel.get(id)); + double[] v = proj.fastProjectDataToRenderSpace(rel.get(iter)); Element dot = svgp.svgCircle(v[0], v[1], marker_size); SVGUtil.addCSSClass(dot, DOTMARKER); - int col = spol.getColorForDBID(id); + int col = spol.getColorForDBID(iter); SVGUtil.setAtt(dot, SVGConstants.SVG_STYLE_ATTRIBUTE, FILL + SVGUtil.colorToString(col)); layer.appendChild(dot); } @@ -160,9 +161,9 @@ public class MarkerVisualization extends AbstractScatterplotVisualization implem @Override public void processNewResult(HierarchicalResult baseResult, Result result) { // Find a style result to visualize: - IterableIterator<StyleResult> styleres = ResultUtil.filteredResults(result, StyleResult.class); + Collection<StyleResult> styleres = ResultUtil.filterResults(result, StyleResult.class); for(StyleResult c : styleres) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME, c, p.getRelation(), this); task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/PolygonVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/PolygonVisualization.java index 4dc78ecf..5b7c13b4 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/PolygonVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/PolygonVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.ArrayList; +import java.util.Collection; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; @@ -32,7 +32,7 @@ import de.lmu.ifi.dbs.elki.data.spatial.Polygon; import de.lmu.ifi.dbs.elki.data.spatial.PolygonsObject; import de.lmu.ifi.dbs.elki.data.type.TypeUtil; import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener; -import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; @@ -40,7 +40,6 @@ import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; import de.lmu.ifi.dbs.elki.utilities.exceptions.ObjectNotFoundException; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; import de.lmu.ifi.dbs.elki.visualization.projections.Projection2D; @@ -109,9 +108,9 @@ public class PolygonVisualization extends AbstractScatterplotVisualization imple svgp.updateStyleElement(); // draw data - for(DBID id : rep.iterDBIDs()) { + for(DBIDIter iditer = rep.iterDBIDs(); iditer.valid(); iditer.advance()) { try { - PolygonsObject poly = rep.get(id); + PolygonsObject poly = rep.get(iditer); if(poly == null) { continue; } @@ -163,11 +162,11 @@ public class PolygonVisualization extends AbstractScatterplotVisualization imple @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - ArrayList<Relation<?>> results = ResultUtil.filterResults(result, Relation.class); + Collection<Relation<?>> results = ResultUtil.filterResults(result, Relation.class); for(Relation<?> rel : results) { if(TypeUtil.POLYGON_TYPE.isAssignableFromType(rel.getDataTypeInformation())) { // Assume that a 2d projector is using the same coordinates as the polygons. - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { if(DatabaseUtil.dimensionality(p.getRelation()) == 2) { final VisualizationTask task = new VisualizationTask(NAME, rel, p.getRelation(), this); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ReferencePointsVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ReferencePointsVisualization.java index 644fc96f..056b788b 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ReferencePointsVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ReferencePointsVisualization.java @@ -34,7 +34,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.ReferencePointsResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; import de.lmu.ifi.dbs.elki.visualization.projector.ScatterPlotProjector; @@ -126,7 +125,7 @@ public class ReferencePointsVisualization extends AbstractScatterplotVisualizati public void processNewResult(HierarchicalResult baseResult, Result result) { Collection<ReferencePointsResult<?>> rps = ResultUtil.filterResults(result, ReferencePointsResult.class); for(ReferencePointsResult<?> rp : rps) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME, rp, p.getRelation(), this); task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ToolBox2DVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ToolBox2DVisualization.java index 7ec5f1ac..d0c05cc7 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ToolBox2DVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/ToolBox2DVisualization.java @@ -24,6 +24,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; */
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import org.apache.batik.util.SVGConstants;
@@ -37,7 +38,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
import de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize;
@@ -126,7 +126,7 @@ public class ToolBox2DVisualization extends AbstractScatterplotVisualization { deleteChildren(container);
ArrayList<VisualizationTask> vis = new ArrayList<VisualizationTask>();
- final Iterable<VisualizationTask> visualizers = ResultUtil.filteredResults(task.getResult(), VisualizationTask.class);
+ Collection<VisualizationTask> visualizers = ResultUtil.filterResults(task.getResult(), VisualizationTask.class);
for(VisualizationTask task : visualizers) {
if(VisualizerUtil.isTool(task) && !vis.contains(task)) {
vis.add(task);
@@ -292,7 +292,7 @@ public class ToolBox2DVisualization extends AbstractScatterplotVisualization { @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(result, ScatterPlotProjector.class);
+ Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(result, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, p, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipScoreVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipScoreVisualization.java index 838390d0..139fa1ed 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipScoreVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipScoreVisualization.java @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; */ import java.text.NumberFormat; -import java.util.List; +import java.util.Collection; import java.util.Locale; import org.apache.batik.util.SVGConstants; @@ -37,7 +37,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterEqualConstraint; @@ -67,7 +66,7 @@ public class TooltipScoreVisualization extends AbstractTooltipVisualization { /** * A short name characterizing this Visualizer. */ - public static final String NAME_GEN = "Score Tooltips"; + public static final String NAME_GEN = " Tooltips"; /** * Number format. @@ -137,6 +136,8 @@ public class TooltipScoreVisualization extends AbstractTooltipVisualization { tooltiparea.setStatement(SVGConstants.CSS_FILL_OPACITY_PROPERTY, "0"); tooltiparea.setStatement(SVGConstants.CSS_CURSOR_PROPERTY, SVGConstants.CSS_POINTER_VALUE); svgp.addCSSClassOrLogError(tooltiparea); + + svgp.updateStyleElement(); } /** @@ -186,9 +187,9 @@ public class TooltipScoreVisualization extends AbstractTooltipVisualization { @Override public void processNewResult(HierarchicalResult baseResult, Result result) { // TODO: we can also visualize other scores! - List<OutlierResult> ors = ResultUtil.filterResults(result, OutlierResult.class); + Collection<OutlierResult> ors = ResultUtil.filterResults(result, OutlierResult.class); for(OutlierResult o : ors) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME, o.getScores(), p.getRelation(), this); task.put(VisualizationTask.META_TOOL, true); @@ -197,9 +198,9 @@ public class TooltipScoreVisualization extends AbstractTooltipVisualization { baseResult.getHierarchy().add(p, task); } } - List<Relation<?>> rrs = ResultUtil.filterResults(result, Relation.class); + Collection<Relation<?>> rrs = ResultUtil.filterResults(result, Relation.class); for(Relation<?> r : rrs) { - if(!TypeUtil.DOUBLE.isAssignableFromType(r.getDataTypeInformation())) { + if(!TypeUtil.DOUBLE.isAssignableFromType(r.getDataTypeInformation()) && !TypeUtil.INTEGER.isAssignableFromType(r.getDataTypeInformation())) { continue; } // Skip if we already considered it above @@ -211,9 +212,9 @@ public class TooltipScoreVisualization extends AbstractTooltipVisualization { } } if(add) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { - final VisualizationTask task = new VisualizationTask(NAME_GEN, r, p.getRelation(), this); + final VisualizationTask task = new VisualizationTask(r.getLongName() + NAME_GEN, r, p.getRelation(), this); task.put(VisualizationTask.META_TOOL, true); task.put(VisualizationTask.META_VISIBLE_DEFAULT, false); baseResult.getHierarchy().add(r, task); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipStringVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipStringVisualization.java index 9baea926..d015793c 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipStringVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/TooltipStringVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.ArrayList; +import java.util.Collection; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; @@ -36,7 +36,6 @@ import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; import de.lmu.ifi.dbs.elki.visualization.projector.ScatterPlotProjector; @@ -174,10 +173,10 @@ public class TooltipStringVisualization extends AbstractTooltipVisualization { @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - ArrayList<Relation<?>> reps = ResultUtil.filterResults(result, Relation.class); + Collection<Relation<?>> reps = ResultUtil.filterResults(result, Relation.class); for(Relation<?> rep : reps) { if(DBID.class.isAssignableFrom(rep.getDataTypeInformation().getRestrictionClass())) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME_ID, rep, p.getRelation(), this); task.put(VisualizationTask.META_TOOL, true); @@ -187,7 +186,7 @@ public class TooltipStringVisualization extends AbstractTooltipVisualization { } } if(ClassLabel.class.isAssignableFrom(rep.getDataTypeInformation().getRestrictionClass())) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME_CLASS, rep, p.getRelation(), this); task.put(VisualizationTask.META_TOOL, true); @@ -197,7 +196,7 @@ public class TooltipStringVisualization extends AbstractTooltipVisualization { } } if(LabelList.class.isAssignableFrom(rep.getDataTypeInformation().getRestrictionClass())) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME_LABEL, rep, p.getRelation(), this); task.put(VisualizationTask.META_TOOL, true); @@ -207,7 +206,7 @@ public class TooltipStringVisualization extends AbstractTooltipVisualization { } } if(ExternalID.class.isAssignableFrom(rep.getDataTypeInformation().getRestrictionClass())) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME_EID, rep, p.getRelation(), this); task.put(VisualizationTask.META_TOOL, true); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterHullVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterHullVisualization.java index 430ab194..e1817b1e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterHullVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterHullVisualization.java @@ -36,7 +36,7 @@ import de.lmu.ifi.dbs.elki.data.Clustering; import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.data.spatial.Polygon;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.math.geometry.AlphaShape;
import de.lmu.ifi.dbs.elki.math.geometry.GrahamScanConvexHull2D;
@@ -44,7 +44,6 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -71,7 +70,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.AbstractScatter * @author Erich Schubert
*
* @apiviz.has Clustering oneway - - visualizes
- * @apiviz.uses ConvexHull2D
+ * @apiviz.uses GrahamScanConvexHull2D
* @apiviz.uses AlphaShape
*/
public class ClusterHullVisualization extends AbstractScatterplotVisualization {
@@ -125,8 +124,8 @@ public class ClusterHullVisualization extends AbstractScatterplotVisualization { if(alpha >= Double.POSITIVE_INFINITY) {
GrahamScanConvexHull2D hull = new GrahamScanConvexHull2D();
- for(DBID clpnum : ids) {
- double[] projP = proj.fastProjectDataToRenderSpace(rel.get(clpnum));
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ double[] projP = proj.fastProjectDataToRenderSpace(rel.get(iter));
hull.add(new Vector(projP));
}
Polygon chres = hull.getHull();
@@ -148,8 +147,8 @@ public class ClusterHullVisualization extends AbstractScatterplotVisualization { }
else {
ArrayList<Vector> ps = new ArrayList<Vector>(ids.size());
- for(DBID clpnum : ids) {
- double[] projP = proj.fastProjectDataToRenderSpace(rel.get(clpnum));
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ double[] projP = proj.fastProjectDataToRenderSpace(rel.get(iter));
ps.add(new Vector(projP));
}
List<Polygon> polys = (new AlphaShape(ps, alpha * Projection.SCALE)).compute();
@@ -225,7 +224,7 @@ public class ClusterHullVisualization extends AbstractScatterplotVisualization { // Find clusterings we can visualize:
Collection<Clustering<?>> clusterings = ResultUtil.filterResults(result, Clustering.class);
for(Clustering<?> c : clusterings) {
- IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class);
+ Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, c, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA - 1);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterMeanVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterMeanVisualization.java index c9443a9f..4f14f4ef 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterMeanVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterMeanVisualization.java @@ -23,6 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.cluster; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Collection;
import java.util.Iterator;
import org.apache.batik.util.SVGConstants;
@@ -32,6 +33,8 @@ import de.lmu.ifi.dbs.elki.data.Cluster; import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.data.model.MedoidModel;
+import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -59,6 +62,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.AbstractScatter * @author Heidi Kolb
*
* @apiviz.has MeanModel oneway - - visualizes
+ * @apiviz.has MedoidModel oneway - - visualizes
*/
public class ClusterMeanVisualization extends AbstractScatterplotVisualization {
/**
@@ -84,7 +88,7 @@ public class ClusterMeanVisualization extends AbstractScatterplotVisualization { /**
* Clustering to visualize.
*/
- Clustering<MeanModel<? extends NumberVector<?, ?>>> clustering;
+ Clustering<Model> clustering;
/**
* Draw stars
@@ -111,10 +115,23 @@ public class ClusterMeanVisualization extends AbstractScatterplotVisualization { MarkerLibrary ml = context.getStyleLibrary().markers();
double marker_size = context.getStyleLibrary().getSize(StyleLibrary.MARKERPLOT);
- Iterator<Cluster<MeanModel<? extends NumberVector<?, ?>>>> ci = clustering.getAllClusters().iterator();
+ Iterator<Cluster<Model>> ci = clustering.getAllClusters().iterator();
for(int cnum = 0; ci.hasNext(); cnum++) {
- Cluster<MeanModel<? extends NumberVector<?, ?>>> clus = ci.next();
- double[] mean = proj.fastProjectDataToRenderSpace(clus.getModel().getMean());
+ Cluster<Model> clus = ci.next();
+ Model model = clus.getModel();
+ double[] mean;
+ if(model instanceof MeanModel) {
+ @SuppressWarnings("unchecked")
+ MeanModel<? extends NumberVector<?, ?>> mmodel = (MeanModel<? extends NumberVector<?, ?>>) model;
+ mean = proj.fastProjectDataToRenderSpace(mmodel.getMean());
+ }
+ else if(model instanceof MedoidModel) {
+ MedoidModel mmodel = (MedoidModel) model;
+ mean = proj.fastProjectDataToRenderSpace(rel.get(mmodel.getMedoid()));
+ }
+ else {
+ continue;
+ }
// add a greater Marker for the mean
Element meanMarker = ml.useMarker(svgp, layer, mean[0], mean[1], cnum, marker_size * 3);
@@ -163,7 +180,7 @@ public class ClusterMeanVisualization extends AbstractScatterplotVisualization { if(stars) {
ColorLibrary colors = context.getStyleLibrary().getColorSet(StyleLibrary.PLOT);
- Iterator<Cluster<MeanModel<? extends NumberVector<?, ?>>>> ci = clustering.getAllClusters().iterator();
+ Iterator<Cluster<Model>> ci = clustering.getAllClusters().iterator();
for(int cnum = 0; ci.hasNext(); cnum++) {
ci.next();
if(!svgp.getCSSClassManager().contains(CSS_MEAN_STAR + "_" + cnum)) {
@@ -219,16 +236,13 @@ public class ClusterMeanVisualization extends AbstractScatterplotVisualization { @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
// Find clusterings we can visualize:
- Iterator<Clustering<?>> clusterings = ResultUtil.filteredResults(result, Clustering.class);
- while(clusterings.hasNext()) {
- Clustering<?> c = clusterings.next();
+ Collection<Clustering<?>> clusterings = ResultUtil.filterResults(result, Clustering.class);
+ for(Clustering<?> c : clusterings) {
if(c.getAllClusters().size() > 0) {
// Does the cluster have a model with cluster means?
- Clustering<MeanModel<? extends NumberVector<?, ?>>> mcls = findMeanModel(c);
- if(mcls != null) {
- Iterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class);
- while(ps.hasNext()) {
- ScatterPlotProjector<?> p = ps.next();
+ if(testMeanModel(c)) {
+ Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
+ for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, c, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA + 1);
baseResult.getHierarchy().add(c, task);
@@ -243,14 +257,17 @@ public class ClusterMeanVisualization extends AbstractScatterplotVisualization { * Test if the given clustering has a mean model.
*
* @param c Clustering to inspect
- * @return the clustering cast to return a mean model, null otherwise.
+ * @return true when the clustering has a mean or medoid model.
*/
- @SuppressWarnings("unchecked")
- private static Clustering<MeanModel<? extends NumberVector<?, ?>>> findMeanModel(Clustering<?> c) {
- if(c.getAllClusters().get(0).getModel() instanceof MeanModel<?>) {
- return (Clustering<MeanModel<? extends NumberVector<?, ?>>>) c;
+ private static boolean testMeanModel(Clustering<?> c) {
+ Model firstmodel = c.getAllClusters().get(0).getModel();
+ if(firstmodel instanceof MeanModel<?>) {
+ return true;
+ }
+ if(firstmodel instanceof MedoidModel) {
+ return true;
}
- return null;
+ return false;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterOrderVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterOrderVisualization.java index 1ac55851..0d43875c 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterOrderVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/ClusterOrderVisualization.java @@ -35,7 +35,6 @@ import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry; import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; import de.lmu.ifi.dbs.elki.visualization.projector.ScatterPlotProjector; @@ -135,7 +134,7 @@ public class ClusterOrderVisualization extends AbstractScatterplotVisualization public void processNewResult(HierarchicalResult baseResult, Result result) { Collection<ClusterOrderResult<DoubleDistance>> cos = ResultUtil.filterResults(result, ClusterOrderResult.class); for(ClusterOrderResult<DoubleDistance> co : cos) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME, co, p.getRelation(), this); task.put(VisualizationTask.META_VISIBLE_DEFAULT, false); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/EMClusterVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/EMClusterVisualization.java index 6b2f43a3..6070361e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/EMClusterVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/EMClusterVisualization.java @@ -50,7 +50,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.EmptyParameterization; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.colors.ColorLibrary; @@ -71,7 +70,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.AbstractScatter * @author Robert Rödler * * @apiviz.has EMModel oneway - - visualizes - * @apiviz.uses ConvexHull2D + * @apiviz.uses GrahamScanConvexHull2D * * @param <NV> Type of the NumberVector being visualized. */ @@ -442,7 +441,7 @@ public class EMClusterVisualization<NV extends NumberVector<NV, ?>> extends Abst // Does the cluster have a model with cluster means? Clustering<MeanModel<NV>> mcls = findMeanModel(c); if(mcls != null) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME, c, p.getRelation(), this); task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA + 3); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/VoronoiVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/VoronoiVisualization.java index 37f125d4..d6ce810c 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/VoronoiVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/VoronoiVisualization.java @@ -1,26 +1,27 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.cluster;
-/* - This file is part of ELKI: +
+/*
+ This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2012 - Ludwig-Maximilians-Universität München - Lehr- und Forschungseinheit für Datenbanksysteme +
+ Copyright (C) 2012
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or +
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 +
+ 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ +
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
import java.util.ArrayList;
import java.util.Collection;
@@ -32,8 +33,8 @@ import org.w3c.dom.Element; import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.data.model.EMModel;
import de.lmu.ifi.dbs.elki.data.model.MeanModel;
+import de.lmu.ifi.dbs.elki.data.model.MedoidModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.math.geometry.SweepHullDelaunay2D;
import de.lmu.ifi.dbs.elki.math.geometry.SweepHullDelaunay2D.Triangle;
@@ -42,7 +43,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -62,13 +62,14 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.AbstractScatter /**
* Visualizer drawing Voronoi cells for k-means clusterings.
*
- * See also: {@link de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansLloyd KMeans
- * clustering}
+ * See also: {@link de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansLloyd
+ * KMeans clustering}
*
* @author Robert Rödler
* @author Erich Schubert
*
* @apiviz.has MeanModel oneway - - visualizes
+ * @apiviz.has MedoidModel oneway - - visualizes
*/
public class VoronoiVisualization extends AbstractScatterplotVisualization {
/**
@@ -95,7 +96,7 @@ public class VoronoiVisualization extends AbstractScatterplotVisualization { /**
* The result we work on
*/
- Clustering<MeanModel<? extends NumberVector<?, ?>>> clustering;
+ Clustering<Model> clustering;
/**
* The Voronoi diagram
@@ -123,7 +124,7 @@ public class VoronoiVisualization extends AbstractScatterplotVisualization { @Override
protected void redraw() {
addCSSClasses(svgp);
- final List<Cluster<MeanModel<? extends NumberVector<?, ?>>>> clusters = clustering.getAllClusters();
+ final List<Cluster<Model>> clusters = clustering.getAllClusters();
if(clusters.size() < 2) {
return;
@@ -133,8 +134,22 @@ public class VoronoiVisualization extends AbstractScatterplotVisualization { if(clusters.size() == 2) {
ArrayList<double[]> means = new ArrayList<double[]>(clusters.size());
{
- for(Cluster<MeanModel<? extends NumberVector<?, ?>>> clus : clusters) {
- means.add(clus.getModel().getMean().getColumnVector().getArrayRef());
+ for(Cluster<Model> clus : clusters) {
+ Model model = clus.getModel();
+ double[] mean;
+ if(model instanceof MeanModel) {
+ @SuppressWarnings("unchecked")
+ MeanModel<? extends NumberVector<?, ?>> mmodel = (MeanModel<? extends NumberVector<?, ?>>) model;
+ mean = proj.fastProjectDataToRenderSpace(mmodel.getMean());
+ }
+ else if(model instanceof MedoidModel) {
+ MedoidModel mmodel = (MedoidModel) model;
+ mean = proj.fastProjectDataToRenderSpace(rel.get(mmodel.getMedoid()));
+ }
+ else {
+ continue;
+ }
+ means.add(mean);
}
}
if(mode == Mode.VORONOI || mode == Mode.V_AND_D) {
@@ -143,7 +158,7 @@ public class VoronoiVisualization extends AbstractScatterplotVisualization { layer.appendChild(path);
}
if(mode == Mode.DELAUNAY || mode == Mode.V_AND_D) {
- Element path = new SVGPath(proj.fastProjectDataToRenderSpace(means.get(0))).drawTo(proj.fastProjectDataToRenderSpace(means.get(1))).makeElement(svgp);
+ Element path = new SVGPath(means.get(0)).drawTo(means.get(1)).makeElement(svgp);
SVGUtil.addCSSClass(path, KMEANSBORDER);
layer.appendChild(path);
}
@@ -152,10 +167,23 @@ public class VoronoiVisualization extends AbstractScatterplotVisualization { ArrayList<Vector> vmeans = new ArrayList<Vector>(clusters.size());
ArrayList<double[]> means = new ArrayList<double[]>(clusters.size());
{
- for(Cluster<MeanModel<? extends NumberVector<?, ?>>> clus : clusters) {
- Vector v = clus.getModel().getMean().getColumnVector();
- vmeans.add(v);
- means.add(v.getArrayRef());
+ for(Cluster<Model> clus : clusters) {
+ Model model = clus.getModel();
+ Vector mean;
+ if(model instanceof MeanModel) {
+ @SuppressWarnings("unchecked")
+ MeanModel<? extends NumberVector<?, ?>> mmodel = (MeanModel<? extends NumberVector<?, ?>>) model;
+ mean = mmodel.getMean().getColumnVector();
+ }
+ else if(model instanceof MedoidModel) {
+ MedoidModel mmodel = (MedoidModel) model;
+ mean = rel.get(mmodel.getMedoid()).getColumnVector();
+ }
+ else {
+ continue;
+ }
+ vmeans.add(mean);
+ means.add(mean.getArrayRef());
}
}
// Compute Delaunay Triangulation
@@ -200,7 +228,7 @@ public class VoronoiVisualization extends AbstractScatterplotVisualization { * @author Erich Schubert
*
* @apiviz.stereotype factory
- * @apiviz.uses VoronoiVisualisation oneway - - «create»
+ * @apiviz.uses VoronoiVisualization oneway - - «create»
*/
public static class Factory extends AbstractVisFactory {
/**
@@ -239,9 +267,8 @@ public class VoronoiVisualization extends AbstractScatterplotVisualization { for(Clustering<?> c : clusterings) {
if(c.getAllClusters().size() > 0) {
// Does the cluster have a model with cluster means?
- Clustering<MeanModel<? extends NumberVector<?, ?>>> mcls = findMeanModel(c);
- if(mcls != null) {
- IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class);
+ if(testMeanModel(c)) {
+ Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
if(DatabaseUtil.dimensionality(p.getRelation()) == 2) {
final VisualizationTask task = new VisualizationTask(NAME, c, p.getRelation(), this);
@@ -259,15 +286,17 @@ public class VoronoiVisualization extends AbstractScatterplotVisualization { * Test if the given clustering has a mean model.
*
* @param c Clustering to inspect
- * @return the clustering cast to return a mean model, null otherwise.
+ * @return true when the clustering has a mean or medoid model.
*/
- @SuppressWarnings("unchecked")
- private static Clustering<MeanModel<? extends NumberVector<?, ?>>> findMeanModel(Clustering<?> c) {
- final Model firstModel = c.getAllClusters().get(0).getModel();
- if(firstModel instanceof MeanModel<?> && !(firstModel instanceof EMModel<?>)) {
- return (Clustering<MeanModel<? extends NumberVector<?, ?>>>) c;
+ private static boolean testMeanModel(Clustering<?> c) {
+ Model firstmodel = c.getAllClusters().get(0).getModel();
+ if(firstmodel instanceof MeanModel<?>) {
+ return true;
+ }
+ if(firstmodel instanceof MedoidModel) {
+ return true;
}
- return null;
+ return false;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/DensityEstimationOverlay.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/DensityEstimationOverlay.java index 28e4da32..c07bc571 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/DensityEstimationOverlay.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/DensityEstimationOverlay.java @@ -24,12 +24,13 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.density; */ import java.awt.image.BufferedImage; import java.util.Arrays; +import java.util.Collection; import java.util.Comparator; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; -import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.math.MathUtil; import de.lmu.ifi.dbs.elki.math.MeanVariance; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; @@ -37,7 +38,6 @@ import de.lmu.ifi.dbs.elki.result.KMLOutputHandler; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.batikutil.ThumbnailRegistryEntry; import de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize; @@ -124,8 +124,8 @@ public class DensityEstimationOverlay extends AbstractScatterplotVisualization { double[][] data = new double[rel.size()][]; { int i = 0; - for(DBID id : rel.iterDBIDs()) { - data[i] = proj.fastProjectDataToRenderSpace(rel.get(id)); + for(DBIDIter iditer = rel.iterDBIDs(); iditer.valid(); iditer.advance()) { + data[i] = proj.fastProjectDataToRenderSpace(rel.get(iditer)); i++; } } @@ -206,7 +206,7 @@ public class DensityEstimationOverlay extends AbstractScatterplotVisualization { * @author Erich Schubert * * @apiviz.stereotype factory - * @apiviz.uses DensityEstimation2DVisualization oneway - - «create» + * @apiviz.uses DensityEstimationOverlay oneway - - «create» */ public static class Factory extends AbstractVisFactory { /** @@ -224,7 +224,7 @@ public class DensityEstimationOverlay extends AbstractScatterplotVisualization { @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(result, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(result, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME, p.getRelation(), p.getRelation(), this); task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA + 1); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeMBRVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeMBRVisualization.java index 0b4bee2f..61635625 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeMBRVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeMBRVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.index; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.ArrayList; +import java.util.Collection; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; @@ -38,7 +38,6 @@ import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeNode; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; @@ -214,10 +213,10 @@ public class TreeMBRVisualization<N extends AbstractRStarTreeNode<N, E>, E exten @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - ArrayList<AbstractRStarTree<RStarTreeNode, SpatialEntry>> trees = ResultUtil.filterResults(result, AbstractRStarTree.class); + Collection<AbstractRStarTree<RStarTreeNode, SpatialEntry>> trees = ResultUtil.filterResults(result, AbstractRStarTree.class); for(AbstractRStarTree<RStarTreeNode, SpatialEntry> tree : trees) { if(tree instanceof Result) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME, (Result) tree, p.getRelation(), this); task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_BACKGROUND + 1); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeSphereVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeSphereVisualization.java index 85429eb1..daebab02 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeSphereVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/TreeSphereVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.index; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.ArrayList; +import java.util.Collection; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; @@ -44,7 +44,6 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree.MTreeNode; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag; @@ -271,9 +270,9 @@ public class TreeSphereVisualization<D extends NumberDistance<D, ?>, N extends A @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { - ArrayList<AbstractMTree<?, DoubleDistance, ?, ?>> trees = ResultUtil.filterResults(result, AbstractMTree.class); + Collection<AbstractMTree<?, DoubleDistance, ?, ?>> trees = ResultUtil.filterResults(result, AbstractMTree.class); for(AbstractMTree<?, DoubleDistance, ?, ?> tree : trees) { if(canVisualize(tree) && tree instanceof Result) { final VisualizationTask task = new VisualizationTask(NAME, (Result) tree, p.getRelation(), this); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/BubbleVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/BubbleVisualization.java index 7c40c1cb..769dc53d 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/BubbleVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/BubbleVisualization.java @@ -23,20 +23,20 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.outlier; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.List; +import java.util.Collection; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener; -import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; +import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; @@ -56,6 +56,7 @@ import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil; import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisFactory; import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; import de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.AbstractScatterplotVisualization; +import de.lmu.ifi.dbs.elki.visualization.visualizers.thumbs.ThumbnailVisualization; /** * Generates a SVG-Element containing bubbles. A Bubble is a circle visualizing @@ -99,18 +100,22 @@ public class BubbleVisualization extends AbstractScatterplotVisualization implem * * @param task Visualization task * @param scaling Scaling function + * @param fill Fill flag */ - public BubbleVisualization(VisualizationTask task, ScalingFunction scaling) { + public BubbleVisualization(VisualizationTask task, ScalingFunction scaling, boolean fill) { super(task); this.result = task.getResult(); this.scaling = scaling; + this.fill = fill; context.addDataStoreListener(this); + context.addResultListener(this); incrementalRedraw(); } @Override public void destroy() { super.destroy(); + context.removeResultListener(this); context.removeDataStoreListener(this); } @@ -123,7 +128,7 @@ public class BubbleVisualization extends AbstractScatterplotVisualization implem ClassStylingPolicy colors = (ClassStylingPolicy) stylepolicy; setupCSS(svgp, colors); // draw data - for(DBID objId : sample.getSample()) { + for(DBIDIter objId = sample.getSample().iter(); objId.valid(); objId.advance()) { final Double radius = getScaledForId(objId); if(radius > 0.01 && !Double.isInfinite(radius)) { final NumberVector<?, ?> vec = rel.get(objId); @@ -138,7 +143,7 @@ public class BubbleVisualization extends AbstractScatterplotVisualization implem } else { // draw data - for(DBID objId : sample.getSample()) { + for(DBIDIter objId = sample.getSample().iter(); objId.valid(); objId.advance()) { final Double radius = getScaledForId(objId); if(radius > 0.01 && !Double.isInfinite(radius)) { final NumberVector<?, ?> vec = rel.get(objId); @@ -165,7 +170,8 @@ public class BubbleVisualization extends AbstractScatterplotVisualization implem @Override public void resultChanged(Result current) { - if(sample == current) { + super.resultChanged(current); + if(sample == current || context.getStyleResult() == current) { synchronizedRedraw(); } } @@ -207,7 +213,7 @@ public class BubbleVisualization extends AbstractScatterplotVisualization implem * @return a Double representing a outlierness-score, after it has modified by * the given scales. */ - protected double getScaledForId(DBID id) { + protected double getScaledForId(DBIDRef id) { double d = result.getScores().get(id).doubleValue(); if(Double.isNaN(d) || Double.isInfinite(d)) { return 0.0; @@ -267,6 +273,7 @@ public class BubbleVisualization extends AbstractScatterplotVisualization implem super(); this.fill = fill; this.scaling = scaling; + thumbmask |= ThumbnailVisualization.ON_DATA | ThumbnailVisualization.ON_STYLE; } @Override @@ -275,14 +282,14 @@ public class BubbleVisualization extends AbstractScatterplotVisualization implem final OutlierResult outlierResult = task.getResult(); ((OutlierScalingFunction) this.scaling).prepare(outlierResult); } - return new BubbleVisualization(task, scaling); + return new BubbleVisualization(task, scaling, fill); } @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - List<OutlierResult> ors = ResultUtil.filterResults(result, OutlierResult.class); + Collection<OutlierResult> ors = ResultUtil.filterResults(result, OutlierResult.class); for(OutlierResult o : ors) { - IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class); + Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); boolean vis = true; // Quick and dirty hack: hide if parent result is also an outlier result // Since that probably is already visible and we're redundant. diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/MoveObjectsToolVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/MoveObjectsToolVisualization.java index fb9de7d5..6b466a88 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/MoveObjectsToolVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/MoveObjectsToolVisualization.java @@ -23,13 +23,14 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.selection; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.Iterator;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
import org.w3c.dom.events.Event;
import org.w3c.dom.svg.SVGPoint;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.UpdatableDatabase;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
@@ -37,7 +38,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea.DragListener;
@@ -79,6 +79,11 @@ public class MoveObjectsToolVisualization extends AbstractScatterplotVisualizati */
private Element rtag;
+ /**
+ * Constructor.
+ *
+ * @param task Task
+ */
public MoveObjectsToolVisualization(VisualizationTask task) {
super(task);
incrementalRedraw();
@@ -113,6 +118,7 @@ public class MoveObjectsToolVisualization extends AbstractScatterplotVisualizati */
// TODO: move to DatabaseUtil?
private void updateDB(DBIDs dbids, Vector movingVector) {
+ NumberVector<?, ?> nv = null;
throw new AbortException("FIXME: INCOMPLETE TRANSITION");
/*
* database.accumulateDataStoreEvents();
@@ -208,11 +214,11 @@ public class MoveObjectsToolVisualization extends AbstractScatterplotVisualizati @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- Iterator<UpdatableDatabase> dbs = ResultUtil.filteredResults(result, UpdatableDatabase.class);
- if(!dbs.hasNext()) {
+ Collection<UpdatableDatabase> dbs = ResultUtil.filterResults(result, UpdatableDatabase.class);
+ if(dbs.isEmpty()) {
return;
}
- IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class);
+ Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, p.getRelation(), p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionConvexHullVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionConvexHullVisualization.java index 5702800d..8a28ab3e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionConvexHullVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionConvexHullVisualization.java @@ -23,14 +23,14 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.selection; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
import de.lmu.ifi.dbs.elki.data.spatial.Polygon;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.math.geometry.GrahamScanConvexHull2D;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
@@ -40,7 +40,6 @@ import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ObjectNotFoundException;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
import de.lmu.ifi.dbs.elki.visualization.projector.ScatterPlotProjector;
@@ -61,7 +60,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.thumbs.ThumbnailVisualizati *
* @apiviz.has SelectionResult oneway - - visualizes
* @apiviz.has DBIDSelection oneway - - visualizes
- * @apiviz.uses ConvexHull2D
+ * @apiviz.uses GrahamScanConvexHull2D
*/
public class SelectionConvexHullVisualization extends AbstractScatterplotVisualization implements DataStoreListener {
/**
@@ -93,9 +92,9 @@ public class SelectionConvexHullVisualization extends AbstractScatterplotVisuali if(selContext != null) {
DBIDs selection = selContext.getSelectedIds();
GrahamScanConvexHull2D hull = new GrahamScanConvexHull2D();
- for(DBID i : selection) {
+ for(DBIDIter iter = selection.iter(); iter.valid(); iter.advance()) {
try {
- hull.add(new Vector(proj.fastProjectDataToRenderSpace(rel.get(i))));
+ hull.add(new Vector(proj.fastProjectDataToRenderSpace(rel.get(iter))));
}
catch(ObjectNotFoundException e) {
// ignore
@@ -158,9 +157,9 @@ public class SelectionConvexHullVisualization extends AbstractScatterplotVisuali @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- final ArrayList<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
+ Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
for(SelectionResult selres : selectionResults) {
- IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class);
+ Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA - 2);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionCubeVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionCubeVisualization.java index 9fd24b43..5151e81e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionCubeVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionCubeVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.selection; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
@@ -35,7 +35,6 @@ import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -227,9 +226,9 @@ public class SelectionCubeVisualization extends AbstractScatterplotVisualization @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- final ArrayList<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
+ Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
for(SelectionResult selres : selectionResults) {
- IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class);
+ Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA - 2);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionDotVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionDotVisualization.java index 79d1afe5..1dc5ce13 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionDotVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionDotVisualization.java @@ -23,13 +23,13 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.selection; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.result.DBIDSelection;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
@@ -37,7 +37,6 @@ import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ObjectNotFoundException;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
import de.lmu.ifi.dbs.elki.visualization.projector.ScatterPlotProjector;
@@ -94,9 +93,9 @@ public class SelectionDotVisualization extends AbstractScatterplotVisualization DBIDSelection selContext = context.getSelection();
if(selContext != null) {
DBIDs selection = selContext.getSelectedIds();
- for(DBID i : selection) {
+ for(DBIDIter iter = selection.iter(); iter.valid(); iter.advance()) {
try {
- double[] v = proj.fastProjectDataToRenderSpace(rel.get(i));
+ double[] v = proj.fastProjectDataToRenderSpace(rel.get(iter));
Element dot = svgp.svgCircle(v[0], v[1], size);
SVGUtil.addCSSClass(dot, MARKER);
layer.appendChild(dot);
@@ -149,9 +148,9 @@ public class SelectionDotVisualization extends AbstractScatterplotVisualization @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- final ArrayList<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
+ Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
for(SelectionResult selres : selectionResults) {
- IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class);
+ Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA - 1);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolCubeVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolCubeVisualization.java index 8e86f920..bc16fd83 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolCubeVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolCubeVisualization.java @@ -23,8 +23,8 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.selection; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
import java.util.BitSet;
+import java.util.Collection;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
@@ -32,7 +32,7 @@ import org.w3c.dom.events.Event; import org.w3c.dom.svg.SVGPoint;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
import de.lmu.ifi.dbs.elki.logging.Logging;
@@ -43,7 +43,6 @@ import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
@@ -192,6 +191,11 @@ public class SelectionToolCubeVisualization extends AbstractScatterplotVisualiza * @param p2 Second Point of the selected rectangle
*/
private void updateSelection(Projection proj, SVGPoint p1, SVGPoint p2) {
+ if(p1 == null || p2 == null) {
+ logger.warning("no rect selected: p1: " + p1 + " p2: " + p2);
+ return;
+ }
+
DBIDSelection selContext = context.getSelection();
ModifiableDBIDs selection;
if(selContext != null) {
@@ -202,42 +206,32 @@ public class SelectionToolCubeVisualization extends AbstractScatterplotVisualiza }
DoubleDoublePair[] ranges;
- if(p1 == null || p2 == null) {
- logger.warning("no rect selected: p1: " + p1 + " p2: " + p2);
+ double x1 = Math.min(p1.getX(), p2.getX());
+ double x2 = Math.max(p1.getX(), p2.getX());
+ double y1 = Math.max(p1.getY(), p2.getY());
+ double y2 = Math.min(p1.getY(), p2.getY());
+
+ if(selContext instanceof RangeSelection) {
+ ranges = ((RangeSelection) selContext).getRanges();
}
else {
- double x1 = Math.min(p1.getX(), p2.getX());
- double x2 = Math.max(p1.getX(), p2.getX());
- double y1 = Math.max(p1.getY(), p2.getY());
- double y2 = Math.min(p1.getY(), p2.getY());
-
- if(selContext instanceof RangeSelection) {
- ranges = ((RangeSelection) selContext).getRanges();
- }
- else {
- ranges = new DoubleDoublePair[dim];
- }
- updateSelectionRectKoordinates(x1, x2, y1, y2, ranges);
-
- selection.clear();
- boolean idIn = true;
- for(DBID id : rel.iterDBIDs()) {
- NumberVector<?, ?> dbTupel = rel.get(id);
- idIn = true;
- for(int i = 0; i < dim; i++) {
- if(ranges != null && ranges[i] != null) {
- if(dbTupel.doubleValue(i + 1) < ranges[i].first || dbTupel.doubleValue(i + 1) > ranges[i].second) {
- idIn = false;
- break;
- }
+ ranges = new DoubleDoublePair[dim];
+ }
+ updateSelectionRectKoordinates(x1, x2, y1, y2, ranges);
+
+ selection.clear();
+ candidates: for(DBIDIter iditer = rel.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ NumberVector<?, ?> dbTupel = rel.get(iditer);
+ for(int i = 0; i < dim; i++) {
+ if(ranges != null && ranges[i] != null) {
+ if(dbTupel.doubleValue(i + 1) < ranges[i].first || dbTupel.doubleValue(i + 1) > ranges[i].second) {
+ continue candidates;
}
}
- if(idIn == true) {
- selection.add(id);
- }
}
- context.setSelection(new RangeSelection(selection, ranges));
+ selection.add(iditer);
}
+ context.setSelection(new RangeSelection(selection, ranges));
}
/**
@@ -281,9 +275,9 @@ public class SelectionToolCubeVisualization extends AbstractScatterplotVisualiza @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- final ArrayList<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
+ Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
for(SelectionResult selres : selectionResults) {
- IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class);
+ Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolDotVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolDotVisualization.java index 877833f7..b52f37c9 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolDotVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionToolDotVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.selection; along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
+import java.util.Collection;
import org.apache.batik.dom.events.DOMMouseEvent;
import org.apache.batik.util.SVGConstants;
@@ -31,7 +31,7 @@ import org.w3c.dom.Element; import org.w3c.dom.events.Event;
import org.w3c.dom.svg.SVGPoint;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
import de.lmu.ifi.dbs.elki.result.DBIDSelection;
@@ -39,7 +39,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result;
import de.lmu.ifi.dbs.elki.result.ResultUtil;
import de.lmu.ifi.dbs.elki.result.SelectionResult;
-import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator;
import de.lmu.ifi.dbs.elki.visualization.VisualizationTask;
import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
@@ -194,22 +193,22 @@ public class SelectionToolDotVisualization extends AbstractScatterplotVisualizat else {
selection = DBIDUtil.newHashSet(selContext.getSelectedIds());
}
- for(DBID id : rel.iterDBIDs()) {
- double[] vec = proj.fastProjectDataToRenderSpace(rel.get(id));
+ for(DBIDIter iditer = rel.iterDBIDs(); iditer.valid(); iditer.advance()) { + double[] vec = proj.fastProjectDataToRenderSpace(rel.get(iditer));
if(vec[0] >= Math.min(p1.getX(), p2.getX()) && vec[0] <= Math.max(p1.getX(), p2.getX()) && vec[1] >= Math.min(p1.getY(), p2.getY()) && vec[1] <= Math.max(p1.getY(), p2.getY())) {
if(mode == Mode.INVERT) {
- if(!selection.contains(id)) {
- selection.add(id);
+ if(!selection.contains(iditer)) {
+ selection.add(iditer);
}
else {
- selection.remove(id);
+ selection.remove(iditer);
}
}
else {
// In REPLACE and ADD, add objects.
// The difference was done before by not re-using the selection.
// Since we are using a set, we can just add in any case.
- selection.add(id);
+ selection.add(iditer);
}
}
}
@@ -256,9 +255,9 @@ public class SelectionToolDotVisualization extends AbstractScatterplotVisualizat @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- final ArrayList<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
+ Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
for(SelectionResult selres : selectionResults) {
- IterableIterator<ScatterPlotProjector<?>> ps = ResultUtil.filteredResults(baseResult, ScatterPlotProjector.class);
+ Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
for(ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailThread.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailThread.java index 2c9425de..8d045138 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailThread.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailThread.java @@ -31,7 +31,6 @@ import java.util.concurrent.ConcurrentLinkedQueue; * * @author Erich Schubert * - * @apiviz.composedOf Thumbnailer * @apiviz.uses Listener oneway - - signals */ public class ThumbnailThread extends Thread { diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java index 05d9038c..5b58e842 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java @@ -59,7 +59,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; * * @apiviz.stereotype factory * @apiviz.uses StaticVisualization oneway - - «create» - * @apiviz.has EvaluateClustering.ScoreResult oneway - - visualizes + * @apiviz.has de.lmu.ifi.dbs.elki.evaluation.clustering.EvaluateClustering.ScoreResult oneway - - visualizes */ public class ClusterEvaluationVisFactory extends AbstractVisFactory { /** diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java index 15c50a39..62a4fb5c 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.Iterator; +import java.util.Collection; import java.util.List; import org.apache.batik.util.SVGConstants; @@ -98,13 +98,14 @@ public class KeyVisualization extends AbstractVisualization { SVGPlot svgp = task.getPlot(); final List<Cluster<Model>> allcs = clustering.getAllClusters(); - MarkerLibrary ml = context.getStyleLibrary().markers(); + StyleLibrary style = context.getStyleLibrary(); + MarkerLibrary ml = style.markers(); layer = svgp.svgElement(SVGConstants.SVG_G_TAG); // Add a label for the clustering. { Element label = svgp.svgText(0.1, 0.7, clustering.getLongName()); - label.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: 0.4"); + label.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: 0.4; fill: "+style.getTextColor(StyleLibrary.DEFAULT)); layer.appendChild(label); } @@ -113,7 +114,7 @@ public class KeyVisualization extends AbstractVisualization { for(Cluster<Model> c : allcs) { ml.useMarker(svgp, layer, 0.3, i + 1.5, i, 0.3); Element label = svgp.svgText(0.7, i + 1.7, c.getNameAutomatic()); - label.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: 0.6"); + label.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: 0.6; fill: "+style.getTextColor(StyleLibrary.DEFAULT)); layer.appendChild(label); i++; } @@ -146,7 +147,7 @@ public class KeyVisualization extends AbstractVisualization { int rows = i + 2; int cols = Math.max(6, (int) (rows * task.getHeight() / task.getWidth())); - final double margin = context.getStyleLibrary().getSize(StyleLibrary.MARGIN); + final double margin = style.getSize(StyleLibrary.MARGIN); final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), cols, rows, margin / StyleLibrary.SCALE); SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform); } @@ -171,9 +172,8 @@ public class KeyVisualization extends AbstractVisualization { @Override public void processNewResult(HierarchicalResult baseResult, Result newResult) { // Find clusterings we can visualize: - Iterator<Clustering<?>> clusterings = ResultUtil.filteredResults(newResult, Clustering.class); - while(clusterings.hasNext()) { - Clustering<?> c = clusterings.next(); + Collection<Clustering<?>> clusterings = ResultUtil.filterResults(newResult, Clustering.class); + for (Clustering<?> c : clusterings) { if(c.getAllClusters().size() > 0) { final VisualizationTask task = new VisualizationTask(NAME, c, null, this); task.width = 1.0; diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java index 5bbc698c..2d726257 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java @@ -32,7 +32,6 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.result.SettingsResult; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter; import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; @@ -138,7 +137,7 @@ public class SettingsVisFactory extends AbstractVisFactory { @Override public void processNewResult(HierarchicalResult baseResult, Result newResult) { - final IterableIterator<SettingsResult> settingsResults = ResultUtil.filteredResults(newResult, SettingsResult.class); + Collection<SettingsResult> settingsResults = ResultUtil.filterResults(newResult, SettingsResult.class); for(SettingsResult sr : settingsResults) { final VisualizationTask task = new VisualizationTask(NAME, sr, null, this); task.width = 1.0; diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisFactory.java index e12a392a..507de376 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisFactory.java @@ -23,25 +23,21 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.Collection; -import java.util.Iterator; +import java.util.ArrayList; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; -import de.lmu.ifi.dbs.elki.evaluation.roc.ComputeROCCurve; -import de.lmu.ifi.dbs.elki.evaluation.roc.ComputeROCCurve.ROCResult; +import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierROCCurve; +import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierROCCurve.ROCResult; +import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierPrecisionRecallCurve.PRCurve; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; -import de.lmu.ifi.dbs.elki.math.DoubleMinMax; +import de.lmu.ifi.dbs.elki.math.geometry.XYCurve; import de.lmu.ifi.dbs.elki.math.scales.LinearScale; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; -import de.lmu.ifi.dbs.elki.result.IterableResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; -import de.lmu.ifi.dbs.elki.utilities.iterator.AbstractFilteredIterator; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; -import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; @@ -62,13 +58,13 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; * * @apiviz.stereotype factory * @apiviz.uses StaticVisualization oneway - - «create» - * @apiviz.has IterableResult oneway - - visualizes + * @apiviz.has XYCurve oneway - - visualizes */ -public class CurveVisFactory extends AbstractVisFactory { +public class XYCurveVisFactory extends AbstractVisFactory { /** * Name for this visualizer. */ - private static final String NAME = "Curve"; + private static final String NAME = "XYCurve"; /** * SVG class name for plot line @@ -76,9 +72,14 @@ public class CurveVisFactory extends AbstractVisFactory { private static final String SERIESID = "series"; /** + * Axis labels + */ + private static final String CSS_AXIS_LABEL = "xy-axis-label"; + + /** * Constructor, Parameterizable style - does nothing. */ - public CurveVisFactory() { + public XYCurveVisFactory() { super(); } @@ -86,7 +87,7 @@ public class CurveVisFactory extends AbstractVisFactory { public Visualization makeVisualization(VisualizationTask task) { VisualizerContext context = task.getContext(); SVGPlot svgp = task.getPlot(); - IterableResult<DoubleDoublePair> curve = task.getResult(); + XYCurve curve = task.getResult(); setupCSS(context, svgp); double scale = StyleLibrary.SCALE; @@ -98,19 +99,13 @@ public class CurveVisFactory extends AbstractVisFactory { SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform); // determine scaling - DoubleMinMax minmaxx = new DoubleMinMax(); - DoubleMinMax minmaxy = new DoubleMinMax(); - for(DoubleDoublePair pair : curve) { - minmaxx.put(pair.first); - minmaxy.put(pair.second); - } - LinearScale scalex = new LinearScale(minmaxx.getMin(), minmaxx.getMax()); - LinearScale scaley = new LinearScale(minmaxy.getMin(), minmaxy.getMax()); + LinearScale scalex = new LinearScale(curve.getMinx(), curve.getMaxx()); + LinearScale scaley = new LinearScale(curve.getMiny(), curve.getMaxy()); // plot the line SVGPath path = new SVGPath(); - for(DoubleDoublePair pair : curve) { - final double x = scalex.getScaled(pair.first); - final double y = 1 - scaley.getScaled(pair.second); + for(XYCurve.Itr iterator = curve.iterator(); iterator.valid(); iterator.advance()) { + final double x = scalex.getScaled(iterator.getX()); + final double y = 1 - scaley.getScaled(iterator.getY()); path.drawTo(sizex * x, sizey * y); } Element line = path.makeElement(svgp); @@ -124,35 +119,44 @@ public class CurveVisFactory extends AbstractVisFactory { catch(CSSNamingConflict e) { LoggingUtil.exception(e); } + // Add axis labels + { + Element labelx = svgp.svgText(sizex / 2, sizey + margin * .9, curve.getLabelx()); + SVGUtil.setCSSClass(labelx, CSS_AXIS_LABEL); + layer.appendChild(labelx); + Element labely = svgp.svgText(margin * -.8, sizey * .5, curve.getLabely()); + SVGUtil.setCSSClass(labely, CSS_AXIS_LABEL); + SVGUtil.setAtt(labely, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, "rotate(-90,"+FormatUtil.NF6.format(margin * -.8)+","+FormatUtil.NF6.format(sizey * .5)+")"); + layer.appendChild(labely); + } // Add AUC value when found if(curve instanceof ROCResult) { - Collection<String> header = ((ROCResult) curve).getHeader(); - for(String str : header) { - String[] parts = str.split(":\\s*"); - if(parts[0].equals(ComputeROCCurve.ROCAUC_LABEL) && parts.length == 2) { - double rocauc = Double.parseDouble(parts[1]); - StyleLibrary style = context.getStyleLibrary(); - CSSClass cls = new CSSClass(svgp, "unmanaged"); - String lt = "ROC AUC: " + FormatUtil.NF8.format(rocauc); - double fontsize = style.getTextSize("curve.labels"); - cls.setStatement(SVGConstants.CSS_FONT_SIZE_PROPERTY, SVGUtil.fmt(fontsize)); - cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, style.getTextColor("curve.labels")); - cls.setStatement(SVGConstants.CSS_FONT_FAMILY_PROPERTY, style.getFontFamily("curve.labels")); - if(rocauc <= 0.5) { - Element auclbl = svgp.svgText(sizex * 0.95, sizey * 0.95, lt); - SVGUtil.setAtt(auclbl, SVGConstants.SVG_STYLE_ATTRIBUTE, cls.inlineCSS()); - // SVGUtil.setAtt(auclbl, SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE, - // SVGConstants.SVG_START_VALUE); - layer.appendChild(auclbl); - } - else { - Element auclbl = svgp.svgText(sizex * 0.95, sizey * 0.95, lt); - SVGUtil.setAtt(auclbl, SVGConstants.SVG_STYLE_ATTRIBUTE, cls.inlineCSS()); - SVGUtil.setAtt(auclbl, SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE, SVGConstants.SVG_END_VALUE); - layer.appendChild(auclbl); - } - } + double rocauc = ((ROCResult) curve).getAUC(); + String lt = OutlierROCCurve.ROCAUC_LABEL + ": " + FormatUtil.NF8.format(rocauc); + if(rocauc <= 0.5) { + Element auclbl = svgp.svgText(sizex * 0.5, sizey * 0.10, lt); + SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL); + layer.appendChild(auclbl); + } + else { + Element auclbl = svgp.svgText(sizex * 0.5, sizey * 0.95, lt); + SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL); + layer.appendChild(auclbl); + } + } + if(curve instanceof PRCurve) { + double prauc = ((PRCurve) curve).getAUC(); + String lt = PRCurve.PRAUC_LABEL + ": " + FormatUtil.NF8.format(prauc); + if(prauc <= 0.5) { + Element auclbl = svgp.svgText(sizex * 0.5, sizey * 0.10, lt); + SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL); + layer.appendChild(auclbl); + } + else { + Element auclbl = svgp.svgText(sizex * 0.5, sizey * 0.95, lt); + SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL); + layer.appendChild(auclbl); } } @@ -166,66 +170,26 @@ public class CurveVisFactory extends AbstractVisFactory { * @param svgp Plot */ private void setupCSS(VisualizerContext context, SVGPlot svgp) { + StyleLibrary style = context.getStyleLibrary(); CSSClass csscls = new CSSClass(this, SERIESID); // csscls.setStatement(SVGConstants.SVG_STROKE_WIDTH_ATTRIBUTE, "0.2%"); csscls.setStatement(SVGConstants.SVG_FILL_ATTRIBUTE, SVGConstants.SVG_NONE_VALUE); - context.getStyleLibrary().lines().formatCSSClass(csscls, 0, context.getStyleLibrary().getLineWidth(StyleLibrary.PLOT)); + style.lines().formatCSSClass(csscls, 0, style.getLineWidth(StyleLibrary.XYCURVE)); svgp.addCSSClassOrLogError(csscls); - } - - /** - * Filter to only retrieve double-double-pair results. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - class CurveFilter extends AbstractFilteredIterator<IterableResult<?>, IterableResult<DoubleDoublePair>> implements IterableIterator<IterableResult<DoubleDoublePair>> { - /** - * Parent iterator to use - */ - Iterator<IterableResult<?>> parent; - - /** - * Constructor. - * - * @param parent Parent iterator to decorate. - */ - public CurveFilter(Iterator<IterableResult<?>> parent) { - super(); - this.parent = parent; - } - - @Override - protected Iterator<IterableResult<?>> getParentIterator() { - return parent; - } - - @Override - protected IterableResult<DoubleDoublePair> testFilter(IterableResult<?> nextobj) { - Iterator<?> iterator = nextobj.iterator(); - if(iterator.hasNext()) { - Object o = iterator.next(); - if(o instanceof DoubleDoublePair) { - @SuppressWarnings("unchecked") - final IterableResult<DoubleDoublePair> ret = (IterableResult<DoubleDoublePair>) nextobj; - return ret; - } - } - return null; - } - - @Override - public Iterator<IterableResult<DoubleDoublePair>> iterator() { - return this; - } + // Axis label + CSSClass label = new CSSClass(this, CSS_AXIS_LABEL); + label.setStatement(SVGConstants.CSS_FILL_PROPERTY, style.getTextColor(StyleLibrary.XYCURVE)); + label.setStatement(SVGConstants.CSS_FONT_FAMILY_PROPERTY, style.getFontFamily(StyleLibrary.XYCURVE)); + label.setStatement(SVGConstants.CSS_FONT_SIZE_PROPERTY, style.getTextSize(StyleLibrary.XYCURVE)); + label.setStatement(SVGConstants.CSS_TEXT_ANCHOR_PROPERTY, SVGConstants.CSS_MIDDLE_VALUE); + svgp.addCSSClassOrLogError(label); + svgp.updateStyleElement(); } @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - final IterableIterator<IterableResult<?>> iterableResults = ResultUtil.filteredResults(result, IterableResult.class); - final IterableIterator<IterableResult<DoubleDoublePair>> curves = new CurveFilter(iterableResults); - for (IterableResult<DoubleDoublePair> curve : curves) { + final ArrayList<XYCurve> curves = ResultUtil.filterResults(result, XYCurve.class); + for(XYCurve curve : curves) { final VisualizationTask task = new VisualizationTask(NAME, curve, null, this); task.width = 1.0; task.height = 1.0; |