diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/visualization/visualizers')
64 files changed, 603 insertions, 401 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisFactory.java index 565cf784..320ecd4c 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java index b023827d..cad9283e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/StaticVisualizationInstance.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/StaticVisualizationInstance.java index 3cd24289..8c7ad9a7 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/StaticVisualizationInstance.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/StaticVisualizationInstance.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisFactory.java index eb675951..c65a1c63 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisFactory.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/Visualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/Visualization.java index d2d1e5fe..5c1be0ab 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/Visualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/Visualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 389aec52..947f5841 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisualizerUtil.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/VisualizerUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,18 +23,9 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -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; -import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation; -import de.lmu.ifi.dbs.elki.database.relation.Relation; -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.AbstractFilteredIterator; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; @@ -48,43 +39,12 @@ import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; public final class VisualizerUtil { /** * Fake constructor: do not instantiate. - * */ private VisualizerUtil() { // Do not instantiate. } /** - * Find the visualizer context in a result tree. - * - * @param baseResult base result to start searching at. - * @return Visualizer context - */ - public static VisualizerContext getContext(HierarchicalResult baseResult) { - List<VisualizerContext> contexts = ResultUtil.filterResults(baseResult, VisualizerContext.class); - if (!contexts.isEmpty()) { - return contexts.get(0); - } else { - return null; - } - } - - /** - * Utility function to change Visualizer visibility. - * - * @param task Visualization task - * @param visibility Visibility value - */ - public static void setVisible(VisualizationTask task, boolean visibility) { - VisualizerContext context = task.getContext(); - if (context != null) { - setVisible(context, task, visibility); - } else { - LoggingUtil.warning("setVisible called without context in task.", new Throwable()); - } - } - - /** * Utility function to change Visualizer visibility. * * @param context Visualization context @@ -104,59 +64,5 @@ public final class VisualizerUtil { } task.visible = visibility; context.getHierarchy().resultChanged(task); - } - - /** - * Filter for number vector field representations. - * - * @param result Result to filter - * @return Iterator over suitable representations - */ - // TODO: move to DatabaseUtil? - public static Iterator<Relation<? extends NumberVector<?>>> iterateVectorFieldRepresentations(final Result result) { - List<Relation<?>> parent = ResultUtil.filterResults(result, Relation.class); - return new VectorspaceIterator(parent.iterator()); - } - - /** - * Iterate over vectorspace. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - private static class VectorspaceIterator extends AbstractFilteredIterator<Relation<?>, Relation<? extends NumberVector<?>>> { - /** - * Parent iterator. - */ - private Iterator<Relation<?>> parent; - - /** - * Constructor. - * - * @param parent Parent iterator - */ - public VectorspaceIterator(Iterator<Relation<?>> parent) { - super(); - this.parent = parent; - } - - @Override - protected Iterator<Relation<?>> getParentIterator() { - return parent; - } - - @SuppressWarnings("unchecked") - @Override - protected Relation<? extends NumberVector<?>> testFilter(Relation<?> nextobj) { - final SimpleTypeInformation<?> type = nextobj.getDataTypeInformation(); - if (!NumberVector.class.isAssignableFrom(type.getRestrictionClass())) { - return null; - } - if (!(type instanceof VectorFieldTypeInformation)) { - return null; - } - return (Relation<? extends NumberVector<?>>) nextobj; - } }; } diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/AbstractHistogramVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/AbstractHistogramVisualization.java index 95df9533..8d3616ac 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/AbstractHistogramVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/AbstractHistogramVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 7a52c8b3..fd7edbd4 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/package-info.java index 4489904f..0379a762 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/histogram/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java index 329fc64a..d734fc9e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -78,7 +78,7 @@ public abstract class AbstractOPTICSVisualization<D extends Distance<D>> extends plotheight = StyleLibrary.SCALE / optics.getOPTICSPlot(context).getRatio(); final double margin = context.getStyleResult().getStyleLibrary().getSize(StyleLibrary.MARGIN); layer = SVGUtil.svgElement(svgp.getDocument(), SVGConstants.SVG_G_TAG); - final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), plotwidth, plotheight, margin * .5); + final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), plotwidth, plotheight, margin * .5, margin * .5, margin * 1.5, margin * .5); SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform); } 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 e771e380..dd4462c9 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,7 +25,6 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.apache.batik.util.SVGConstants; @@ -40,6 +39,7 @@ 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.datastructures.hierarchy.Hierarchy; 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; @@ -80,9 +80,9 @@ public class OPTICSClusterVisualization extends AbstractVisFactory { @Override public void processNewResult(HierarchicalResult baseResult, Result result) { Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class); - for(OPTICSProjector<?> p : ops) { + for (OPTICSProjector<?> p : ops) { final Clustering<OPTICSModel> ocl = findOPTICSClustering(baseResult); - if(ocl != null) { + if (ocl != null) { final VisualizationTask task = new VisualizationTask(NAME, ocl, null, this); task.level = VisualizationTask.LEVEL_DATA; baseResult.getHierarchy().add(p, task); @@ -112,17 +112,16 @@ public class OPTICSClusterVisualization extends AbstractVisFactory { @SuppressWarnings("unchecked") protected static Clustering<OPTICSModel> findOPTICSClustering(Result result) { Collection<Clustering<?>> cs = ResultUtil.filterResults(result, Clustering.class); - for(Clustering<?> clus : cs) { - if(clus.getToplevelClusters().size() == 0) { + for (Clustering<?> clus : cs) { + if (clus.getToplevelClusters().size() == 0) { continue; } try { Cluster<?> firstcluster = clus.getToplevelClusters().iterator().next(); - if(firstcluster.getModel() instanceof OPTICSModel) { + if (firstcluster.getModel() instanceof OPTICSModel) { return (Clustering<OPTICSModel>) clus; } - } - catch(Exception e) { + } catch (Exception e) { // Empty clustering? Shouldn't happen. LOG.warning("Clustering with no cluster detected.", e); } @@ -168,13 +167,13 @@ public class OPTICSClusterVisualization extends AbstractVisFactory { addCSSClasses(); ColorLibrary colors = context.getStyleResult().getStyleLibrary().getColorSet(StyleLibrary.PLOT); - HashMap<Cluster<?>, String> colormap = new HashMap<Cluster<?>, String>(); + HashMap<Cluster<?>, String> colormap = new HashMap<>(); int cnum = 0; - for(Cluster<?> c : clus.getAllClusters()) { + for (Cluster<?> c : clus.getAllClusters()) { colormap.put(c, colors.getColor(cnum)); cnum++; } - drawClusters(clus.getToplevelClusters(), 1, colormap); + drawClusters(clus, clus.iterToplevelClusters(), 1, colormap); } /** @@ -184,10 +183,11 @@ public class OPTICSClusterVisualization extends AbstractVisFactory { * @param depth Recursion depth * @param colormap Color mapping */ - private void drawClusters(List<Cluster<OPTICSModel>> clusters, int depth, Map<Cluster<?>, String> colormap) { + private void drawClusters(Clustering<OPTICSModel> clustering, Hierarchy.Iter<Cluster<OPTICSModel>> clusters, int depth, Map<Cluster<?>, String> colormap) { final double scale = StyleLibrary.SCALE; - for(Cluster<OPTICSModel> cluster : clusters) { + for (; clusters.valid(); clusters.advance()) { + Cluster<OPTICSModel> cluster = clusters.get(); try { OPTICSModel model = cluster.getModel(); final double x1 = plotwidth * ((model.getStartIndex() + .25) / this.optics.getResult().getClusterOrder().size()); @@ -196,18 +196,17 @@ public class OPTICSClusterVisualization extends AbstractVisFactory { Element e = svgp.svgLine(x1, y, x2, y); SVGUtil.addCSSClass(e, CSS_BRACKET); String color = colormap.get(cluster); - if(color != null) { + if (color != null) { SVGUtil.setAtt(e, SVGConstants.SVG_STYLE_ATTRIBUTE, SVGConstants.CSS_STROKE_PROPERTY + ":" + color); } layer.appendChild(e); - } - catch(ClassCastException e) { + } catch (ClassCastException e) { LOG.warning("Expected OPTICSModel, got: " + cluster.getModel().getClass().getSimpleName()); } // Descend - final List<Cluster<OPTICSModel>> children = cluster.getChildren(); - if(children != null) { - drawClusters(children, depth + 1, colormap); + final Hierarchy.Iter<Cluster<OPTICSModel>> children = clustering.getClusterHierarchy().iterChildren(cluster); + if (children != null) { + drawClusters(clustering, children, depth + 1, colormap); } } } @@ -217,7 +216,7 @@ public class OPTICSClusterVisualization extends AbstractVisFactory { */ private void addCSSClasses() { // Class for the markers - if(!svgp.getCSSClassManager().contains(CSS_BRACKET)) { + if (!svgp.getCSSClassManager().contains(CSS_BRACKET)) { final CSSClass cls = new CSSClass(this, CSS_BRACKET); final StyleLibrary style = context.getStyleResult().getStyleLibrary(); cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, style.getColor(StyleLibrary.PLOT)); @@ -226,4 +225,4 @@ public class OPTICSClusterVisualization extends AbstractVisFactory { } } } -}
\ No newline at end of file +} 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 739e0ccd..e53c4c9d 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 @@ -66,6 +66,9 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { */
private static final String NAME = "OPTICS Cut";
+ /**
+ * Constructor.
+ */
public OPTICSPlotCutVisualization() {
super();
}
@@ -73,7 +76,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class);
- for(OPTICSProjector<?> p : ops) {
+ for (OPTICSProjector<?> p : ops) {
final VisualizationTask task = new VisualizationTask(NAME, p, null, this);
task.level = VisualizationTask.LEVEL_INTERACTIVE;
baseResult.getHierarchy().add(p, task);
@@ -151,7 +154,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { @Override
protected void incrementalRedraw() {
- if(layer == null) {
+ if (layer == null) {
makeLayerElement();
addCSSClasses();
}
@@ -161,36 +164,33 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { // compute absolute y-value of bar
final double yAct = plotheight - getYFromEpsilon(epsilon);
- if(elemText == null) {
+ if (elemText == null) {
elemText = svgp.svgText(StyleLibrary.SCALE * 1.05, yAct, label);
SVGUtil.setAtt(elemText, SVGConstants.SVG_CLASS_ATTRIBUTE, CSS_EPSILON);
layer.appendChild(elemText);
- }
- else {
+ } else {
elemText.setTextContent(label);
SVGUtil.setAtt(elemText, SVGConstants.SVG_Y_ATTRIBUTE, yAct);
}
// line and handle
- if(elementLine == null) {
+ if (elementLine == null) {
elementLine = svgp.svgLine(0, yAct, StyleLibrary.SCALE * 1.04, yAct);
SVGUtil.addCSSClass(elementLine, CSS_LINE);
layer.appendChild(elementLine);
- }
- else {
+ } else {
SVGUtil.setAtt(elementLine, SVG12Constants.SVG_Y1_ATTRIBUTE, yAct);
SVGUtil.setAtt(elementLine, SVG12Constants.SVG_Y2_ATTRIBUTE, yAct);
}
- if(elementPoint == null) {
+ if (elementPoint == null) {
elementPoint = svgp.svgCircle(StyleLibrary.SCALE * 1.04, yAct, StyleLibrary.SCALE * 0.004);
SVGUtil.addCSSClass(elementPoint, CSS_LINE);
layer.appendChild(elementPoint);
- }
- else {
+ } else {
SVGUtil.setAtt(elementPoint, SVG12Constants.SVG_CY_ATTRIBUTE, yAct);
}
- if(eventarea == null) {
+ if (eventarea == null) {
eventarea = new DragableArea(svgp, StyleLibrary.SCALE, 0, StyleLibrary.SCALE * 0.1, plotheight, this);
layer.appendChild(eventarea.getElement());
}
@@ -209,10 +209,10 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { * @return epsilon
*/
protected double getEpsilonFromY(double y) {
- if(y < 0) {
+ if (y < 0) {
y = 0;
}
- if(y > plotheight) {
+ if (y > plotheight) {
y = plotheight;
}
return optics.getOPTICSPlot(context).getScale().getUnscaled(y / plotheight);
@@ -226,10 +226,10 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { */
protected double getYFromEpsilon(double epsilon) {
double y = optics.getOPTICSPlot(context).getScale().getScaled(epsilon) * plotheight;
- if(y < 0) {
+ if (y < 0) {
y = 0;
}
- if(y > plotheight) {
+ if (y > plotheight) {
y = plotheight;
}
return y;
@@ -245,7 +245,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { @Override
public boolean duringDrag(SVGPoint start, SVGPoint end, Event evt, boolean inside) {
- if(inside) {
+ if (inside) {
epsilon = getEpsilonFromY(plotheight - end.getY());
}
// opvis.unsetEpsilonExcept(this);
@@ -255,7 +255,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { @Override
public boolean endDrag(SVGPoint start, SVGPoint end, Event evt, boolean inside) {
- if(inside) {
+ if (inside) {
epsilon = getEpsilonFromY(plotheight - end.getY());
// opvis.unsetEpsilonExcept(this);
@@ -264,8 +264,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { Clustering<Model> cl = OPTICSCut.makeOPTICSCut(order, optics.getOPTICSPlot(context).getDistanceAdapter(), epsilon);
order.addChildResult(cl);
}
- context.getHierarchy().resultChanged(this.task);
- // synchronizedRedraw();
+ synchronizedRedraw();
return true;
}
@@ -282,7 +281,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { private void addCSSClasses() {
// Class for the epsilon-value
final StyleLibrary style = context.getStyleResult().getStyleLibrary();
- if(!svgp.getCSSClassManager().contains(CSS_EPSILON)) {
+ if (!svgp.getCSSClassManager().contains(CSS_EPSILON)) {
final CSSClass label = new CSSClass(svgp, CSS_EPSILON);
label.setStatement(SVGConstants.CSS_FILL_PROPERTY, style.getTextColor(StyleLibrary.AXIS_LABEL));
label.setStatement(SVGConstants.CSS_FONT_FAMILY_PROPERTY, style.getFontFamily(StyleLibrary.AXIS_LABEL));
@@ -290,7 +289,7 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { svgp.addCSSClassOrLogError(label);
}
// Class for the epsilon cut line
- if(!svgp.getCSSClassManager().contains(CSS_LINE)) {
+ if (!svgp.getCSSClassManager().contains(CSS_LINE)) {
final CSSClass lcls = new CSSClass(svgp, CSS_LINE);
lcls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, style.getColor(StyleLibrary.PLOT));
lcls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, 0.5 * style.getLineWidth(StyleLibrary.PLOT));
@@ -298,4 +297,4 @@ public class OPTICSPlotCutVisualization extends AbstractVisFactory { }
}
}
-}
\ No newline at end of file +}
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 cde2d89d..6a834cb8 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 e6e00960..d587b554 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.optics; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -41,6 +41,7 @@ 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.datastructures.hierarchy.Hierarchy; 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; @@ -76,9 +77,9 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory { @Override public void processNewResult(HierarchicalResult baseResult, Result result) { Collection<OPTICSProjector<?>> ops = ResultUtil.filterResults(result, OPTICSProjector.class); - for(OPTICSProjector<?> p : ops) { + for (OPTICSProjector<?> p : ops) { final SteepAreaResult steep = findSteepAreaResult(p.getResult()); - if(steep != null) { + if (steep != null) { final VisualizationTask task = new VisualizationTask(NAME, p, null, this); task.level = VisualizationTask.LEVEL_DATA + 1; task.initDefaultVisibility(false); @@ -106,9 +107,9 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory { * @return OPTICS clustering */ protected static OPTICSXi.SteepAreaResult findSteepAreaResult(ClusterOrderResult<?> co) { - for(Result r : co.getHierarchy().getChildren(co)) { - if(OPTICSXi.SteepAreaResult.class.isInstance(r)) { - return (OPTICSXi.SteepAreaResult) r; + for (Hierarchy.Iter<Result> r = co.getHierarchy().iterChildren(co); r.valid(); r.advance()) { + if (OPTICSXi.SteepAreaResult.class.isInstance(r.get())) { + return (OPTICSXi.SteepAreaResult) r.get(); } } return null; @@ -160,7 +161,7 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory { final OPTICSDistanceAdapter<D> adapter = opticsplot.getDistanceAdapter(); final LinearScale scale = opticsplot.getScale(); - for(OPTICSXi.SteepArea area : areas) { + for (OPTICSXi.SteepArea area : areas) { final int st = area.getStartIndex(); final int en = area.getEndIndex(); // Note: make sure we are using doubles! @@ -171,10 +172,9 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory { final double y1 = (!Double.isInfinite(d1) && !Double.isNaN(d1)) ? (1. - scale.getScaled(d1)) : 0.; final double y2 = (!Double.isInfinite(d2) && !Double.isNaN(d2)) ? (1. - scale.getScaled(d2)) : 0.; Element e = svgp.svgLine(plotwidth * x1, plotheight * y1, plotwidth * x2, plotheight * y2); - if(area instanceof OPTICSXi.SteepDownArea) { + if (area instanceof OPTICSXi.SteepDownArea) { SVGUtil.addCSSClass(e, CSS_STEEP_DOWN); - } - else { + } else { SVGUtil.addCSSClass(e, CSS_STEEP_UP); } layer.appendChild(e); @@ -187,10 +187,10 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory { private void addCSSClasses() { // Class for the markers final StyleLibrary style = context.getStyleResult().getStyleLibrary(); - if(!svgp.getCSSClassManager().contains(CSS_STEEP_DOWN)) { + if (!svgp.getCSSClassManager().contains(CSS_STEEP_DOWN)) { final CSSClass cls = new CSSClass(this, CSS_STEEP_DOWN); Color color = SVGUtil.stringToColor(style.getColor(StyleLibrary.PLOT)); - if(color == null) { + if (color == null) { color = Color.BLACK; } color = new Color((int) (color.getRed() * 0.8), (int) (color.getGreen() * 0.8 + 0.2 * 256.), (int) (color.getBlue() * 0.8)); @@ -198,10 +198,10 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory { cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, style.getLineWidth(StyleLibrary.PLOT)); svgp.addCSSClassOrLogError(cls); } - if(!svgp.getCSSClassManager().contains(CSS_STEEP_UP)) { + if (!svgp.getCSSClassManager().contains(CSS_STEEP_UP)) { final CSSClass cls = new CSSClass(this, CSS_STEEP_UP); Color color = SVGUtil.stringToColor(style.getColor(StyleLibrary.PLOT)); - if(color == null) { + if (color == null) { color = Color.BLACK; } color = new Color((int) (color.getRed() * 0.8 + 0.2 * 256.), (int) (color.getGreen() * 0.8), (int) (color.getBlue() * 0.8)); @@ -213,11 +213,11 @@ public class OPTICSSteepAreaVisualization extends AbstractVisFactory { @Override public void resultChanged(Result current) { - if(current instanceof SelectionResult) { + if (current instanceof SelectionResult) { synchronizedRedraw(); return; } super.resultChanged(current); } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/package-info.java index 642f817c..6cae6baa 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/package-info.java index d5dad85b..486ecffc 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/package-info.java @@ -9,7 +9,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 400b8ebb..9718925f 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.pairsegments; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -227,7 +227,7 @@ public class CircleSegmentsVisualizer extends AbstractVisFactory { /** * Map to connect segments to their visual elements */ - public Map<Segment, List<Element>> segmentToElements = new HashMap<Segment, List<Element>>(); + public Map<Segment, List<Element>> segmentToElements = new HashMap<>(); /** * Show unclustered Pairs in CircleSegments @@ -412,7 +412,7 @@ public class CircleSegmentsVisualizer extends AbstractVisFactory { // ITERATE OVER ALL SEGMENT-CLUSTERS - ArrayList<Element> elems = new ArrayList<Element>(clusterings); + ArrayList<Element> elems = new ArrayList<>(clusterings); segmentToElements.put(segment, elems); // draw segment for every clustering 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 0ea700c8..4dc35180 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.pairsegments; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -56,12 +56,12 @@ public class SegmentsStylingPolicy implements ClassStylingPolicy, Result { /** * Selected segments */ - protected ArrayList<Segment> selectedSegments = new ArrayList<Segment>(); + protected ArrayList<Segment> selectedSegments = new ArrayList<>(); /** * Segments indirectly selected */ - protected TreeMap<Segment, Segment> indirectSelections = new TreeMap<Segment, Segment>(); + protected TreeMap<Segment, Segment> indirectSelections = new TreeMap<>(); /** * Not selected IDs that will be drawn in default colors. @@ -165,6 +165,20 @@ public class SegmentsStylingPolicy implements ClassStylingPolicy, Result { return (ids != null) ? ids.iter() : DBIDUtil.EMPTYDBIDS.iter(); } + @Override + public int classSize(int cnum) { + // unselected + if(cnum == -2) { + return unselectedObjects.size(); + } + else if(cnum == -1) { + return 0; + } + // colors + DBIDs ids = selectedSegments.get(cnum).getDBIDs(); + return (ids != null) ? ids.size() : 0; + } + /** * Adds or removes the given segment to the selection. Depending on the * clustering and cluster selected and the addToSelection option given, the @@ -239,7 +253,7 @@ public class SegmentsStylingPolicy implements ClassStylingPolicy, Result { */ protected void deselectSegment(Segment segment) { if(segment.isUnpaired()) { - ArrayList<Segment> remove = new ArrayList<Segment>(); + ArrayList<Segment> remove = new ArrayList<>(); // remove all object segments associated with unpaired segment from // selection list for(Entry<Segment, Segment> entry : indirectSelections.entrySet()) { diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/package-info.java index c0c71dd3..967ed347 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/pairsegments/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisVisibilityVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisVisibilityVisualization.java index ea68d660..3c78120a 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisVisibilityVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/AxisVisibilityVisualization.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.parallel; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 47a6d9a8..10aa6309 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 @@ -35,6 +35,7 @@ import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener;
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.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
import de.lmu.ifi.dbs.elki.result.Result;
@@ -65,7 +66,7 @@ public class ClusterOutlineVisualization extends AbstractVisFactory { /**
* A short name characterizing this Visualizer.
*/
- public static final String NAME = "Cluster Outline";
+ public static final String NAME = "Parallel Cluster Outline";
/**
* Currently unused option to enable/disable rounding
@@ -169,6 +170,10 @@ public class ClusterOutlineVisualization extends AbstractVisFactory { Iterator<Cluster<Model>> ci = clustering.getAllClusters().iterator();
for(int cnum = 0; cnum < clustering.getAllClusters().size(); cnum++) {
Cluster<?> clus = ci.next();
+ final DBIDs ids = clus.getIDs();
+ if (ids.size() < 1) {
+ continue;
+ }
for(int i = 0; i < dim; i++) {
mms[i].reset();
if(i < dim - 1) {
@@ -178,7 +183,7 @@ public class ClusterOutlineVisualization extends AbstractVisFactory { // Process points
// TODO: do this just once, cache the result somewhere appropriately?
- for(DBIDIter id = clus.getIDs().iter(); id.valid(); id.advance()) {
+ for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
double[] yPos = proj.fastProjectDataToRenderSpace(relation.get(id));
for(int i = 0; i < dim; i++) {
mms[i].put(yPos[i]);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/package-info.java index 7977da0c..0ae97b92 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/cluster/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 7c2c8b9f..04676905 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 @@ -96,8 +96,8 @@ public class RTreeParallelVisualization extends AbstractVisFactory { @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- ArrayList<AbstractRStarTree<RStarTreeNode, SpatialEntry>> trees = ResultUtil.filterResults(result, AbstractRStarTree.class);
- for(AbstractRStarTree<RStarTreeNode, SpatialEntry> tree : trees) {
+ ArrayList<AbstractRStarTree<RStarTreeNode, SpatialEntry, ?>> trees = ResultUtil.filterResults(result, AbstractRStarTree.class);
+ for(AbstractRStarTree<RStarTreeNode, SpatialEntry, ?> tree : trees) {
if(tree instanceof Result) {
Collection<ParallelPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ParallelPlotProjector.class);
for(ParallelPlotProjector<?> p : ps) {
@@ -125,7 +125,7 @@ public class RTreeParallelVisualization extends AbstractVisFactory { /**
* The tree we visualize
*/
- protected AbstractRStarTree<N, E> tree;
+ protected AbstractRStarTree<N, E, ?> tree;
/**
* Constructor.
@@ -201,7 +201,7 @@ public class RTreeParallelVisualization extends AbstractVisFactory { * @param entry Current entry
* @param depth Current depth
*/
- private void visualizeRTreeEntry(SVGPlot svgp, Element layer, ProjectionParallel proj, AbstractRStarTree<? extends N, E> rtree, E entry, int depth, int step) {
+ private void visualizeRTreeEntry(SVGPlot svgp, Element layer, ProjectionParallel proj, AbstractRStarTree<? extends N, E, ?> rtree, E entry, int depth, int step) {
final int dim = proj.getVisibleDimensions();
double[] min = proj.fastProjectDataToRenderSpace(SpatialUtil.getMin(entry));
double[] max = proj.fastProjectDataToRenderSpace(SpatialUtil.getMax(entry));
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/package-info.java index 1cefd6f0..93c1e75b 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/index/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/package-info.java index 0ab7d565..d46f1a94 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/package-info.java index e4589b05..52acab59 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/parallel/selection/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractScatterplotVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractScatterplotVisualization.java index 8cedcf0b..1f2d89d7 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractScatterplotVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractScatterplotVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractTooltipVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractTooltipVisualization.java index 107af095..332f31e1 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractTooltipVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/AbstractTooltipVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 f08c4b2d..dd3f2218 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 f2140502..964500ec 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -69,7 +69,7 @@ public class MarkerVisualization extends AbstractVisFactory { */ public MarkerVisualization() { super(); - thumbmask |= ThumbnailVisualization.ON_DATA | ThumbnailVisualization.ON_STYLE; + this.thumbmask |= ThumbnailVisualization.ON_DATA | ThumbnailVisualization.ON_STYLE; } @Override 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 0fc99bbc..8037eae6 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -39,6 +39,7 @@ 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.datastructures.iterator.ArrayListIter; import de.lmu.ifi.dbs.elki.utilities.exceptions.ObjectNotFoundException; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; @@ -155,11 +156,11 @@ public class PolygonVisualization extends AbstractVisFactory { Vector first = ppoly.get(0); double[] f = proj.fastProjectDataToRenderSpace(first.getArrayRef()); path.moveTo(f[0], f[1]); - for(Vector v : ppoly) { - if(v == first) { + for(ArrayListIter<Vector> it = ppoly.iter(); it.valid(); it.advance()) { + if(it.getOffset() == 0) { continue; } - double[] p = proj.fastProjectDataToRenderSpace(v.getArrayRef()); + double[] p = proj.fastProjectDataToRenderSpace(it.get().getArrayRef()); path.drawTo(p[0], p[1]); } // close path. 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 94c1c8d2..b3a66582 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 352e79de..55727c46 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 @@ -159,7 +159,7 @@ public class ToolBox2DVisualization extends AbstractVisFactory { double scale = StyleLibrary.SCALE;
deleteChildren(container);
- ArrayList<VisualizationTask> vis = new ArrayList<VisualizationTask>();
+ ArrayList<VisualizationTask> vis = new ArrayList<>();
Collection<VisualizationTask> visualizers = ResultUtil.filterResults(task.getResult(), VisualizationTask.class);
for(VisualizationTask task : visualizers) {
if(task.tool && !vis.contains(task)) {
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 f3f35002..bcf0dc71 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -37,6 +37,7 @@ 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.datastructures.hierarchy.Hierarchy; 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; @@ -113,8 +114,8 @@ public class TooltipScoreVisualization extends AbstractVisFactory { } // Skip if we already considered it above boolean add = true; - for(Result p : baseResult.getHierarchy().getChildren(r)) { - if(p instanceof VisualizationTask && ((VisualizationTask) p).getFactory() instanceof TooltipScoreVisualization) { + for(Hierarchy.Iter<Result> p = baseResult.getHierarchy().iterChildren(r); p.valid(); p.advance()) { + if(p.get() instanceof VisualizationTask && ((VisualizationTask) p.get()).getFactory() instanceof TooltipScoreVisualization) { add = false; break; } 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 979ce905..42da21d9 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 ebaf9eb9..123ed7d9 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 @@ -25,14 +25,16 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.cluster; import java.util.ArrayList;
import java.util.Collection;
-import java.util.Iterator;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.batik.util.SVGConstants;
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.model.CoreObjectsModel;
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;
@@ -44,23 +46,31 @@ 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.datastructures.hierarchy.Hierarchy;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy.Iter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.ArrayListIter;
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;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleObjPair;
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.projections.CanvasSize;
import de.lmu.ifi.dbs.elki.visualization.projections.Projection;
import de.lmu.ifi.dbs.elki.visualization.projector.ScatterPlotProjector;
+import de.lmu.ifi.dbs.elki.visualization.style.ClusterStylingPolicy;
import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary;
+import de.lmu.ifi.dbs.elki.visualization.style.StyleResult;
+import de.lmu.ifi.dbs.elki.visualization.style.StylingPolicy;
import de.lmu.ifi.dbs.elki.visualization.svg.SVGPath;
import de.lmu.ifi.dbs.elki.visualization.svg.SVGPlot;
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;
/**
* Visualizer for generating an SVG-Element containing the convex hull / alpha
@@ -91,6 +101,7 @@ public class ClusterHullVisualization extends AbstractVisFactory { public ClusterHullVisualization(Parameterizer settings) {
super();
this.settings = settings;
+ this.thumbmask |= ThumbnailVisualization.ON_DATA | ThumbnailVisualization.ON_STYLE;
}
@Override
@@ -100,11 +111,12 @@ public class ClusterHullVisualization extends AbstractVisFactory { @Override
public void processNewResult(HierarchicalResult baseResult, Result result) {
- // Find clusterings we can visualize:
- Collection<Clustering<?>> clusterings = ResultUtil.filterResults(result, Clustering.class);
- for(Clustering<?> c : clusterings) {
+ // We attach ourselves to the style library, not the clustering, so there is
+ // only one hull.
+ Collection<StyleResult> styleres = ResultUtil.filterResults(result, StyleResult.class);
+ for (StyleResult c : styleres) {
Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
- for(ScatterPlotProjector<?> p : ps) {
+ for (ScatterPlotProjector<?> p : ps) {
final VisualizationTask task = new VisualizationTask(NAME, c, p.getRelation(), this);
task.level = VisualizationTask.LEVEL_DATA - 1;
task.initDefaultVisibility(false);
@@ -132,9 +144,9 @@ public class ClusterHullVisualization extends AbstractVisFactory { public static final String CLUSTERHULL = "cluster-hull";
/**
- * The result we work on
+ * The result we visualize
*/
- Clustering<Model> clustering;
+ private StyleResult style;
/**
* Constructor
@@ -143,60 +155,97 @@ public class ClusterHullVisualization extends AbstractVisFactory { */
public Instance(VisualizationTask task) {
super(task);
- this.clustering = task.getResult();
+ this.style = task.getResult();
incrementalRedraw();
}
@Override
protected void redraw() {
+ final StylingPolicy spol = style.getStylingPolicy();
+ if (!(spol instanceof ClusterStylingPolicy)) {
+ return;
+ }
+ final ClusterStylingPolicy cpol = (ClusterStylingPolicy) spol;
+ @SuppressWarnings("unchecked")
+ Clustering<Model> clustering = (Clustering<Model>) cpol.getClustering();
+
// Viewport size, for "relative size" computations
final CanvasSize viewp = proj.estimateViewport();
double projarea = viewp.getDiffX() * viewp.getDiffY();
- double opacity = 0.25;
-
- Iterator<Cluster<Model>> ci = clustering.getAllClusters().iterator();
-
- for(int cnum = 0; cnum < clustering.getAllClusters().size(); cnum++) {
- Cluster<?> clus = ci.next();
- final DBIDs ids = clus.getIDs();
+ List<Cluster<Model>> clusters = clustering.getAllClusters();
+ List<Cluster<Model>> topc = clustering.getToplevelClusters();
+ Hierarchy<Cluster<Model>> hier = clustering.getClusterHierarchy();
+ boolean flat = (clusters.size() == topc.size());
+ // Heuristic value for transparency:
+ double baseopacity = flat ? 0.5 : 0.5;
+
+ // Convex hull mode:
+ if (settings.alpha >= Double.POSITIVE_INFINITY) {
+ // Build the convex hulls (reusing the hulls of nested clusters!)
+ Map<Object, DoubleObjPair<Polygon>> hullmap = new HashMap<>(clusters.size());
+ for (Cluster<Model> clu : topc) {
+ buildHullsRecursively(clu, hier, hullmap);
+ }
- if(settings.alpha >= Double.POSITIVE_INFINITY) {
- GrahamScanConvexHull2D hull = new GrahamScanConvexHull2D();
+ // This way, we draw each cluster only once.
+ // Unfortunately, not depth ordered (TODO!)
+ for (Cluster<Model> clu : clusters) {
+ DoubleObjPair<Polygon> pair = hullmap.get(clu), mpair = hullmap.get(clu.getModel());
+ ;
+ // Plot the convex hull:
+ if (pair != null && pair.second != null && pair.second.size() > 1) {
+ SVGPath path = new SVGPath(pair.second);
+ // Approximate area (using bounding box)
+ double hullarea = SpatialUtil.volume(pair.second);
+ final double relativeArea = 1 - (hullarea / projarea);
+ final double relativeSize = pair.first / rel.size();
+ final double corefact = (mpair == null) ? 1.0 : .5;
+ final double opacity = corefact * baseopacity * Math.sqrt(relativeSize * relativeArea);
+ addCSSClasses(svgp, cpol.getStyleForCluster(clu), opacity);
- for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- double[] projP = proj.fastProjectDataToRenderSpace(rel.get(iter));
- hull.add(new Vector(projP));
+ Element hulls = path.makeElement(svgp);
+ SVGUtil.addCSSClass(hulls, CLUSTERHULL + cpol.getStyleForCluster(clu));
+ layer.appendChild(hulls);
}
- Polygon chres = hull.getHull();
-
- // Plot the convex hull:
- if(chres != null && chres.size() > 1) {
- SVGPath path = new SVGPath(chres);
+ // For core density models, over-plot the core:
+ if (mpair != null && mpair.second != null && mpair.second.size() > 1) {
+ SVGPath path = new SVGPath(mpair.second);
// Approximate area (using bounding box)
- double hullarea = SpatialUtil.volume(chres);
- final double relativeArea = (projarea - hullarea) / projarea;
- final double relativeSize = (double) ids.size() / rel.size();
- opacity = Math.sqrt(relativeSize * relativeArea);
+ double hullarea = SpatialUtil.volume(mpair.second);
+ final double relativeArea = 1 - (hullarea / projarea);
+ final double relativeSize = mpair.first / rel.size();
+ final double opacity = .5 * baseopacity * Math.sqrt(relativeSize * relativeArea);
+ addCSSClasses(svgp, cpol.getStyleForCluster(clu), opacity);
Element hulls = path.makeElement(svgp);
- addCSSClasses(svgp, cnum, opacity);
- SVGUtil.addCSSClass(hulls, CLUSTERHULL + cnum);
+ SVGUtil.addCSSClass(hulls, CLUSTERHULL + cpol.getStyleForCluster(clu));
layer.appendChild(hulls);
}
}
- else {
- ArrayList<Vector> ps = new ArrayList<Vector>(ids.size());
- for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- double[] projP = proj.fastProjectDataToRenderSpace(rel.get(iter));
- ps.add(new Vector(projP));
+ } else {
+ // Alpha shape mode.
+ // For alpha shapes we can't use the shortcut of convex hulls,
+ // but have to revisit all child clusters.
+ for (Cluster<Model> clu : clusters) {
+ ArrayList<Vector> ps = new ArrayList<>();
+ double weight = addRecursively(ps, hier, clu);
+ List<Polygon> polys;
+ if (ps.size() < 1) {
+ continue;
}
- List<Polygon> polys = (new AlphaShape(ps, settings.alpha * Projection.SCALE)).compute();
- for(Polygon p : polys) {
+ if (ps.size() > 2) {
+ polys = (new AlphaShape(ps, settings.alpha * Projection.SCALE)).compute();
+ } else {
+ // Trivial polygon. Might still degenerate to a single point though.
+ polys = new ArrayList<>(1);
+ polys.add(new Polygon(ps));
+ }
+ for (Polygon p : polys) {
SVGPath path = new SVGPath(p);
Element hulls = path.makeElement(svgp);
- addCSSClasses(svgp, cnum, 0.5);
- SVGUtil.addCSSClass(hulls, CLUSTERHULL + cnum);
+ addCSSClasses(svgp, cpol.getStyleForCluster(clu), baseopacity * weight / rel.size());
+ SVGUtil.addCSSClass(hulls, CLUSTERHULL + cpol.getStyleForCluster(clu));
layer.appendChild(hulls);
}
}
@@ -204,6 +253,89 @@ public class ClusterHullVisualization extends AbstractVisFactory { }
/**
+ * Recursively step through the clusters to build the hulls.
+ *
+ * @param clu Current cluster
+ * @param hier Clustering hierarchy
+ * @param hulls Hull map
+ */
+ private DoubleObjPair<Polygon> buildHullsRecursively(Cluster<Model> clu, Hierarchy<Cluster<Model>> hier, Map<Object, DoubleObjPair<Polygon>> hulls) {
+ final Model model = clu.getModel();
+ final DBIDs ids = clu.getIDs();
+ boolean coremodel = false;
+ DBIDs cids = null;
+ if (model instanceof CoreObjectsModel) {
+ cids = ((CoreObjectsModel) model).getCoreObjects();
+ coremodel = cids.size() > 0;
+ }
+
+ GrahamScanConvexHull2D hull = new GrahamScanConvexHull2D();
+ GrahamScanConvexHull2D hull2 = coremodel ? new GrahamScanConvexHull2D() : null;
+ for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ Vector projP = new Vector(proj.fastProjectDataToRenderSpace(rel.get(iter)));
+ hull.add(projP);
+ if (coremodel && cids.contains(iter)) {
+ hull2.add(projP);
+ }
+ }
+ double weight = ids.size(), cweight = coremodel ? cids.size() : 0.0;
+ if (hier != null && hulls != null) {
+ final int numc = hier.numChildren(clu);
+ if (numc > 0) {
+ for (Iter<Cluster<Model>> iter = hier.iterChildren(clu); iter.valid(); iter.advance()) {
+ final Cluster<Model> iclu = iter.get();
+ DoubleObjPair<Polygon> poly = hulls.get(iclu);
+ if (poly == null) {
+ poly = buildHullsRecursively(iclu, hier, hulls);
+ }
+ // Add inner convex hull to outer convex hull.
+ for (ArrayListIter<Vector> vi = poly.second.iter(); vi.valid(); vi.advance()) {
+ hull.add(vi.get());
+ }
+ // For a core model, include the inner core, too.
+ if (coremodel) {
+ DoubleObjPair<Polygon> ipoly = hulls.get(iclu.getModel());
+ if (ipoly != null) {
+ for (ArrayListIter<Vector> vi = ipoly.second.iter(); vi.valid(); vi.advance()) {
+ hull2.add(vi.get());
+ }
+ cweight += ipoly.first / numc;
+ }
+ }
+ weight += poly.first / numc;
+ }
+ }
+ }
+ DoubleObjPair<Polygon> pair = new DoubleObjPair<>(weight, hull.getHull());
+ hulls.put(clu, pair);
+ if (coremodel) {
+ hulls.put(model, new DoubleObjPair<>(cweight, hull2.getHull()));
+ }
+ return pair;
+ }
+
+ /**
+ * Recursively add a cluster and its children.
+ *
+ * @param hull Hull to add to
+ * @param hier Cluster hierarchy
+ * @param clus Current cluster
+ * @return Weight for visualization
+ */
+ private double addRecursively(ArrayList<Vector> hull, Hierarchy<Cluster<Model>> hier, Cluster<Model> clus) {
+ final DBIDs ids = clus.getIDs();
+ double weight = ids.size();
+ for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ double[] projP = proj.fastProjectDataToRenderSpace(rel.get(iter));
+ hull.add(new Vector(projP));
+ }
+ for (Iter<Cluster<Model>> iter = hier.iterChildren(clus); iter.valid(); iter.advance()) {
+ weight += .5 * addRecursively(hull, hier, iter.get());
+ }
+ return weight;
+ }
+
+ /**
* Adds the required CSS-Classes
*
* @param svgp SVG-Plot
@@ -215,13 +347,7 @@ public class ClusterHullVisualization extends AbstractVisFactory { CSSClass cls = new CSSClass(this, CLUSTERHULL + clusterID);
cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, style.getLineWidth(StyleLibrary.PLOT));
- final String color;
- if(clustering.getAllClusters().size() == 1) {
- color = "black";
- }
- else {
- color = colors.getColor(clusterID);
- }
+ final String color = colors.getColor(clusterID);
cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, color);
cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, color);
cls.setStatement(SVGConstants.CSS_FILL_OPACITY_PROPERTY, opac);
@@ -256,7 +382,7 @@ public class ClusterHullVisualization extends AbstractVisFactory { protected void makeOptions(Parameterization config) {
super.makeOptions(config);
DoubleParameter alphaP = new DoubleParameter(ALPHA_ID, Double.POSITIVE_INFINITY);
- if(config.grab(alphaP)) {
+ if (config.grab(alphaP)) {
alpha = alphaP.doubleValue();
}
}
@@ -266,4 +392,4 @@ public class ClusterHullVisualization extends AbstractVisFactory { return new ClusterHullVisualization(this);
}
}
-}
\ No newline at end of file +}
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 bd173e80..bdc77006 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.cluster; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 2806812a..9a5df4e4 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.cluster; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -93,7 +93,7 @@ public class EMClusterVisualization extends AbstractVisFactory { @Override public Instance<DoubleVector> makeVisualization(VisualizationTask task) { - return new Instance<DoubleVector>(task); + return new Instance<>(task); } @Override @@ -346,7 +346,7 @@ public class EMClusterVisualization extends AbstractVisFactory { for(int i = 1; i <= times; i++) { SVGPath path = new SVGPath(); - ArrayList<Vector> delta = new ArrayList<Vector>(chres.size()); + ArrayList<Vector> delta = new ArrayList<>(chres.size()); for(int p = 0; p < chres.size(); p++) { Vector prev = chres.get((p - 1 + chres.size()) % chres.size()); Vector curr = chres.get(p); 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 7ae28f42..7c4b57f2 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 @@ -203,7 +203,7 @@ public class VoronoiVisualization extends AbstractVisFactory { // Collect cluster means
if (clusters.size() == 2) {
- ArrayList<double[]> means = new ArrayList<double[]>(clusters.size());
+ ArrayList<double[]> means = new ArrayList<>(clusters.size());
{
for (Cluster<Model> clus : clusters) {
Model model = clus.getModel();
@@ -232,8 +232,8 @@ public class VoronoiVisualization extends AbstractVisFactory { layer.appendChild(path);
}
} else {
- ArrayList<Vector> vmeans = new ArrayList<Vector>(clusters.size());
- ArrayList<double[]> means = new ArrayList<double[]>(clusters.size());
+ ArrayList<Vector> vmeans = new ArrayList<>(clusters.size());
+ ArrayList<double[]> means = new ArrayList<>(clusters.size());
{
for (Cluster<Model> clus : clusters) {
Model model = clus.getModel();
@@ -313,7 +313,7 @@ public class VoronoiVisualization extends AbstractVisFactory { @Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- EnumParameter<Mode> modeP = new EnumParameter<Mode>(MODE_ID, Mode.class, Mode.VORONOI);
+ EnumParameter<Mode> modeP = new EnumParameter<>(MODE_ID, Mode.class, Mode.VORONOI);
if (config.grab(modeP)) {
mode = modeP.getValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/package-info.java index 0f232498..076b6563 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/cluster/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 96658910..a2b34e0e 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.density; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/package-info.java index b9771aed..3b6385f3 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/density/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 9d466a8f..438eddb8 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.index; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -96,8 +96,8 @@ public class TreeMBRVisualization extends AbstractVisFactory { @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - Collection<AbstractRStarTree<RStarTreeNode, SpatialEntry>> trees = ResultUtil.filterResults(result, AbstractRStarTree.class); - for(AbstractRStarTree<RStarTreeNode, SpatialEntry> tree : trees) { + Collection<AbstractRStarTree<RStarTreeNode, SpatialEntry, ?>> trees = ResultUtil.filterResults(result, AbstractRStarTree.class); + for(AbstractRStarTree<RStarTreeNode, SpatialEntry, ?> tree : trees) { if(tree instanceof Result) { Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for(ScatterPlotProjector<?> p : ps) { @@ -126,7 +126,7 @@ public class TreeMBRVisualization extends AbstractVisFactory { /** * The tree we visualize */ - protected AbstractRStarTree<N, E> tree; + protected AbstractRStarTree<N, E, ?> tree; /** * Constructor. @@ -182,7 +182,7 @@ public class TreeMBRVisualization extends AbstractVisFactory { * @param entry Current entry * @param depth Current depth */ - private void visualizeRTreeEntry(SVGPlot svgp, Element layer, Projection2D proj, AbstractRStarTree<? extends N, E> rtree, E entry, int depth) { + private void visualizeRTreeEntry(SVGPlot svgp, Element layer, Projection2D proj, AbstractRStarTree<? extends N, E, ?> rtree, E entry, int depth) { SpatialComparable mbr = entry; if(settings.fill) { 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 e89be028..4ced6de1 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.index; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -32,9 +32,9 @@ 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.distance.distancefunction.DistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancefunction.EuclideanDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancefunction.LPNormDistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancefunction.ManhattanDistanceFunction; +import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.EuclideanDistanceFunction; +import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction; +import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.ManhattanDistanceFunction; import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree; @@ -107,8 +107,8 @@ public class TreeSphereVisualization extends AbstractVisFactory { public void processNewResult(HierarchicalResult baseResult, Result result) { Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class); for (ScatterPlotProjector<?> p : ps) { - Collection<AbstractMTree<?, DoubleDistance, ?, ?>> trees = ResultUtil.filterResults(result, AbstractMTree.class); - for (AbstractMTree<?, DoubleDistance, ?, ?> tree : trees) { + 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); task.level = VisualizationTask.LEVEL_BACKGROUND + 1; @@ -121,7 +121,7 @@ public class TreeSphereVisualization extends AbstractVisFactory { @Override public Visualization makeVisualization(VisualizationTask task) { - return new Instance<DoubleDistance, MTreeNode<Object, DoubleDistance>, MTreeEntry<DoubleDistance>>(task); + return new Instance<DoubleDistance, MTreeNode<Object, DoubleDistance>, MTreeEntry>(task); } /** @@ -130,10 +130,10 @@ public class TreeSphereVisualization extends AbstractVisFactory { * @param tree Tree to visualize * @return p value */ - public static double getLPNormP(AbstractMTree<?, ?, ?, ?> tree) { + public static double getLPNormP(AbstractMTree<?, ?, ?, ?, ?> tree) { // Note: we deliberately lose generics here, so the compilers complain // less on the next typecheck and cast! - DistanceFunction<?, ?> distanceFunction = tree.getDistanceQuery().getDistanceFunction(); + DistanceFunction<?, ?> distanceFunction = tree.getDistanceFunction(); if (LPNormDistanceFunction.class.isInstance(distanceFunction)) { return ((LPNormDistanceFunction) distanceFunction).getP(); } @@ -146,7 +146,7 @@ public class TreeSphereVisualization extends AbstractVisFactory { * @param tree Tree to visualize * @return whether the tree is visualizable */ - public static boolean canVisualize(AbstractMTree<?, ?, ?, ?> tree) { + public static boolean canVisualize(AbstractMTree<?, ?, ?, ?, ?> tree) { return getLPNormP(tree) > 0; } @@ -162,7 +162,7 @@ public class TreeSphereVisualization extends AbstractVisFactory { * @param <E> Tree entry type */ // TODO: listen for tree changes! - public class Instance<D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<?, D, N, E>, E extends MTreeEntry<D>> extends AbstractScatterplotVisualization implements DataStoreListener { + public class Instance<D extends NumberDistance<D, ?>, N extends AbstractMTreeNode<?, D, N, E>, E extends MTreeEntry> extends AbstractScatterplotVisualization implements DataStoreListener { protected double p; /** @@ -173,7 +173,7 @@ public class TreeSphereVisualization extends AbstractVisFactory { /** * The tree we visualize */ - protected AbstractMTree<?, D, N, E> tree; + protected AbstractMTree<?, D, N, E, ?> tree; /** * Constructor @@ -197,9 +197,9 @@ public class TreeSphereVisualization extends AbstractVisFactory { p = getLPNormP(tree); if (tree != null) { - if (ManhattanDistanceFunction.class.isInstance(tree.getDistanceQuery())) { + if (ManhattanDistanceFunction.class.isInstance(tree.getDistanceFunction())) { dist = Modus.MANHATTAN; - } else if (EuclideanDistanceFunction.class.isInstance(tree.getDistanceQuery())) { + } else if (EuclideanDistanceFunction.class.isInstance(tree.getDistanceFunction())) { dist = Modus.EUCLIDEAN; } else { dist = Modus.LPCROSS; @@ -240,11 +240,11 @@ public class TreeSphereVisualization extends AbstractVisFactory { * @param entry Current entry * @param depth Current depth */ - private void visualizeMTreeEntry(SVGPlot svgp, Element layer, Projection2D proj, AbstractMTree<?, D, N, E> mtree, E entry, int depth) { + private void visualizeMTreeEntry(SVGPlot svgp, Element layer, Projection2D proj, AbstractMTree<?, D, N, E, ?> mtree, E entry, int depth) { DBID roid = entry.getRoutingObjectID(); if (roid != null) { NumberVector<?> ro = rel.get(roid); - D rad = entry.getCoveringRadius(); + double rad = entry.getCoveringRadius(); final Element r; if (dist == Modus.MANHATTAN) { diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/package-info.java index a4b3c0c9..b82e9359 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/index/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 ebe9612d..5051d019 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -36,6 +36,7 @@ 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.datastructures.hierarchy.Hierarchy; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; @@ -100,7 +101,7 @@ public class BubbleVisualization extends AbstractVisFactory { @Override public Visualization makeVisualization(VisualizationTask task) { - if(settings.scaling != null && settings.scaling instanceof OutlierScalingFunction) { + if (settings.scaling != null && settings.scaling instanceof OutlierScalingFunction) { final OutlierResult outlierResult = task.getResult(); ((OutlierScalingFunction) settings.scaling).prepare(outlierResult); } @@ -110,21 +111,21 @@ public class BubbleVisualization extends AbstractVisFactory { @Override public void processNewResult(HierarchicalResult baseResult, Result result) { Collection<OutlierResult> ors = ResultUtil.filterResults(result, OutlierResult.class); - for(OutlierResult o : ors) { + for (OutlierResult o : ors) { 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. - for(Result r : o.getHierarchy().getParents(o)) { - if(r instanceof OutlierResult) { + for (Hierarchy.Iter<Result> r = o.getHierarchy().iterParents(o); r.valid(); r.advance()) { + if (r.get() instanceof OutlierResult) { vis = false; break; } } - for(ScatterPlotProjector<?> p : ps) { + for (ScatterPlotProjector<?> p : ps) { final VisualizationTask task = new VisualizationTask(NAME, o, p.getRelation(), this); task.level = VisualizationTask.LEVEL_DATA; - if(!vis) { + if (!vis) { task.initDefaultVisibility(false); } baseResult.getHierarchy().add(o, task); @@ -172,15 +173,15 @@ public class BubbleVisualization extends AbstractVisFactory { StylingPolicy stylepolicy = style.getStylingPolicy(); // bubble size final double bubble_size = style.getStyleLibrary().getSize(StyleLibrary.BUBBLEPLOT); - if(stylepolicy instanceof ClassStylingPolicy) { + if (stylepolicy instanceof ClassStylingPolicy) { ClassStylingPolicy colors = (ClassStylingPolicy) stylepolicy; setupCSS(svgp, colors); // draw data - for(DBIDIter objId = sample.getSample().iter(); objId.valid(); objId.advance()) { + for (DBIDIter objId = sample.getSample().iter(); objId.valid(); objId.advance()) { final double radius = getScaledForId(objId); - if(radius > 0.01 && !Double.isInfinite(radius)) { + if (radius > 0.01 && !Double.isInfinite(radius)) { final NumberVector<?> vec = rel.get(objId); - if(vec != null) { + if (vec != null) { double[] v = proj.fastProjectDataToRenderSpace(vec); Element circle = svgp.svgCircle(v[0], v[1], radius * bubble_size); SVGUtil.addCSSClass(circle, BUBBLE + colors.getStyleForDBID(objId)); @@ -188,23 +189,21 @@ public class BubbleVisualization extends AbstractVisFactory { } } } - } - else { + } else { // draw data - for(DBIDIter objId = sample.getSample().iter(); objId.valid(); objId.advance()) { + for (DBIDIter objId = sample.getSample().iter(); objId.valid(); objId.advance()) { final double radius = getScaledForId(objId); - if(radius > 0.01 && !Double.isInfinite(radius)) { + if (radius > 0.01 && !Double.isInfinite(radius)) { final NumberVector<?> vec = rel.get(objId); - if(vec != null) { + if (vec != null) { double[] v = proj.fastProjectDataToRenderSpace(vec); Element circle = svgp.svgCircle(v[0], v[1], radius * bubble_size); int color = stylepolicy.getColorForDBID(objId); final StringBuilder cssstyle = new StringBuilder(); - if(settings.fill) { + if (settings.fill) { cssstyle.append(SVGConstants.CSS_FILL_PROPERTY).append(':').append(SVGUtil.colorToString(color)); cssstyle.append(SVGConstants.CSS_FILL_OPACITY_PROPERTY).append(":0.5"); - } - else { + } else { cssstyle.append(SVGConstants.CSS_STROKE_VALUE).append(':').append(SVGUtil.colorToString(color)); cssstyle.append(SVGConstants.CSS_FILL_PROPERTY).append(':').append(SVGConstants.CSS_NONE_VALUE); } @@ -219,7 +218,7 @@ public class BubbleVisualization extends AbstractVisFactory { @Override public void resultChanged(Result current) { super.resultChanged(current); - if(sample == current || context.getStyleResult() == current) { + if (sample == current || context.getStyleResult() == current) { synchronizedRedraw(); } } @@ -235,17 +234,16 @@ public class BubbleVisualization extends AbstractVisFactory { ColorLibrary colors = style.getColorSet(StyleLibrary.PLOT); // creating IDs manually because cluster often return a null-ID. - for(int clusterID = policy.getMinStyle(); clusterID < policy.getMaxStyle(); clusterID++) { + for (int clusterID = policy.getMinStyle(); clusterID < policy.getMaxStyle(); clusterID++) { CSSClass bubble = new CSSClass(svgp, BUBBLE + clusterID); bubble.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, style.getLineWidth(StyleLibrary.PLOT)); String color = colors.getColor(clusterID); - if(settings.fill) { + if (settings.fill) { bubble.setStatement(SVGConstants.CSS_FILL_PROPERTY, color); bubble.setStatement(SVGConstants.CSS_FILL_OPACITY_PROPERTY, 0.5); - } - else { + } else { // for diamond-shaped strokes, see bugs.sun.com, bug ID 6294396 bubble.setStatement(SVGConstants.CSS_STROKE_VALUE, color); bubble.setStatement(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_NONE_VALUE); @@ -264,13 +262,12 @@ public class BubbleVisualization extends AbstractVisFactory { */ protected double getScaledForId(DBIDRef id) { double d = result.getScores().get(id).doubleValue(); - if(Double.isNaN(d) || Double.isInfinite(d)) { + if (Double.isNaN(d) || Double.isInfinite(d)) { return 0.0; } - if(settings.scaling == null) { + if (settings.scaling == null) { return result.getOutlierMeta().normalizeScore(d); - } - else { + } else { return settings.scaling.getScaled(d); } } @@ -316,12 +313,12 @@ public class BubbleVisualization extends AbstractVisFactory { protected void makeOptions(Parameterization config) { super.makeOptions(config); Flag fillF = new Flag(FILL_ID); - if(config.grab(fillF)) { + if (config.grab(fillF)) { fill = fillF.isTrue(); } - ObjectParameter<ScalingFunction> scalingP = new ObjectParameter<ScalingFunction>(SCALING_ID, OutlierScalingFunction.class, true); - if(config.grab(scalingP)) { + ObjectParameter<ScalingFunction> scalingP = new ObjectParameter<>(SCALING_ID, OutlierScalingFunction.class, true); + if (config.grab(scalingP)) { scaling = scalingP.instantiateClass(config); } } @@ -331,4 +328,4 @@ public class BubbleVisualization extends AbstractVisFactory { return new BubbleVisualization(this); } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/COPVectorVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/COPVectorVisualization.java index e953f9ae..c3346c02 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/COPVectorVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/COPVectorVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/package-info.java index 7332fcb0..f8da2afd 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/outlier/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/package-info.java index 805379d7..66d9b609 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/package-info.java @@ -12,7 +12,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/DistanceFunctionVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/DistanceFunctionVisualization.java index 257a3c54..d9b860de 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/DistanceFunctionVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/DistanceFunctionVisualization.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.scatterplot.selection; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -32,17 +32,18 @@ import de.lmu.ifi.dbs.elki.data.VectorUtil; import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.DistanceDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
import de.lmu.ifi.dbs.elki.distance.distancefunction.ArcCosineDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.CosineDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.LPNormDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultIter;
-import de.lmu.ifi.dbs.elki.distance.distanceresultlist.KNNResult;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.LPNormDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.preprocessed.knn.AbstractMaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.linearalgebra.VMath;
import de.lmu.ifi.dbs.elki.result.DBIDSelection;
import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
@@ -180,7 +181,7 @@ public class DistanceFunctionVisualization extends AbstractVisFactory { double l1 = VMath.scalarProduct(pm, p1), l2 = VMath.scalarProduct(pm, p2);
// Rotate projection by + and - angle
// Using sin(-x) = -sin(x) and cos(-x)=cos(x)
- final double cangle = Math.cos(angle), sangle = Math.sin(angle);
+ final double cangle = Math.cos(angle), sangle = MathUtil.cosToSin(angle, cangle);
double r11 = +cangle * l1 - sangle * l2, r12 = +sangle * l1 + cangle * l2;
double r21 = +cangle * l1 + sangle * l2, r22 = -sangle * l1 + cangle * l2;
// Build rotated vectors - remove projected component, add rotated
@@ -276,8 +277,8 @@ public class DistanceFunctionVisualization extends AbstractVisFactory { DBIDs selection = selContext.getSelectedIds();
for(DBIDIter i = selection.iter(); i.valid(); i.advance()) {
- final KNNResult<D> knn = result.get(i);
- for(DistanceDBIDResultIter<D> iter = knn.iter(); iter.valid(); iter.advance()) {
+ final KNNList<D> knn = result.get(i);
+ for(DistanceDBIDListIter<D> iter = knn.iter(); iter.valid(); iter.advance()) {
try {
double[] v = proj.fastProjectDataToRenderSpace(rel.get(iter));
Element dot = svgp.svgCircle(v[0], v[1], size);
@@ -298,13 +299,13 @@ public class DistanceFunctionVisualization extends AbstractVisFactory { {
final Element dist;
if(p == 1.0) {
- dist = SVGHyperSphere.drawManhattan(svgp, proj, rel.get(i), last.getDistance());
+ dist = SVGHyperSphere.drawManhattan(svgp, proj, rel.get(i), last.getDistance().doubleValue());
}
else if(p == 2.0) {
- dist = SVGHyperSphere.drawEuclidean(svgp, proj, rel.get(i), last.getDistance());
+ dist = SVGHyperSphere.drawEuclidean(svgp, proj, rel.get(i), last.getDistance().doubleValue());
}
else if(!Double.isNaN(p)) {
- dist = SVGHyperSphere.drawLp(svgp, proj, rel.get(i), last.getDistance(), p);
+ dist = SVGHyperSphere.drawLp(svgp, proj, rel.get(i), last.getDistance().doubleValue(), p);
}
else if(angular) {
final NumberVector<?> refvec = rel.get(i);
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 c2282bf1..84659848 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 @@ -30,7 +30,6 @@ 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;
@@ -159,9 +158,9 @@ public class MoveObjectsToolVisualization extends AbstractVisFactory { */
// TODO: move to DatabaseUtil?
private void updateDB(DBIDs dbids, Vector movingVector) {
- NumberVector<?> nv = null;
throw new AbortException("FIXME: INCOMPLETE TRANSITION");
/*
+ * NumberVector<?> nv = null;
* database.accumulateDataStoreEvents();
* Representation<DatabaseObjectMetadata> mrep =
* database.getMetadataQuery(); for(DBID dbid : dbids) { NV obj =
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/package-info.java index 3710de5c..86214f53 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 8d045138..bf210fce 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.thumbs; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -37,7 +37,7 @@ public class ThumbnailThread extends Thread { /** * Queue of thumbnails to generate. */ - private Queue<Task> queue = new ConcurrentLinkedQueue<Task>(); + private Queue<Task> queue = new ConcurrentLinkedQueue<>(); /** * Flag to signal shutdown. diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java index dd502146..651f41c0 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.thumbs; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/package-info.java index 64676bb3..c32b9f19 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisualization.java index 4b57a503..8d87945e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,6 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; */ import java.util.ArrayList; -import java.util.List; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; @@ -42,6 +41,7 @@ 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.datastructures.hierarchy.Hierarchy; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; import de.lmu.ifi.dbs.elki.visualization.svg.SVGPlot; @@ -59,7 +59,9 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; * * @apiviz.stereotype factory * @apiviz.uses StaticVisualizationInstance oneway - - «create» - * @apiviz.has de.lmu.ifi.dbs.elki.evaluation.clustering.EvaluateClustering.ScoreResult oneway - - visualizes + * @apiviz.has + * de.lmu.ifi.dbs.elki.evaluation.clustering.EvaluateClustering.ScoreResult + * oneway - - visualizes */ public class ClusterEvaluationVisualization extends AbstractVisFactory { /** @@ -87,10 +89,10 @@ public class ClusterEvaluationVisualization extends AbstractVisFactory { @Override public void processNewResult(HierarchicalResult baseResult, Result newResult) { final ArrayList<EvaluateClustering.ScoreResult> srs = ResultUtil.filterResults(newResult, EvaluateClustering.ScoreResult.class); - for(EvaluateClustering.ScoreResult sr : srs) { + for (EvaluateClustering.ScoreResult sr : srs) { final VisualizationTask task = new VisualizationTask(NAME, sr, null, this); - task.width = .5; - task.height = 2.0; + task.width = .4; + task.height = 1.5; task.level = VisualizationTask.LEVEL_STATIC; baseResult.getHierarchy().add(sr, task); } @@ -118,17 +120,16 @@ public class ClusterEvaluationVisualization extends AbstractVisFactory { @Override public Visualization makeVisualization(VisualizationTask task) { // TODO: make a utility class to wrap SVGPlot + parent layer + ypos. - + double ypos = -.5; // Skip space before first header SVGPlot svgp = task.getPlot(); Element parent = svgp.svgElement(SVGConstants.SVG_G_TAG); EvaluateClustering.ScoreResult sr = task.getResult(); ClusterContingencyTable cont = sr.getContingencyTable(); - List<Result> parents = task.getContext().getHierarchy().getParents(sr); - - for(Result r : parents) { - if(r instanceof Clustering) { + for (Hierarchy.Iter<Result> parents = task.getContext().getHierarchy().iterParents(sr); parents.valid(); parents.advance()) { + Result r = parents.get(); + if (r instanceof Clustering) { ypos = addHeader(svgp, parent, ypos, r.getLongName()); } } @@ -194,4 +195,4 @@ public class ClusterEvaluationVisualization extends AbstractVisFactory { // Don't use thumbnails return false; } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisualization.java index d97b5117..77f096fb 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team 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 f21e4df6..f18ef371 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 @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,6 +23,9 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import gnu.trove.map.TObjectIntMap; +import gnu.trove.map.hash.TObjectIntHashMap; + import java.util.Collection; import java.util.List; @@ -38,7 +41,11 @@ import de.lmu.ifi.dbs.elki.data.model.Model; 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.datastructures.hierarchy.Hierarchy; +import de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy.Hierarchy.Iter; +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; import de.lmu.ifi.dbs.elki.visualization.style.ClusterStylingPolicy; import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; import de.lmu.ifi.dbs.elki.visualization.style.StylingPolicy; @@ -52,7 +59,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; /** * Visualizer, displaying the key for a clustering. - * + * * @author Erich Schubert * * @apiviz.stereotype factory @@ -68,24 +75,65 @@ public class KeyVisualization extends AbstractVisFactory { public void processNewResult(HierarchicalResult baseResult, Result newResult) { // Find clusterings we can visualize: Collection<Clustering<?>> clusterings = ResultUtil.filterResults(newResult, Clustering.class); - for(Clustering<?> c : clusterings) { + for (Clustering<?> c : clusterings) { final int numc = c.getAllClusters().size(); - if(numc > 0) { - // FIXME: compute from labels? - final double maxwidth = 10.; + final int topc = c.getToplevelClusters().size(); + if (numc > 0) { final VisualizationTask task = new VisualizationTask(NAME, c, null, this); - final int cols = getPreferredColumns(1.0, 1.0, numc, maxwidth); - final int rows = (int) Math.ceil(numc / (double) cols); - final double div = Math.max(2. + rows, cols * maxwidth); - task.width = cols * maxwidth / div; - task.height = (2. + rows) / div; + if (numc == topc) { + // FIXME: compute from labels? + final double maxwidth = 10.; + // Flat clustering. + final int cols = getPreferredColumns(1.0, 1.0, numc, maxwidth); + final int rows = (int) Math.ceil(numc / (double) cols); + final double ratio = cols * maxwidth / (2. + rows); + task.width = (ratio >= 1.) ? 1 : 1. / ratio; + task.height = (ratio >= 1.) ? 1. / ratio : 1; + if (numc > 100) { + task.width *= 2; + task.height *= 2; + } + } else { + // Hierarchical clustering. + final int[] shape = findDepth(c); + final double maxwidth = 8.; + final double ratio = shape[0] * maxwidth / (2. + shape[1]); + task.width = (ratio >= 1.) ? 1 : 1. / ratio; + task.height = (ratio >= 1.) ? 1. / ratio : 1; + if (shape[0] * maxwidth > 20 || shape[1] > 18) { + task.width *= 2; + task.height *= 2; + } + } task.level = VisualizationTask.LEVEL_STATIC; - task.nodetail = true; + if (numc < 20) { + task.nodetail = true; + } baseResult.getHierarchy().add(c, task); } } } + private static <M extends Model> int[] findDepth(Clustering<M> c) { + final Hierarchy<Cluster<M>> hier = c.getClusterHierarchy(); + int[] size = { 0, 0 }; + for (Iter<Cluster<M>> iter = c.iterToplevelClusters(); iter.valid(); iter.advance()) { + findDepth(hier, iter.get(), size); + } + return size; + } + + private static <M extends Model> void findDepth(Hierarchy<Cluster<M>> hier, Cluster<M> cluster, int[] size) { + if (hier.numChildren(cluster) > 0) { + for (Iter<Cluster<M>> iter = hier.iterChildren(cluster); iter.valid(); iter.advance()) { + findDepth(hier, iter.get(), size); + } + size[0] += 1; // Depth + } else { + size[1] += 1; // Leaves + } + } + /** * Compute the preferred number of columns. * @@ -123,6 +171,21 @@ public class KeyVisualization extends AbstractVisFactory { */ public class Instance extends AbstractVisualization { /** + * CSS class for key captions. + */ + private static final String KEY_CAPTION = "key-caption"; + + /** + * CSS class for key entries. + */ + private static final String KEY_ENTRY = "key-entry"; + + /** + * CSS class for hierarchy plot lines + */ + private static final String KEY_HIERLINE = "key-hierarchy"; + + /** * Clustering to display */ private Clustering<Model> clustering; @@ -147,59 +210,84 @@ public class KeyVisualization extends AbstractVisFactory { @Override public void resultChanged(Result current) { super.resultChanged(current); - if(current == context.getStyleResult()) { + if (current == context.getStyleResult()) { incrementalRedraw(); } } @Override protected void redraw() { - SVGPlot svgp = task.getPlot(); StyleLibrary style = context.getStyleResult().getStyleLibrary(); MarkerLibrary ml = style.markers(); - // Maximum width (compared to height) of labels - guess. - // FIXME: compute from labels? - final double maxwidth = 10.; - final List<Cluster<Model>> allcs = clustering.getAllClusters(); - final int numc = allcs.size(); - final int cols = getPreferredColumns(task.getWidth(), task.getHeight(), numc, maxwidth); - final int rows = 2 + (int) Math.ceil(numc / (double) cols); - // We use a coordinate system based on rows, so columns are at c*maxwidth + final List<Cluster<Model>> topcs = clustering.getToplevelClusters(); + setupCSS(svgp); 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; fill: " + style.getTextColor(StyleLibrary.DEFAULT)); + SVGUtil.setCSSClass(label, KEY_CAPTION); layer.appendChild(label); } - int i = 0; - for(Cluster<Model> c : allcs) { - final int col = i / rows; - final int row = i % rows; - ml.useMarker(svgp, layer, 0.3 + maxwidth * col, row + 1.5, i, 0.3); - Element label = svgp.svgText(0.7 + maxwidth * col, row + 1.7, c.getNameAutomatic()); - label.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: 0.6; fill: " + style.getTextColor(StyleLibrary.DEFAULT)); - layer.appendChild(label); - i++; + final int extrarows = 2; + double kwi, khe; + if (allcs.size() == topcs.size()) { + // Maximum width (compared to height) of labels - guess. + // FIXME: compute from labels? + final double maxwidth = 10.; + + // Flat clustering. Use multiple columns. + final int numc = allcs.size(); + final int cols = getPreferredColumns(task.getWidth(), task.getHeight(), numc, maxwidth); + final int rows = (int) Math.ceil(numc / (double) cols); + // We use a coordinate system based on rows, so columns are at + // c*maxwidth + + int i = 0; + for (Cluster<Model> c : allcs) { + final int col = i / rows; + final int row = i % rows; + ml.useMarker(svgp, layer, 0.3 + maxwidth * col, row + 1.5, i, 0.3); + Element label = svgp.svgText(0.7 + maxwidth * col, row + 1.7, c.getNameAutomatic()); + SVGUtil.setCSSClass(label, KEY_ENTRY); + layer.appendChild(label); + i++; + } + kwi = cols * maxwidth; + khe = rows; + } else { + // For consistent keying: + TObjectIntMap<Cluster<Model>> cnum = new TObjectIntHashMap<>(allcs.size()); + int i = 0; + for (Cluster<Model> c : allcs) { + cnum.put(c, i); + i++; + } + // Hierarchical clustering. Draw recursively. + DoubleDoublePair size = new DoubleDoublePair(0., 1.), pos = new DoubleDoublePair(0., 1.); + Hierarchy<Cluster<Model>> hier = clustering.getClusterHierarchy(); + for (Cluster<Model> cluster : topcs) { + drawHierarchy(svgp, ml, size, pos, 0, cluster, cnum, hier); + } + kwi = size.first; + khe = size.second; } // Add a button to set style policy { StylingPolicy sp = context.getStyleResult().getStylingPolicy(); - if(sp instanceof ClusterStylingPolicy && ((ClusterStylingPolicy) sp).getClustering() == clustering) { + if (sp instanceof ClusterStylingPolicy && ((ClusterStylingPolicy) sp).getClustering() == clustering) { // Don't show the button when active. May confuse people more than the // disappearing button? // SVGButton button = new SVGButton(.1, rows + 1.1, 3.8, .7, .2); // button.setTitle("Active style", "darkgray"); // layer.appendChild(button.render(svgp)); - } - else { - SVGButton button = new SVGButton(.1, rows + 1.1, 3.8, .7, .2); + } else { + SVGButton button = new SVGButton(.1, khe + 1.1, 3.8, .7, .2); button.setTitle("Set style", "black"); Element elem = button.render(svgp); // Attach listener @@ -214,14 +302,44 @@ public class KeyVisualization extends AbstractVisFactory { } } - // int rows = i + 2; - // int cols = Math.max(6, (int) (rows * task.getHeight() / - // task.getWidth())); final double margin = style.getSize(StyleLibrary.MARGIN); - final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), cols * maxwidth, rows, margin / StyleLibrary.SCALE); + final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), kwi, khe + extrarows, margin / StyleLibrary.SCALE); SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform); } + private double drawHierarchy(SVGPlot svgp, MarkerLibrary ml, DoubleDoublePair size, DoubleDoublePair pos, int depth, Cluster<Model> cluster, TObjectIntMap<Cluster<Model>> cnum, Hierarchy<Cluster<Model>> hier) { + final double maxwidth = 8.; + DoubleDoublePair subpos = new DoubleDoublePair(pos.first + maxwidth, pos.second); + int numc = hier.numChildren(cluster); + double posy; + if (numc > 0) { + double[] mids = new double[numc]; + Iter<Cluster<Model>> iter = hier.iterChildren(cluster); + for (int i = 0; iter.valid(); iter.advance(), i++) { + mids[i] = drawHierarchy(svgp, ml, size, subpos, depth, iter.get(), cnum, hier); + } + // Center: + posy = (pos.second + subpos.second) * .5; + for (int i = 0; i < numc; i++) { + Element line = svgp.svgLine(pos.first + maxwidth - 1., posy + .5, pos.first + maxwidth, mids[i] + .5); + SVGUtil.setCSSClass(line, KEY_HIERLINE); + layer.appendChild(line); + } + // Use vertical extends of children: + pos.second = subpos.second; + } else { + posy = pos.second + .5; + pos.second += 1.; + } + ml.useMarker(svgp, layer, 0.3 + pos.first, posy + 0.5, cnum.get(cluster), 0.3); + Element label = svgp.svgText(0.7 + pos.first, posy + 0.7, cluster.getNameAutomatic()); + SVGUtil.setCSSClass(label, KEY_ENTRY); + layer.appendChild(label); + size.first = Math.max(size.first, pos.first + maxwidth); + size.second = Math.max(size.second, pos.second); + return posy; + } + /** * Trigger a style change. */ @@ -229,5 +347,37 @@ public class KeyVisualization extends AbstractVisFactory { context.getStyleResult().setStylingPolicy(new ClusterStylingPolicy(clustering, context.getStyleResult().getStyleLibrary())); context.getHierarchy().resultChanged(context.getStyleResult()); } + + /** + * Registers the Tooltip-CSS-Class at a SVGPlot. + * + * @param svgp the SVGPlot to register the Tooltip-CSS-Class. + */ + protected void setupCSS(SVGPlot svgp) { + final StyleLibrary style = context.getStyleResult().getStyleLibrary(); + final double fontsize = style.getTextSize(StyleLibrary.KEY); + final String fontfamily = style.getFontFamily(StyleLibrary.KEY); + final String color = style.getColor(StyleLibrary.KEY); + + CSSClass keycaption = new CSSClass(svgp, KEY_CAPTION); + keycaption.setStatement(SVGConstants.CSS_FONT_SIZE_PROPERTY, fontsize); + keycaption.setStatement(SVGConstants.CSS_FONT_FAMILY_PROPERTY, fontfamily); + keycaption.setStatement(SVGConstants.CSS_FILL_PROPERTY, color); + keycaption.setStatement(SVGConstants.CSS_FONT_WEIGHT_PROPERTY, SVGConstants.CSS_BOLD_VALUE); + svgp.addCSSClassOrLogError(keycaption); + + CSSClass keyentry = new CSSClass(svgp, KEY_ENTRY); + keyentry.setStatement(SVGConstants.CSS_FONT_SIZE_PROPERTY, fontsize); + keyentry.setStatement(SVGConstants.CSS_FONT_FAMILY_PROPERTY, fontfamily); + keyentry.setStatement(SVGConstants.CSS_FILL_PROPERTY, color); + svgp.addCSSClassOrLogError(keyentry); + + CSSClass hierline = new CSSClass(svgp, KEY_HIERLINE); + hierline.setStatement(SVGConstants.CSS_STROKE_PROPERTY, color); + hierline.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, style.getLineWidth("key.hierarchy") / StyleLibrary.SCALE); + svgp.addCSSClassOrLogError(hierline); + + svgp.updateStyleElement(); + } } -}
\ No newline at end of file +} diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisualization.java index d29a6467..0fe96e50 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java index 19cc6254..60080373 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisualization.java index 736f28e7..d39d5bfd 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -143,6 +143,7 @@ public class SettingsVisualization extends AbstractVisFactory { task.width = 1.0; task.height = 1.0; task.level = VisualizationTask.LEVEL_STATIC; + task.initDefaultVisibility(false); baseResult.getHierarchy().add(sr, task); } } diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java index f1404050..b4570a32 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,6 +29,7 @@ import java.util.Collection; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; +import de.lmu.ifi.dbs.elki.database.Database; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.evaluation.similaritymatrix.ComputeSimilarityMatrixImage; @@ -145,7 +146,8 @@ public class SimilarityMatrixVisualizer extends AbstractVisFactory { final double hlsize = StyleLibrary.SCALE * zoom * iratio / size; final double vlsize = StyleLibrary.SCALE * zoom / size; int i = 0; - final Relation<String> lrep = DatabaseUtil.guessObjectLabelRepresentation(result.getRelation().getDatabase()); + Database database = ResultUtil.findDatabase(context.getResult()); + final Relation<String> lrep = DatabaseUtil.guessObjectLabelRepresentation(database); for(DBIDIter id = result.getIDs().iter(); id.valid(); id.advance()) { String label = lrep.get(id); if(label != null) { diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisualization.java index 76ce7c09..691ab925 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisualization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -133,7 +133,7 @@ public class XYCurveVisualization extends AbstractVisFactory { // Add AUC value when found if(curve instanceof ROCResult) { double rocauc = ((ROCResult) curve).getAUC(); - String lt = OutlierROCCurve.ROCAUC_LABEL + ": " + FormatUtil.NF8.format(rocauc); + String lt = OutlierROCCurve.ROCAUC_LABEL + ": " + FormatUtil.NF.format(rocauc); if(rocauc <= 0.5) { Element auclbl = svgp.svgText(sizex * 0.5, sizey * 0.10, lt); SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL); @@ -147,7 +147,7 @@ public class XYCurveVisualization extends AbstractVisFactory { } if(curve instanceof PRCurve) { double prauc = ((PRCurve) curve).getAUC(); - String lt = PRCurve.PRAUC_LABEL + ": " + FormatUtil.NF8.format(prauc); + String lt = PRCurve.PRAUC_LABEL + ": " + FormatUtil.NF.format(prauc); if(prauc <= 0.5) { Element auclbl = svgp.svgText(sizex * 0.5, sizey * 0.10, lt); SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL); diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/package-info.java index 30042923..ff45c35e 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2012 +Copyright (C) 2013 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team |