diff options
author | Andrej Shadura <andrewsh@debian.org> | 2019-03-09 22:30:28 +0000 |
---|---|---|
committer | Andrej Shadura <andrewsh@debian.org> | 2019-03-09 22:30:28 +0000 |
commit | cde76aeb42240f7270bc6605c606ae07d2dc5a7d (patch) | |
tree | c3ebf1d7745224f524da31dbabc5d76b9ea75916 /src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java |
Import Upstream version 0.4.0~beta1
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java')
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java new file mode 100644 index 00000000..05a2d1f3 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java @@ -0,0 +1,160 @@ +package de.lmu.ifi.dbs.elki.visualization.visualizers.vis2d; +/* +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; + +import org.w3c.dom.Element; + +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.database.datastore.DataStoreEvent; +import de.lmu.ifi.dbs.elki.database.datastore.DataStoreListener; +import de.lmu.ifi.dbs.elki.database.ids.DBID; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +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.ClusterOrderEntry; +import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult; +import de.lmu.ifi.dbs.elki.utilities.iterator.IterableUtil; +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.projections.Projection2D; +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.Visualization; +import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizationTask; +import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerUtil; + +/** + * Cluster order visualizer. + * + * @author Erich Schubert + * + * @apiviz.has ClusterOrderResult oneway - - visualizes + */ +// TODO: listen for CLUSTER ORDER changes. +public class ClusterOrderVisualization<NV extends NumberVector<NV, ?>> extends P2DVisualization<NV> implements DataStoreListener { + /** + * A short name characterizing this Visualizer. + */ + private static final String NAME = "Predecessor Graph"; + + /** + * CSS class name + */ + private static final String CSSNAME = "predecessor"; + + /** + * The result we visualize + */ + protected ClusterOrderResult<?> result; + + public ClusterOrderVisualization(VisualizationTask task) { + super(task); + result = task.getResult(); + context.addDataStoreListener(this); + incrementalRedraw(); + } + + @Override + public void destroy() { + super.destroy(); + context.removeDataStoreListener(this); + } + + @Override + public void redraw() { + CSSClass cls = new CSSClass(this, CSSNAME); + context.getStyleLibrary().lines().formatCSSClass(cls, 0, context.getStyleLibrary().getLineWidth(StyleLibrary.CLUSTERORDER)); + + svgp.addCSSClassOrLogError(cls); + + for(ClusterOrderEntry<?> ce : result) { + DBID thisId = ce.getID(); + DBID prevId = ce.getPredecessorID(); + if(thisId == null || prevId == null) { + continue; + } + double[] thisVec = proj.fastProjectDataToRenderSpace(rep.get(thisId)); + double[] prevVec = proj.fastProjectDataToRenderSpace(rep.get(prevId)); + + Element arrow = svgp.svgLine(prevVec[0], prevVec[1], thisVec[0], thisVec[1]); + SVGUtil.setCSSClass(arrow, cls.getName()); + + layer.appendChild(arrow); + } + } + + @Override + public void contentChanged(@SuppressWarnings("unused") DataStoreEvent e) { + synchronizedRedraw(); + } + + /** + * Visualize an OPTICS cluster order by drawing connection lines. + * + * @author Erich Schubert + * + * @apiviz.stereotype factory + * @apiviz.uses ClusterOrderVisualization oneway - - «create» + * + * @param <NV> object type + */ + public static class Factory<NV extends NumberVector<NV, ?>> extends AbstractVisFactory { + /** + * Constructor, adhering to + * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable} + */ + public Factory() { + super(); + } + + @Override + public Visualization makeVisualization(VisualizationTask task) { + return new ClusterOrderVisualization<NV>(task); + } + + @Override + public void processNewResult(HierarchicalResult baseResult, Result result) { + Iterator<Relation<? extends NumberVector<?, ?>>> reps = VisualizerUtil.iterateVectorFieldRepresentations(baseResult); + for(Relation<? extends NumberVector<?, ?>> rep : IterableUtil.fromIterator(reps)) { + Collection<ClusterOrderResult<DoubleDistance>> cos = ResultUtil.filterResults(result, ClusterOrderResult.class); + for(ClusterOrderResult<DoubleDistance> co : cos) { + final VisualizationTask task = new VisualizationTask(NAME, co, rep, this, P2DVisualization.class); + task.put(VisualizationTask.META_VISIBLE_DEFAULT, false); + task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA - 1); + baseResult.getHierarchy().add(co, task); + } + } + } + + @Override + public Class<? extends Projection> getProjectionType() { + return Projection2D.class; + } + } +}
\ No newline at end of file |