diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj')
13 files changed, 239 insertions, 1623 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java index a5146dd5..469d6db5 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java @@ -1,26 +1,27 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; + /* -This file is part of ELKI: -Environment for Developing KDD-Applications Supported by Index-Structures + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ import java.util.ArrayList; @@ -33,14 +34,13 @@ 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.visualization.projections.Projection; +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; 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.StaticVisualization; import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; /** * Pseudo-Visualizer, that lists the cluster evaluation results found. @@ -68,7 +68,9 @@ public class ClusterEvaluationVisFactory extends AbstractVisFactory { public void processNewResult(HierarchicalResult baseResult, Result newResult) { final ArrayList<EvaluatePairCountingFMeasure.ScoreResult> srs = ResultUtil.filterResults(newResult, EvaluatePairCountingFMeasure.ScoreResult.class); for(EvaluatePairCountingFMeasure.ScoreResult sr : srs) { - final VisualizationTask task = new VisualizationTask(NAME, sr, null, this, null); + final VisualizationTask task = new VisualizationTask(NAME, sr, null, this); + task.width = 1.0; + task.height = 0.5; task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_STATIC); baseResult.getHierarchy().add(sr, task); } @@ -119,9 +121,10 @@ public class ClusterEvaluationVisFactory extends AbstractVisFactory { return new StaticVisualization(task, layer); } - + @Override - public Class<? extends Projection> getProjectionType() { - return null; + public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) { + // Don't use thumbnails + return false; } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java index e71ffe73..a45f2007 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java @@ -1,26 +1,27 @@ 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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ import java.util.Collection; import java.util.Iterator; @@ -40,9 +41,10 @@ import de.lmu.ifi.dbs.elki.utilities.FormatUtil; import de.lmu.ifi.dbs.elki.utilities.iterator.AbstractFilteredIterator; import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair; +import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; +import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; import de.lmu.ifi.dbs.elki.visualization.css.CSSClassManager.CSSNamingConflict; -import de.lmu.ifi.dbs.elki.visualization.projections.Projection; import de.lmu.ifi.dbs.elki.visualization.scales.LinearScale; import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; import de.lmu.ifi.dbs.elki.visualization.svg.SVGPath; @@ -52,8 +54,6 @@ 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.StaticVisualization; import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerContext; /** * Visualizer to render a simple 2D curve such as a ROC curve. @@ -226,7 +226,9 @@ public class CurveVisFactory extends AbstractVisFactory { final IterableIterator<IterableResult<?>> iterableResults = ResultUtil.filteredResults(result, IterableResult.class); final IterableIterator<IterableResult<DoubleDoublePair>> curves = new CurveFilter(iterableResults); for (IterableResult<DoubleDoublePair> curve : curves) { - final VisualizationTask task = new VisualizationTask(NAME, curve, null, this, null); + final VisualizationTask task = new VisualizationTask(NAME, curve, null, this); + task.width = 1.0; + task.height = 1.0; task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_STATIC); baseResult.getHierarchy().add(curve, task); } @@ -237,9 +239,4 @@ public class CurveVisFactory extends AbstractVisFactory { // TODO: depending on the curve complexity? return false; } - - @Override - public Class<? extends Projection> getProjectionType() { - return null; - } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisFactory.java index 3d328b58..c8dfe0c8 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisFactory.java @@ -1,26 +1,27 @@ 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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ import java.util.List; @@ -34,10 +35,11 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.HistogramResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; +import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; +import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; 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.css.CSSClassManager.CSSNamingConflict; -import de.lmu.ifi.dbs.elki.visualization.projections.Projection; import de.lmu.ifi.dbs.elki.visualization.scales.LinearScale; import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; import de.lmu.ifi.dbs.elki.visualization.svg.SVGPath; @@ -47,8 +49,6 @@ 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.StaticVisualization; import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerContext; /** * Visualizer to draw histograms. @@ -168,7 +168,9 @@ public class HistogramVisFactory extends AbstractVisFactory { public void processNewResult(HierarchicalResult baseResult, Result newResult) { List<HistogramResult<? extends NumberVector<?, ?>>> histograms = ResultUtil.filterResults(newResult, HistogramResult.class); for(HistogramResult<? extends NumberVector<?, ?>> histogram : histograms) { - final VisualizationTask task = new VisualizationTask(NAME, histogram, null, this, null); + final VisualizationTask task = new VisualizationTask(NAME, histogram, null, this); + task.width = 2.0; + task.height = 1.0; task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_STATIC); baseResult.getHierarchy().add(histogram, task); } @@ -179,9 +181,4 @@ public class HistogramVisFactory extends AbstractVisFactory { // TODO: depending on the histogram complexity? return false; } - - @Override - public Class<? extends Projection> getProjectionType() { - return null; - } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisFactory.java index 26462faf..69813d99 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisFactory.java @@ -1,26 +1,27 @@ 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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ import java.util.Collection; import java.util.List; @@ -34,7 +35,8 @@ 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.visualization.projections.Projection; +import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; +import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; import de.lmu.ifi.dbs.elki.visualization.style.marker.MarkerLibrary; import de.lmu.ifi.dbs.elki.visualization.svg.SVGPlot; @@ -42,8 +44,6 @@ 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.StaticVisualization; import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerContext; /** * Pseudo-Visualizer, that gives the key for a clustering. @@ -106,7 +106,9 @@ public class KeyVisFactory extends AbstractVisFactory { Collection<Clustering<?>> clusterings = ResultUtil.filterResults(newResult, Clustering.class); for(Clustering<?> c : clusterings) { if(c.getAllClusters().size() > 0) { - final VisualizationTask task = new VisualizationTask(NAME, c, null, this, null); + final VisualizationTask task = new VisualizationTask(NAME, c, null, this); + task.width = 1.0; + task.height = 1.0; task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_STATIC); baseResult.getHierarchy().add(c, task); } @@ -117,9 +119,4 @@ public class KeyVisFactory extends AbstractVisFactory { public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) { return false; } - - @Override - public Class<? extends Projection> getProjectionType() { - return null; - } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisFactory.java index a10b1b09..6145b7a8 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/LabelVisFactory.java @@ -1,46 +1,46 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; + /* -This file is part of ELKI: -Environment for Developing KDD-Applications Supported by Index-Structures + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; +import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; +import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; -import de.lmu.ifi.dbs.elki.visualization.projections.Projection; import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; 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.StaticVisualization; import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerContext; /** - * Trivial "visualizer" that displays a static label. - * The visualizer is meant to be used for dimension labels in the overview. + * Trivial "visualizer" that displays a static label. The visualizer is meant to + * be used for dimension labels in the overview. * * @author Erich Schubert * @@ -54,7 +54,12 @@ public class LabelVisFactory extends AbstractVisFactory { private String label = "undefined"; /** - * Formal constructor, to satisfy Parameterizable API + * Flag to indicate rotated labels (90 deg to the left) + */ + private boolean rotated = false; + + /** + * Constructor. Solely for API purposes (Parameterizable!) */ public LabelVisFactory() { super(); @@ -66,11 +71,21 @@ public class LabelVisFactory extends AbstractVisFactory { * @param label Label to use */ public LabelVisFactory(String label) { - this(); + this(label, false); + } + + /** + * Constructor. + * + * @param label Label to use + * @param rotated Rotated 90 deg to the left + */ + public LabelVisFactory(String label, boolean rotated) { + super(); this.label = label; + this.rotated = rotated; } - @SuppressWarnings("unused") @Override public void processNewResult(HierarchicalResult baseResult, Result newResult) { // No auto discovery supported. @@ -87,19 +102,23 @@ public class LabelVisFactory extends AbstractVisFactory { cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, style.getTextColor("overview.labels")); cls.setStatement(SVGConstants.CSS_FONT_FAMILY_PROPERTY, style.getFontFamily("overview.labels")); - Element layer = svgp.svgText(task.getWidth() / 2, task.getHeight() / 2 + .35 * fontsize, this.label); - SVGUtil.setAtt(layer, SVGConstants.SVG_STYLE_ATTRIBUTE, cls.inlineCSS()); - SVGUtil.setAtt(layer, SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE, SVGConstants.SVG_MIDDLE_VALUE); + Element layer; + if(!rotated) { + layer = svgp.svgText(task.getWidth() / 2, task.getHeight() / 2 + .35 * fontsize, this.label); + SVGUtil.setAtt(layer, SVGConstants.SVG_STYLE_ATTRIBUTE, cls.inlineCSS()); + SVGUtil.setAtt(layer, SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE, SVGConstants.SVG_MIDDLE_VALUE); + } + else { + layer = svgp.svgText(- task.getHeight() / 2, task.getWidth() / 2 + .35 * fontsize, this.label); + SVGUtil.setAtt(layer, SVGConstants.SVG_STYLE_ATTRIBUTE, cls.inlineCSS()); + SVGUtil.setAtt(layer, SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE, SVGConstants.SVG_MIDDLE_VALUE); + SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, "rotate(-90)"); + } return new StaticVisualization(task, layer); } @Override - public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) { + public boolean allowThumbnails(VisualizationTask task) { return false; } - - @Override - public Class<? extends Projection> getProjectionType() { - return null; - } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSClusterVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSClusterVisualization.java deleted file mode 100644 index 666d4518..00000000 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSClusterVisualization.java +++ /dev/null @@ -1,240 +0,0 @@ -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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -import java.util.Collection; -import java.util.List; - -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.OPTICSModel; -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.result.SelectionResult; -import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult; -import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; -import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot; -import de.lmu.ifi.dbs.elki.visualization.projections.Projection; -import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; -import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil; -import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisFactory; -import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; - -/** - * Visualize the clusters and cluster hierarchy found by OPTICS on the OPTICS - * Plot. - * - * @author Erich Schubert - * - * @apiviz.uses ClusterOrderResult - * @apiviz.uses OPTICSPlot - */ -public class OPTICSClusterVisualization extends AbstractVisualization { - /** - * The logger for this class. - */ - private static final Logging logger = Logging.getLogger(OPTICSClusterVisualization.class); - - /** - * A short name characterizing this Visualizer. - */ - private static final String NAME = "OPTICS Cluster Range"; - - /** - * CSS class for markers - */ - protected static final String CSS_BRACKET = "opticsBracket"; - - /** - * Our cluster order - */ - private ClusterOrderResult<?> co; - - /** - * Our clustering - */ - Clustering<OPTICSModel> clus; - - /** - * The plot - */ - private OPTICSPlot<?> opticsplot; - - /** - * Constructor. - * - * @param task Visualization task - */ - public OPTICSClusterVisualization(VisualizationTask task) { - super(task); - this.co = task.getResult(); - this.clus = findOPTICSClustering(this.co); - this.opticsplot = OPTICSPlot.plotForClusterOrder(this.co, context); - context.addResultListener(this); - incrementalRedraw(); - } - - /** - * Find the OPTICS clustering child of a cluster order. - * - * @param co Cluster order - * @return OPTICS clustering - */ - @SuppressWarnings("unchecked") - protected static Clustering<OPTICSModel> findOPTICSClustering(ClusterOrderResult<?> co) { - for(Result r : co.getHierarchy().getChildren(co)) { - if(!Clustering.class.isInstance(r)) { - continue; - } - Clustering<?> clus = (Clustering<?>) r; - if(clus.getToplevelClusters().size() == 0) { - continue; - } - Cluster<?> firstcluster = clus.getToplevelClusters().iterator().next(); - if(firstcluster.getModel() instanceof OPTICSModel) { - return (Clustering<OPTICSModel>) clus; - } - } - return null; - } - - @Override - protected void redraw() { - final double scale = StyleLibrary.SCALE; - final double sizex = scale; - final double sizey = scale * task.getHeight() / task.getWidth(); - final double margin = context.getStyleLibrary().getSize(StyleLibrary.MARGIN); - layer = SVGUtil.svgElement(svgp.getDocument(), SVGConstants.SVG_G_TAG); - final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), sizex, sizey, margin); - SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform); - - addCSSClasses(); - - drawClusters(scale, scale / opticsplot.getRatio(), clus.getToplevelClusters(), 1); - } - - /** - * Recursively draw clusters - * - * @param sizex Width - * @param sizey Height of optics plot - * @param clusters Current set of clusters - * @param depth Recursion depth - */ - private void drawClusters(double sizex, double sizey, List<Cluster<OPTICSModel>> clusters, int depth) { - final double scale = StyleLibrary.SCALE; - for(Cluster<OPTICSModel> cluster : clusters) { - try { - OPTICSModel model = cluster.getModel(); - final double x1 = sizex * ((model.getStartIndex() + .25) / this.co.getClusterOrder().size()); - final double x2 = sizex * ((model.getEndIndex() + .75) / this.co.getClusterOrder().size()); - final double y = sizey + depth * scale * 0.01; - Element e = svgp.svgLine(x1, y, x2, y); - SVGUtil.addCSSClass(e, CSS_BRACKET); - layer.appendChild(e); - } - catch(ClassCastException e) { - logger.warning("Expected OPTICSModel, got: " + cluster.getModel().getClass().getSimpleName()); - } - // Descend - final List<Cluster<OPTICSModel>> children = cluster.getChildren(); - if(children != null) { - drawClusters(sizex, sizey, children, depth + 1); - } - } - } - - /** - * Adds the required CSS-Classes - */ - private void addCSSClasses() { - // Class for the markers - if(!svgp.getCSSClassManager().contains(CSS_BRACKET)) { - final CSSClass cls = new CSSClass(this, CSS_BRACKET); - cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, context.getStyleLibrary().getColor(StyleLibrary.PLOT)); - cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, context.getStyleLibrary().getLineWidth(StyleLibrary.PLOT)); - svgp.addCSSClassOrLogError(cls); - } - } - - @Override - public void resultChanged(Result current) { - if(current instanceof SelectionResult || current == co || current == opticsplot) { - synchronizedRedraw(); - return; - } - super.resultChanged(current); - } - - /** - * Factory class for OPTICS plot selections. - * - * @author Erich Schubert - * - * @apiviz.stereotype factory - * @apiviz.uses OPTICSPlotSelectionVisualization oneway - - «create» - */ - public static class Factory extends AbstractVisFactory { - /** - * Constructor, adhering to - * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable} - */ - public Factory() { - super(); - } - - @Override - public void processNewResult(HierarchicalResult baseResult, Result result) { - Collection<OPTICSPlot<?>> plots = ResultUtil.filterResults(result, OPTICSPlot.class); - for(OPTICSPlot<?> plot : plots) { - ClusterOrderResult<?> co = plot.getClusterOrder(); - final VisualizationTask task = new VisualizationTask(NAME, co, null, this, plot); - task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE); - baseResult.getHierarchy().add(plot, task); - } - } - - @Override - public Visualization makeVisualization(VisualizationTask task) { - return new OPTICSClusterVisualization(task); - } - - @Override - public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) { - // Don't use thumbnails - return false; - } - - @Override - public Class<? extends Projection> getProjectionType() { - return null; - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSPlotCutVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSPlotCutVisualization.java deleted file mode 100644 index 9c44c839..00000000 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSPlotCutVisualization.java +++ /dev/null @@ -1,330 +0,0 @@ -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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -
-import java.util.Collection;
-
-import org.apache.batik.util.SVG12Constants;
-import org.apache.batik.util.SVGConstants;
-import org.w3c.dom.Element;
-import org.w3c.dom.events.Event;
-import org.w3c.dom.svg.SVGPoint;
-
-import de.lmu.ifi.dbs.elki.data.Clustering;
-import de.lmu.ifi.dbs.elki.data.model.Model;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-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.optics.ClusterOrderResult;
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
-import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
-import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
-import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSCut;
-import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot;
-import de.lmu.ifi.dbs.elki.visualization.projections.Projection;
-import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary;
-import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil;
-import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisFactory;
-import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization;
-import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization;
-import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask;
-
-/**
- * Visualizes a cut in an OPTICS Plot to select an Epsilon value and generate a
- * new clustering result
- *
- * @author Heidi Kolb
- *
- * @apiviz.uses ClusterOrderResult oneway - 1 visualizes
- * @apiviz.uses OPTICSPlot oneway - 1 visualizes
- *
- * @param <D> distance type
- */
-public class OPTICSPlotCutVisualization<D extends Distance<D>> extends AbstractVisualization implements DragableArea.DragListener {
- /**
- * A short name characterizing this Visualizer.
- */
- private static final String NAME = "OPTICS Cut";
-
- /**
- * Our concerned curve
- */
- ClusterOrderResult<D> order;
-
- /**
- * The actual plot
- */
- private OPTICSPlot<D> opticsplot;
-
- /**
- * CSS-Styles
- */
- protected static final String CSS_LINE = "opticsPlotLine";
-
- /**
- * CSS-Styles
- */
- protected final static String CSS_EPSILON = "opticsPlotEpsilonValue";
-
- /**
- * The current epsilon value.
- */
- private double epsilon = 0.0;
-
- /**
- * The height of the plot
- */
- private double plotHeight;
-
- /**
- * Sensitive (clickable) area
- */
- private DragableArea eventarea = null;
-
- /**
- * The label element
- */
- private Element elemText = null;
-
- /**
- * The line element
- */
- private Element elementLine = null;
-
- /**
- * The drag handle element
- */
- private Element elementPoint = null;
-
- /**
- * Constructor.
- *
- * @param task Task
- */
- public OPTICSPlotCutVisualization(VisualizationTask task) {
- super(task);
- this.order = task.getResult();
- this.opticsplot = OPTICSPlot.plotForClusterOrder(this.order, context);
- this.plotHeight = StyleLibrary.SCALE / opticsplot.getRatio();
-
- synchronizedRedraw();
- }
-
- @Override
- protected void redraw() {
- incrementalRedraw();
- }
-
- @Override
- protected void incrementalRedraw() {
- addCSSClasses();
-
- final double scale = StyleLibrary.SCALE;
-
- if(layer == null) {
- layer = svgp.svgElement(SVGConstants.SVG_G_TAG);
- final double sizex = scale;
- final double sizey = scale * task.getHeight() / task.getWidth();
- final double margin = context.getStyleLibrary().getSize(StyleLibrary.MARGIN);
- final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), sizex, sizey, margin);
- SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform);
- SVGUtil.setAtt(layer, SVGConstants.SVG_NAME_ATTRIBUTE, "cut layer");
- }
-
- // TODO make the number of digits configurable
- final String label = (epsilon != 0.0) ? FormatUtil.format(epsilon, 4) : "";
- // compute absolute y-value of bar
- final double yAct = plotHeight - getYFromEpsilon(epsilon);
-
- 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 {
- elemText.setTextContent(label);
- SVGUtil.setAtt(elemText, SVGConstants.SVG_Y_ATTRIBUTE, yAct);
- }
-
- // line and handle
- if(elementLine == null) {
- elementLine = svgp.svgLine(0, yAct, StyleLibrary.SCALE * 1.05, yAct);
- SVGUtil.addCSSClass(elementLine, CSS_LINE);
- layer.appendChild(elementLine);
- }
- else {
- SVGUtil.setAtt(elementLine, SVG12Constants.SVG_Y1_ATTRIBUTE, yAct);
- SVGUtil.setAtt(elementLine, SVG12Constants.SVG_Y2_ATTRIBUTE, yAct);
- }
- if(elementPoint == null) {
- elementPoint = svgp.svgCircle(StyleLibrary.SCALE * 1.05, yAct, StyleLibrary.SCALE * 0.004);
- SVGUtil.addCSSClass(elementPoint, CSS_LINE);
- layer.appendChild(elementPoint);
- }
- else {
- SVGUtil.setAtt(elementPoint, SVG12Constants.SVG_CY_ATTRIBUTE, yAct);
- }
-
- if(eventarea == null) {
- eventarea = new DragableArea(svgp, StyleLibrary.SCALE, 0, StyleLibrary.SCALE * 0.1, plotHeight, this);
- layer.appendChild(eventarea.getElement());
- }
- }
-
- @Override
- public void destroy() {
- super.destroy();
- eventarea.destroy();
- }
-
- /**
- * Get epsilon from y-value
- *
- * @param y y-Value
- * @return epsilon
- */
- protected double getEpsilonFromY(double y) {
- if(y < 0) {
- y = 0;
- }
- if(y > plotHeight) {
- y = plotHeight;
- }
- return opticsplot.getScale().getUnscaled(y / plotHeight);
- }
-
- /**
- * Get y-value from epsilon
- *
- * @param epsilon epsilon
- * @return y-Value
- */
- protected double getYFromEpsilon(double epsilon) {
- double y = opticsplot.getScale().getScaled(epsilon) * plotHeight;
- if(y < 0) {
- y = 0;
- }
- if(y > plotHeight) {
- y = plotHeight;
- }
- return y;
- }
-
- @Override
- public boolean startDrag(SVGPoint start, @SuppressWarnings("unused") Event evt) {
- epsilon = getEpsilonFromY(plotHeight - start.getY());
- // opvis.unsetEpsilonExcept(this);
- synchronizedRedraw();
- return true;
- }
-
- @Override
- public boolean duringDrag(@SuppressWarnings("unused") SVGPoint start, SVGPoint end, @SuppressWarnings("unused") Event evt, boolean inside) {
- if(inside) {
- epsilon = getEpsilonFromY(plotHeight - end.getY());
- }
- // opvis.unsetEpsilonExcept(this);
- synchronizedRedraw();
- return true;
- }
-
- @Override
- public boolean endDrag(@SuppressWarnings("unused") SVGPoint start, SVGPoint end, @SuppressWarnings("unused") Event evt, boolean inside) {
- if(inside) {
- epsilon = getEpsilonFromY(plotHeight - end.getY());
- // opvis.unsetEpsilonExcept(this);
-
- // FIXME: replace an existing optics cut result!
- Clustering<Model> cl = OPTICSCut.makeOPTICSCut(order, opticsplot.getDistanceAdapter(), epsilon);
- order.addChildResult(cl);
- }
- context.resultChanged(this.task);
- // synchronizedRedraw();
- return true;
- }
-
- /**
- * Reset the epsilon value.
- */
- public void unsetEpsilon() {
- epsilon = 0.0;
- }
-
- /**
- * Adds the required CSS-Classes
- */
- private void addCSSClasses() {
- // Class for the epsilon-value
- if(!svgp.getCSSClassManager().contains(CSS_EPSILON)) {
- final CSSClass label = new CSSClass(svgp, CSS_EPSILON);
- label.setStatement(SVGConstants.CSS_FILL_PROPERTY, context.getStyleLibrary().getTextColor(StyleLibrary.AXIS_LABEL));
- label.setStatement(SVGConstants.CSS_FONT_FAMILY_PROPERTY, context.getStyleLibrary().getFontFamily(StyleLibrary.AXIS_LABEL));
- label.setStatement(SVGConstants.CSS_FONT_SIZE_PROPERTY, context.getStyleLibrary().getTextSize(StyleLibrary.AXIS_LABEL));
- svgp.addCSSClassOrLogError(label);
- }
- // Class for the epsilon cut line
- if(!svgp.getCSSClassManager().contains(CSS_LINE)) {
- final CSSClass lcls = new CSSClass(svgp, CSS_LINE);
- lcls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, context.getStyleLibrary().getColor(StyleLibrary.PLOT));
- lcls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, 0.5 * context.getStyleLibrary().getLineWidth(StyleLibrary.PLOT));
- svgp.addCSSClassOrLogError(lcls);
- }
- }
-
- /**
- * Factory class
- *
- * @author Erich Schubert
- *
- * @apiviz.stereotype factory
- * @apiviz.uses OPTICSPlotCutVisualization oneway - - «create»
- */
- public static class Factory extends AbstractVisFactory {
- public Factory() {
- super();
- }
-
- @Override
- public void processNewResult(HierarchicalResult baseResult, Result result) {
- Collection<OPTICSPlot<?>> plots = ResultUtil.filterResults(result, OPTICSPlot.class);
- for(OPTICSPlot<?> plot : plots) {
- ClusterOrderResult<?> co = plot.getClusterOrder();
- final VisualizationTask task = new VisualizationTask(NAME, co, null, this, plot);
- task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE);
- baseResult.getHierarchy().add(plot, task);
- }
- }
-
- @Override
- public Visualization makeVisualization(VisualizationTask task) {
- return new OPTICSPlotCutVisualization<DoubleDistance>(task);
- }
-
- @Override
- public Class<? extends Projection> getProjectionType() {
- return null;
- }
- }
-}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSPlotSelectionVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSPlotSelectionVisualization.java deleted file mode 100644 index d5c5a232..00000000 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSPlotSelectionVisualization.java +++ /dev/null @@ -1,406 +0,0 @@ -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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.batik.dom.events.DOMMouseEvent;
-import org.apache.batik.util.SVGConstants;
-import org.w3c.dom.Element;
-import org.w3c.dom.events.Event;
-import org.w3c.dom.svg.SVGPoint;
-
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.result.DBIDSelection;
-import de.lmu.ifi.dbs.elki.result.HierarchicalResult;
-import de.lmu.ifi.dbs.elki.result.Result;
-import de.lmu.ifi.dbs.elki.result.ResultUtil;
-import de.lmu.ifi.dbs.elki.result.SelectionResult;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderEntry;
-import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
-import de.lmu.ifi.dbs.elki.visualization.batikutil.DragableArea;
-import de.lmu.ifi.dbs.elki.visualization.css.CSSClass;
-import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot;
-import de.lmu.ifi.dbs.elki.visualization.projections.Projection;
-import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary;
-import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil;
-import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisFactory;
-import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization;
-import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization;
-import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask;
-import de.lmu.ifi.dbs.elki.visualization.visualizers.thumbs.ThumbnailVisualization;
-
-/**
- * Handle the marker in an OPTICS plot.
- *
- * @author Heidi Kolb
- *
- * @apiviz.uses ClusterOrderResult oneway - 1
- * @apiviz.uses OPTICSPlot oneway - 1
- * @apiviz.uses DBIDSelection oneway - 1 visualizes
- *
- * @param <D> distance type
- */
-public class OPTICSPlotSelectionVisualization<D extends Distance<D>> extends AbstractVisualization implements DragableArea.DragListener {
- /**
- * The logger for this class.
- */
- private static final Logging logger = Logging.getLogger(OPTICSPlotSelectionVisualization.class);
-
- /**
- * A short name characterizing this Visualizer.
- */
- private static final String NAME = "OPTICS Selection";
-
- /**
- * CSS class for markers
- */
- protected static final String CSS_MARKER = "opticsPlotMarker";
-
- /**
- * CSS class for markers
- */
- protected static final String CSS_RANGEMARKER = "opticsPlotRangeMarker";
-
- /**
- * Input modes
- *
- * @apiviz.exclude
- */
- // TODO: Refactor all Mode copies into a shared class?
- private enum Mode {
- REPLACE, ADD, INVERT
- }
-
- /**
- * Our concerned curve
- */
- ClusterOrderResult<D> co;
-
- /**
- * The plot
- */
- private OPTICSPlot<D> opticsplot;
-
- /**
- * Element for the events
- */
- private Element etag;
-
- /**
- * Element for the marker
- */
- private Element mtag;
-
- /**
- * Constructor.
- *
- * @param task Visualization task
- */
- public OPTICSPlotSelectionVisualization(VisualizationTask task) {
- super(task);
- this.co = task.getResult();
- this.opticsplot = OPTICSPlot.plotForClusterOrder(this.co, context);
- context.addResultListener(this);
- incrementalRedraw();
- }
-
- @Override
- protected void redraw() {
- double scale = StyleLibrary.SCALE;
- final double sizex = scale;
- final double sizey = scale * task.getHeight() / task.getWidth();
- final double margin = context.getStyleLibrary().getSize(StyleLibrary.MARGIN);
- layer = SVGUtil.svgElement(svgp.getDocument(), SVGConstants.SVG_G_TAG);
- final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), sizex, sizey, margin);
- SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform);
-
- addCSSClasses();
-
- this.etag = svgp.svgElement(SVGConstants.SVG_G_TAG);
- this.mtag = svgp.svgElement(SVGConstants.SVG_G_TAG);
-
- double heightPlot = scale / opticsplot.getRatio();
-
- DragableArea drag = new DragableArea(svgp, 0 - scale * 0.1, 0, scale * 1.1, heightPlot, this);
- etag = drag.getElement();
-
- addMarker();
- // mtag first, etag must be the top Element
- layer.appendChild(mtag);
- layer.appendChild(etag);
- }
-
- /**
- * Add marker for the selected IDs to mtag
- */
- public void addMarker() {
- List<ClusterOrderEntry<D>> order = co.getClusterOrder();
- // TODO: replace mtag!
- DBIDSelection selContext = context.getSelection();
- if(selContext != null) {
- DBIDs selection = DBIDUtil.ensureSet(selContext.getSelectedIds());
-
- final double width = StyleLibrary.SCALE / order.size();
- int begin = -1;
- for(int j = 0; j < order.size(); j++) {
- DBID id = order.get(j).getID();
- if(selection.contains(id)) {
- if(begin == -1) {
- begin = j;
- }
- }
- else {
- if(begin != -1) {
- Element marker = addMarkerRect(begin * width, (j - begin) * width);
- SVGUtil.addCSSClass(marker, CSS_MARKER);
- mtag.appendChild(marker);
- begin = -1;
- }
- }
- }
- // tail
- if(begin != -1) {
- Element marker = addMarkerRect(begin * width, (order.size() - begin) * width);
- SVGUtil.addCSSClass(marker, CSS_MARKER);
- mtag.appendChild(marker);
- }
- }
- }
-
- /**
- * Create a rectangle as marker (Marker higher than plot!)
- *
- * @param x1 X-Value for the marker
- * @param width Width of an entry
- * @return SVG-Element svg-rectangle
- */
- public Element addMarkerRect(double x1, double width) {
- double heightPlot = StyleLibrary.SCALE / opticsplot.getRatio();
- return svgp.svgRect(x1, 0, width, heightPlot);
- }
-
- @Override
- public boolean startDrag(SVGPoint startPoint, @SuppressWarnings("unused") Event evt) {
- List<ClusterOrderEntry<D>> order = co.getClusterOrder();
- int mouseActIndex = getSelectedIndex(order, startPoint);
- if(mouseActIndex >= 0 && mouseActIndex < order.size()) {
- double width = StyleLibrary.SCALE / order.size();
- double x1 = mouseActIndex * width;
- Element marker = addMarkerRect(x1, width);
- SVGUtil.setCSSClass(marker, CSS_RANGEMARKER);
- mtag.appendChild(marker);
- return true;
- }
- return false;
- }
-
- @Override
- public boolean duringDrag(SVGPoint startPoint, SVGPoint dragPoint, @SuppressWarnings("unused") Event evt, @SuppressWarnings("unused") boolean inside) {
- List<ClusterOrderEntry<D>> order = co.getClusterOrder();
- int mouseDownIndex = getSelectedIndex(order, startPoint);
- int mouseActIndex = getSelectedIndex(order, dragPoint);
- final int begin = Math.max(Math.min(mouseDownIndex, mouseActIndex), 0);
- final int end = Math.min(Math.max(mouseDownIndex, mouseActIndex), order.size());
- double width = StyleLibrary.SCALE / order.size();
- double x1 = begin * width;
- double x2 = (end * width) + width;
- mtag.removeChild(mtag.getLastChild());
- Element marker = addMarkerRect(x1, x2 - x1);
- SVGUtil.setCSSClass(marker, CSS_RANGEMARKER);
- mtag.appendChild(marker);
- return true;
- }
-
- @Override
- public boolean endDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, @SuppressWarnings("unused") boolean inside) {
- List<ClusterOrderEntry<D>> order = co.getClusterOrder();
- int mouseDownIndex = getSelectedIndex(order, startPoint);
- int mouseActIndex = getSelectedIndex(order, dragPoint);
- Mode mode = getInputMode(evt);
- final int begin = Math.max(Math.min(mouseDownIndex, mouseActIndex), 0);
- final int end = Math.min(Math.max(mouseDownIndex, mouseActIndex), order.size());
- updateSelection(mode, begin, end);
- return true;
- }
-
- /**
- * Get the current input mode, on each mouse event.
- *
- * @param evt Mouse event.
- * @return Input mode
- */
- private Mode getInputMode(Event evt) {
- if(evt instanceof DOMMouseEvent) {
- DOMMouseEvent domme = (DOMMouseEvent) evt;
- // TODO: visual indication of mode possible?
- if(domme.getShiftKey()) {
- return Mode.ADD;
- }
- else if(domme.getCtrlKey()) {
- return Mode.INVERT;
- }
- else {
- return Mode.REPLACE;
- }
- }
- // Default mode is replace.
- return Mode.REPLACE;
- }
-
- /**
- * Gets the Index of the ClusterOrderEntry where the event occurred
- *
- * @param order List of ClusterOrderEntries
- * @param cPt clicked point
- * @return Index of the object
- */
- private int getSelectedIndex(List<ClusterOrderEntry<D>> order, SVGPoint cPt) {
- int mouseActIndex = (int) ((cPt.getX() / StyleLibrary.SCALE) * order.size());
- return mouseActIndex;
- }
-
- /**
- * Updates the selection for the given ClusterOrderEntry.
- *
- * @param mode Input mode
- * @param begin first index to select
- * @param end last index to select
- */
- protected void updateSelection(Mode mode, int begin, int end) {
- List<ClusterOrderEntry<D>> order = co.getClusterOrder();
- if(begin < 0 || begin > end || end >= order.size()) {
- logger.warning("Invalid range in updateSelection: " + begin + " .. " + end);
- return;
- }
-
- DBIDSelection selContext = context.getSelection();
- HashSetModifiableDBIDs selection;
- if(selContext == null || mode == Mode.REPLACE) {
- selection = DBIDUtil.newHashSet();
- }
- else {
- selection = DBIDUtil.newHashSet(selContext.getSelectedIds());
- }
-
- for(int i = begin; i <= end; i++) {
- DBID id = order.get(i).getID();
- if(mode == Mode.INVERT) {
- if(!selection.contains(id)) {
- selection.add(id);
- }
- else {
- selection.remove(id);
- }
- }
- else {
- // In REPLACE and ADD, add objects.
- // The difference was done before by not re-using the selection.
- // Since we are using a set, we can just add in any case.
- selection.add(id);
- }
- }
- context.setSelection(new DBIDSelection(selection));
- }
-
- /**
- * Adds the required CSS-Classes
- */
- private void addCSSClasses() {
- // Class for the markers
- if(!svgp.getCSSClassManager().contains(CSS_MARKER)) {
- final CSSClass cls = new CSSClass(this, CSS_MARKER);
- cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_BLUE_VALUE);
- cls.setStatement(SVGConstants.CSS_OPACITY_PROPERTY, "0.2");
- svgp.addCSSClassOrLogError(cls);
- }
-
- // Class for the range marking
- if(!svgp.getCSSClassManager().contains(CSS_RANGEMARKER)) {
- final CSSClass rcls = new CSSClass(this, CSS_RANGEMARKER);
- rcls.setStatement(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_RED_VALUE);
- rcls.setStatement(SVGConstants.CSS_OPACITY_PROPERTY, "0.2");
- svgp.addCSSClassOrLogError(rcls);
- }
- }
-
- @Override
- public void resultChanged(Result current) {
- if(current instanceof SelectionResult || current == co || current == opticsplot) {
- synchronizedRedraw();
- return;
- }
- super.resultChanged(current);
- }
-
- /**
- * Factory class for OPTICS plot selections.
- *
- * @author Erich Schubert
- *
- * @apiviz.stereotype factory
- * @apiviz.uses OPTICSPlotSelectionVisualization oneway - - «create»
- */
- public static class Factory extends AbstractVisFactory {
- /**
- * Constructor, adhering to
- * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable}
- */
- public Factory() {
- super();
- }
-
- @Override
- public void processNewResult(HierarchicalResult baseResult, Result result) {
- Collection<OPTICSPlot<?>> plots = ResultUtil.filterResults(result, OPTICSPlot.class);
- for(OPTICSPlot<?> plot : plots) {
- ClusterOrderResult<?> co = plot.getClusterOrder();
- final VisualizationTask task = new VisualizationTask(NAME, co, null, this, plot);
- task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE);
- baseResult.getHierarchy().add(plot, task);
- }
- }
-
- @Override
- public Visualization makeVisualization(VisualizationTask task) {
- return new OPTICSPlotSelectionVisualization<DoubleDistance>(task);
- }
-
- @Override
- public Visualization makeVisualizationOrThumbnail(VisualizationTask task) {
- return new ThumbnailVisualization(this, task, ThumbnailVisualization.ON_SELECTION);
- }
-
- @Override
- public Class<? extends Projection> getProjectionType() {
- return null;
- }
- }
-}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSPlotVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSPlotVisualizer.java deleted file mode 100644 index d1bbddfb..00000000 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSPlotVisualizer.java +++ /dev/null @@ -1,170 +0,0 @@ -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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -import java.io.File; -import java.io.IOException; -import java.util.Collection; - -import org.apache.batik.util.SVGConstants; -import org.w3c.dom.Element; - -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -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.result.optics.ClusterOrderResult; -import de.lmu.ifi.dbs.elki.visualization.css.CSSClassManager.CSSNamingConflict; -import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot; -import de.lmu.ifi.dbs.elki.visualization.projections.Projection; -import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; -import de.lmu.ifi.dbs.elki.visualization.svg.SVGSimpleLinearAxis; -import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil; -import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisFactory; -import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerContext; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerUtil; - -/** - * Visualize an OPTICS result by constructing an OPTICS plot for it. - * - * @author Erich Schubert - * - * @apiviz.has OPTICSPlot oneway - 1 visualizes - * @apiviz.has ClusterOrderResult oneway - 1 visualizes - * - * @param <D> Distance type - */ -public class OPTICSPlotVisualizer<D extends Distance<D>> extends AbstractVisualization { - /** - * Name for this visualizer. - */ - private static final String NAME = "OPTICS Plot"; - - /** - * The actual plot object. - */ - private OPTICSPlot<D> opticsplot; - - /** - * The image we generated. - */ - private File imgfile; - - public OPTICSPlotVisualizer(VisualizationTask task) { - super(task); - this.opticsplot = task.getResult(); - } - - @Override - protected void redraw() { - // TODO: Use width, height, imgratio, number of OPTICS plots! - double scale = StyleLibrary.SCALE; - final double sizex = scale; - final double sizey = scale * task.getHeight() / task.getWidth(); - final double margin = context.getStyleLibrary().getSize(StyleLibrary.MARGIN); - layer = SVGUtil.svgElement(svgp.getDocument(), SVGConstants.SVG_G_TAG); - final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), sizex, sizey, margin); - SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform); - - if(imgfile == null) { - try { - imgfile = opticsplot.getAsTempFile(); - } - catch(IOException e) { - LoggingUtil.exception("Could not generate OPTICS plot.", e); - } - } - - Element itag = svgp.svgElement(SVGConstants.SVG_IMAGE_TAG); - SVGUtil.setAtt(itag, SVGConstants.SVG_IMAGE_RENDERING_ATTRIBUTE, SVGConstants.SVG_OPTIMIZE_SPEED_VALUE); - SVGUtil.setAtt(itag, SVGConstants.SVG_X_ATTRIBUTE, 0); - SVGUtil.setAtt(itag, SVGConstants.SVG_Y_ATTRIBUTE, 0); - SVGUtil.setAtt(itag, SVGConstants.SVG_WIDTH_ATTRIBUTE, scale); - SVGUtil.setAtt(itag, SVGConstants.SVG_HEIGHT_ATTRIBUTE, scale / opticsplot.getRatio()); - itag.setAttributeNS(SVGConstants.XLINK_NAMESPACE_URI, SVGConstants.XLINK_HREF_QNAME, imgfile.toURI().toString()); - - layer.appendChild(itag); - - try { - SVGSimpleLinearAxis.drawAxis(svgp, layer, opticsplot.getScale(), 0, scale / opticsplot.getRatio(), 0, 0, true, false, context.getStyleLibrary()); - SVGSimpleLinearAxis.drawAxis(svgp, layer, opticsplot.getScale(), scale, scale / opticsplot.getRatio(), scale, 0, true, true, context.getStyleLibrary()); - } - catch(CSSNamingConflict e) { - LoggingUtil.exception("CSS naming conflict for axes on OPTICS plot", e); - } - } - - /** - * Factory class for OPTICS plot. - * - * @author Erich Schubert - * - * @apiviz.stereotype factory - * @apiviz.uses OPTICSPlotVisualizer oneway - - «create» - */ - public static class Factory extends AbstractVisFactory { - /** - * Constructor, adhering to - * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable} - */ - public Factory() { - super(); - } - - @Override - public void processNewResult(HierarchicalResult baseResult, Result result) { - VisualizerContext context = VisualizerUtil.getContext(baseResult); - Collection<ClusterOrderResult<?>> cos = ResultUtil.filterResults(result, ClusterOrderResult.class); - for(ClusterOrderResult<?> co : cos) { - // Add plots, attach visualizer - OPTICSPlot<?> plot = OPTICSPlot.plotForClusterOrder(co, context); - if(plot != null) { - final VisualizationTask task = new VisualizationTask(NAME, plot, null, this, plot); - task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_STATIC); - baseResult.getHierarchy().add(plot, task); - } - } - } - - @Override - public Visualization makeVisualization(VisualizationTask task) { - return new OPTICSPlotVisualizer<DoubleDistance>(task); - } - - @Override - public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) { - // Don't use thumbnails - return false; - } - - @Override - public Class<? extends Projection> getProjectionType() { - return null; - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSSteepAreaVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSSteepAreaVisualization.java deleted file mode 100644 index eb2f2ba1..00000000 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/OPTICSSteepAreaVisualization.java +++ /dev/null @@ -1,242 +0,0 @@ -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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -import java.awt.Color; -import java.util.Collection; - -import org.apache.batik.util.SVGConstants; -import org.w3c.dom.Element; - -import de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSXi; -import de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSXi.SteepAreaResult; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; -import de.lmu.ifi.dbs.elki.result.HierarchicalResult; -import de.lmu.ifi.dbs.elki.result.Result; -import de.lmu.ifi.dbs.elki.result.ResultUtil; -import de.lmu.ifi.dbs.elki.result.SelectionResult; -import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult; -import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; -import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSDistanceAdapter; -import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot; -import de.lmu.ifi.dbs.elki.visualization.projections.Projection; -import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; -import de.lmu.ifi.dbs.elki.visualization.svg.SVGUtil; -import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisFactory; -import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; - -/** - * Visualize the steep areas found in an OPTICS plot - * - * @author Erich Schubert - * - * @apiviz.uses - * de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSXi.SteepAreaResult - */ -public class OPTICSSteepAreaVisualization<D extends Distance<D>> extends AbstractVisualization { - /** - * A short name characterizing this Visualizer. - */ - private static final String NAME = "OPTICS Steep Areas"; - - /** - * CSS class for markers - */ - protected static final String CSS_STEEP_UP = "opticsSteepUp"; - - /** - * CSS class for markers - */ - protected static final String CSS_STEEP_DOWN = "opticsSteepDown"; - - /** - * Our cluster order - */ - private ClusterOrderResult<D> co; - - /** - * Our clustering - */ - OPTICSXi.SteepAreaResult areas; - - /** - * The plot - */ - private OPTICSPlot<D> opticsplot; - - /** - * Constructor. - * - * @param task Visualization task - */ - public OPTICSSteepAreaVisualization(VisualizationTask task) { - super(task); - this.co = task.getResult(); - this.areas = findSteepAreaResult(this.co); - this.opticsplot = OPTICSPlot.plotForClusterOrder(this.co, context); - context.addResultListener(this); - incrementalRedraw(); - } - - /** - * Find the OPTICS clustering child of a cluster order. - * - * @param co Cluster order - * @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; - } - } - return null; - } - - @Override - protected void redraw() { - final double scale = StyleLibrary.SCALE; - final double sizex = scale; - final double sizey = scale * task.getHeight() / task.getWidth(); - final double margin = context.getStyleLibrary().getSize(StyleLibrary.MARGIN); - layer = SVGUtil.svgElement(svgp.getDocument(), SVGConstants.SVG_G_TAG); - final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), sizex, sizey, margin); - SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform); - - addCSSClasses(); - - final double plotwidth = scale; - final double plotheight = scale / opticsplot.getRatio(); - - OPTICSDistanceAdapter<D> adapter = opticsplot.getDistanceAdapter(); - for(OPTICSXi.SteepArea area : areas) { - final int st = area.getStartIndex(); - final int en = area.getEndIndex(); - // Note: make sure we are using doubles! - final double x1 = (st + .25) / this.co.getClusterOrder().size(); - final double x2 = (en + .75) / this.co.getClusterOrder().size(); - final double d1 = adapter.getDoubleForEntry(this.co.getClusterOrder().get(st)); - final double d2 = adapter.getDoubleForEntry(this.co.getClusterOrder().get(en)); - final double y1 = (!Double.isInfinite(d1) && !Double.isNaN(d1)) ? (1. - opticsplot.getScale().getScaled(d1)) : 0.; - final double y2 = (!Double.isInfinite(d2) && !Double.isNaN(d2)) ? (1. - opticsplot.getScale().getScaled(d2)) : 0.; - Element e = svgp.svgLine(plotwidth * x1, plotheight * y1, plotwidth * x2, plotheight * y2); - if(area instanceof OPTICSXi.SteepDownArea) { - SVGUtil.addCSSClass(e, CSS_STEEP_DOWN); - } - else { - SVGUtil.addCSSClass(e, CSS_STEEP_UP); - } - layer.appendChild(e); - } - } - - /** - * Adds the required CSS-Classes - */ - private void addCSSClasses() { - // Class for the markers - if(!svgp.getCSSClassManager().contains(CSS_STEEP_DOWN)) { - final CSSClass cls = new CSSClass(this, CSS_STEEP_DOWN); - Color color = SVGUtil.stringToColor(context.getStyleLibrary().getColor(StyleLibrary.PLOT)); - 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)); - cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, SVGUtil.colorToString(color)); - cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, context.getStyleLibrary().getLineWidth(StyleLibrary.PLOT)); - svgp.addCSSClassOrLogError(cls); - } - if(!svgp.getCSSClassManager().contains(CSS_STEEP_UP)) { - final CSSClass cls = new CSSClass(this, CSS_STEEP_UP); - Color color = SVGUtil.stringToColor(context.getStyleLibrary().getColor(StyleLibrary.PLOT)); - 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)); - cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, SVGUtil.colorToString(color)); - cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, context.getStyleLibrary().getLineWidth(StyleLibrary.PLOT)); - svgp.addCSSClassOrLogError(cls); - } - } - - @Override - public void resultChanged(Result current) { - if(current instanceof SelectionResult || current == co || current == opticsplot) { - synchronizedRedraw(); - return; - } - super.resultChanged(current); - } - - /** - * Factory class for OPTICS plot selections. - * - * @author Erich Schubert - * - * @apiviz.stereotype factory - * @apiviz.uses OPTICSPlotSelectionVisualization oneway - - «create» - */ - public static class Factory extends AbstractVisFactory { - /** - * Constructor, adhering to - * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable} - */ - public Factory() { - super(); - } - - @Override - public void processNewResult(HierarchicalResult baseResult, Result result) { - Collection<OPTICSPlot<?>> plots = ResultUtil.filterResults(result, OPTICSPlot.class); - for(OPTICSPlot<?> plot : plots) { - ClusterOrderResult<?> co = plot.getClusterOrder(); - final SteepAreaResult steep = findSteepAreaResult(co); - if(steep != null) { - final VisualizationTask task = new VisualizationTask(NAME, co, null, this, plot); - task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_INTERACTIVE); - task.put(VisualizationTask.META_VISIBLE_DEFAULT, false); - baseResult.getHierarchy().add(steep, task); - } - } - } - - @Override - public Visualization makeVisualization(VisualizationTask task) { - return new OPTICSSteepAreaVisualization<DoubleDistance>(task); - } - - @Override - public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) { - // Don't use thumbnails - return false; - } - - @Override - public Class<? extends Projection> getProjectionType() { - return null; - } - } -}
\ No newline at end of file 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 8667c2d4..06268dac 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 @@ -1,26 +1,27 @@ 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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ import java.awt.image.RenderedImage; import java.util.Collection; @@ -32,13 +33,12 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.PixmapResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; -import de.lmu.ifi.dbs.elki.visualization.projections.Projection; +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.SVGUtil; import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisFactory; import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization; import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; /** * Visualize an arbitrary pixmap result. @@ -121,7 +121,9 @@ public class PixmapVisualizer extends AbstractVisualization { Collection<PixmapResult> prs = ResultUtil.filterResults(result, PixmapResult.class); for(PixmapResult pr : prs) { // Add plots, attach visualizer - final VisualizationTask task = new VisualizationTask(NAME, pr, null, this, null); + final VisualizationTask task = new VisualizationTask(NAME, pr, null, this); + task.width = pr.getImage().getWidth() / pr.getImage().getHeight(); + task.height = 1.0; task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_STATIC); baseResult.getHierarchy().add(pr, task); } @@ -137,10 +139,5 @@ public class PixmapVisualizer extends AbstractVisualization { // Don't use thumbnails return false; } - - @Override - public Class<? extends Projection> getProjectionType() { - return null; - } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java index 9a62001e..9be580f7 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java @@ -1,26 +1,27 @@ 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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ import java.util.Collection; @@ -35,15 +36,14 @@ import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter; import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; -import de.lmu.ifi.dbs.elki.visualization.projections.Projection; +import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; +import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; import de.lmu.ifi.dbs.elki.visualization.style.StyleLibrary; 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.StaticVisualization; import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerContext; /** * Pseudo-Visualizer, that lists the settings of the algorithm- @@ -140,7 +140,9 @@ public class SettingsVisFactory extends AbstractVisFactory { public void processNewResult(HierarchicalResult baseResult, Result newResult) { final IterableIterator<SettingsResult> settingsResults = ResultUtil.filteredResults(newResult, SettingsResult.class); for(SettingsResult sr : settingsResults) { - final VisualizationTask task = new VisualizationTask(NAME, sr, null, this, null); + final VisualizationTask task = new VisualizationTask(NAME, sr, null, this); + task.width = 1.0; + task.height = 1.0; task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_STATIC); baseResult.getHierarchy().add(sr, task); } @@ -150,9 +152,4 @@ public class SettingsVisFactory extends AbstractVisFactory { public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) { return false; } - - @Override - public Class<? extends Projection> getProjectionType() { - return null; - } }
\ No newline at end of file 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 c7a64d54..f9b1ef52 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 @@ -1,26 +1,27 @@ 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) 2011 -Ludwig-Maximilians-Universität München -Lehr- und Forschungseinheit für Datenbanksysteme -ELKI Development Team - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ import java.awt.image.RenderedImage; import java.util.Collection; @@ -36,13 +37,12 @@ import de.lmu.ifi.dbs.elki.result.HierarchicalResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; -import de.lmu.ifi.dbs.elki.visualization.projections.Projection; +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.SVGUtil; import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisFactory; import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization; import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; -import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; /** * Visualize a similarity matrix with object labels @@ -149,7 +149,9 @@ public class SimilarityMatrixVisualizer extends AbstractVisualization { Collection<ComputeSimilarityMatrixImage.SimilarityMatrix> prs = ResultUtil.filterResults(result, ComputeSimilarityMatrixImage.SimilarityMatrix.class); for(ComputeSimilarityMatrixImage.SimilarityMatrix pr : prs) { // Add plots, attach visualizer - final VisualizationTask task = new VisualizationTask(NAME, pr, null, this, null); + final VisualizationTask task = new VisualizationTask(NAME, pr, null, this); + task.width = 1.0; + task.height = 1.0; task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_STATIC); baseResult.getHierarchy().add(pr, task); } @@ -165,10 +167,5 @@ public class SimilarityMatrixVisualizer extends AbstractVisualization { // Don't use thumbnails return false; } - - @Override - public Class<? extends Projection> getProjectionType() { - return null; - } } }
\ No newline at end of file |