~ubuntu-branches/ubuntu/vivid/elki/vivid

« back to all changes in this revision

Viewing changes to src/de/lmu/ifi/dbs/elki/visualization/visualizers/scatterplot/selection/SelectionConvexHullVisualization.java

  • Committer: Package Import Robot
  • Author(s): Erich Schubert
  • Date: 2012-12-14 20:45:15 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20121214204515-4m0d0er9ivtu5w9d
Tags: 0.5.5-1
New upstream release: 0.5.5 interim release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
 * 
59
59
 * @author Robert Rödler
60
60
 * 
61
 
 * @apiviz.has SelectionResult oneway - - visualizes
62
 
 * @apiviz.has DBIDSelection oneway - - visualizes
63
 
 * @apiviz.uses GrahamScanConvexHull2D
 
61
 * @apiviz.stereotype factory
 
62
 * @apiviz.uses Instance oneway - - «create»
64
63
 */
65
 
public class SelectionConvexHullVisualization extends AbstractScatterplotVisualization implements DataStoreListener {
 
64
public class SelectionConvexHullVisualization extends AbstractVisFactory {
66
65
  /**
67
66
   * A short name characterizing this Visualizer.
68
67
   */
69
68
  private static final String NAME = "Convex Hull of Selection";
70
69
 
71
70
  /**
72
 
   * Generic tag to indicate the type of element. Used in IDs, CSS-Classes etc.
73
 
   */
74
 
  public static final String SELECTEDHULL = "selectionConvexHull";
75
 
 
76
 
  /**
77
 
   * Constructor.
78
 
   * 
79
 
   * @param task Task
80
 
   */
81
 
  public SelectionConvexHullVisualization(VisualizationTask task) {
82
 
    super(task);
83
 
    context.addResultListener(this);
84
 
    context.addDataStoreListener(this);
85
 
    incrementalRedraw();
86
 
  }
87
 
 
88
 
  @Override
89
 
  protected void redraw() {
90
 
    addCSSClasses(svgp);
91
 
    DBIDSelection selContext = context.getSelection();
92
 
    if(selContext != null) {
93
 
      DBIDs selection = selContext.getSelectedIds();
94
 
      GrahamScanConvexHull2D hull = new GrahamScanConvexHull2D();
95
 
      for(DBIDIter iter = selection.iter(); iter.valid(); iter.advance()) {
96
 
        try {
97
 
          hull.add(new Vector(proj.fastProjectDataToRenderSpace(rel.get(iter))));
98
 
        }
99
 
        catch(ObjectNotFoundException e) {
100
 
          // ignore
101
 
        }
102
 
      }
103
 
      Polygon chres = hull.getHull();
104
 
      if(chres != null && chres.size() >= 3) {
105
 
        SVGPath path = new SVGPath(chres);
106
 
 
107
 
        Element selHull = path.makeElement(svgp);
108
 
        SVGUtil.addCSSClass(selHull, SELECTEDHULL);
109
 
        // TODO: use relative selection size for opacity?
110
 
        layer.appendChild(selHull);
111
 
      }
112
 
    }
113
 
  }
114
 
 
115
 
  /**
116
 
   * Adds the required CSS-Classes
117
 
   * 
118
 
   * @param svgp SVG-Plot
119
 
   */
120
 
  private void addCSSClasses(SVGPlot svgp) {
121
 
    // Class for the dot markers
122
 
    if(!svgp.getCSSClassManager().contains(SELECTEDHULL)) {
123
 
      CSSClass cls = new CSSClass(this, SELECTEDHULL);
124
 
      // cls = new CSSClass(this, CONVEXHULL);
125
 
      cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, context.getStyleLibrary().getColor(StyleLibrary.SELECTION));
126
 
      cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, context.getStyleLibrary().getLineWidth(StyleLibrary.SELECTION));
127
 
      cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, context.getStyleLibrary().getColor(StyleLibrary.SELECTION));
128
 
      cls.setStatement(SVGConstants.CSS_OPACITY_PROPERTY, ".25");
129
 
      cls.setStatement(SVGConstants.CSS_STROKE_LINECAP_PROPERTY, SVGConstants.CSS_ROUND_VALUE);
130
 
      cls.setStatement(SVGConstants.CSS_STROKE_LINEJOIN_PROPERTY, SVGConstants.CSS_ROUND_VALUE);
131
 
      svgp.addCSSClassOrLogError(cls);
132
 
    }
133
 
  }
134
 
 
135
 
  /**
136
 
   * Factory for visualizers to generate an SVG-Element containing the convex
137
 
   * hull of the selected points
 
71
   * Constructor
 
72
   */
 
73
  public SelectionConvexHullVisualization() {
 
74
    super();
 
75
    thumbmask |= ThumbnailVisualization.ON_DATA | ThumbnailVisualization.ON_SELECTION;
 
76
  }
 
77
 
 
78
  @Override
 
79
  public Visualization makeVisualization(VisualizationTask task) {
 
80
    return new Instance(task);
 
81
  }
 
82
 
 
83
  @Override
 
84
  public void processNewResult(HierarchicalResult baseResult, Result result) {
 
85
    Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
 
86
    for(SelectionResult selres : selectionResults) {
 
87
      Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
 
88
      for(ScatterPlotProjector<?> p : ps) {
 
89
        final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
 
90
        task.level = VisualizationTask.LEVEL_DATA - 2;
 
91
        baseResult.getHierarchy().add(selres, task);
 
92
        baseResult.getHierarchy().add(p, task);
 
93
      }
 
94
    }
 
95
  }
 
96
 
 
97
  /**
 
98
   * Instance
138
99
   * 
139
100
   * @author Robert Rödler
140
101
   * 
141
 
   * @apiviz.stereotype factory
142
 
   * @apiviz.uses SelectionConvexHullVisualization oneway - - «create»
 
102
   * @apiviz.has SelectionResult oneway - - visualizes
 
103
   * @apiviz.has DBIDSelection oneway - - visualizes
 
104
   * @apiviz.uses GrahamScanConvexHull2D
143
105
   */
144
 
  public static class Factory extends AbstractVisFactory {
145
 
    /**
146
 
     * Constructor
147
 
     */
148
 
    public Factory() {
149
 
      super();
150
 
      thumbmask |= ThumbnailVisualization.ON_DATA | ThumbnailVisualization.ON_SELECTION;
151
 
    }
152
 
 
153
 
    @Override
154
 
    public Visualization makeVisualization(VisualizationTask task) {
155
 
      return new SelectionConvexHullVisualization(task);
156
 
    }
157
 
 
158
 
    @Override
159
 
    public void processNewResult(HierarchicalResult baseResult, Result result) {
160
 
      Collection<SelectionResult> selectionResults = ResultUtil.filterResults(result, SelectionResult.class);
161
 
      for(SelectionResult selres : selectionResults) {
162
 
        Collection<ScatterPlotProjector<?>> ps = ResultUtil.filterResults(baseResult, ScatterPlotProjector.class);
163
 
        for(ScatterPlotProjector<?> p : ps) {
164
 
          final VisualizationTask task = new VisualizationTask(NAME, selres, p.getRelation(), this);
165
 
          task.put(VisualizationTask.META_LEVEL, VisualizationTask.LEVEL_DATA - 2);
166
 
          baseResult.getHierarchy().add(selres, task);
167
 
          baseResult.getHierarchy().add(p, task);
168
 
        }
 
106
  public class Instance extends AbstractScatterplotVisualization implements DataStoreListener {
 
107
    /**
 
108
     * Generic tag to indicate the type of element. Used in IDs, CSS-Classes
 
109
     * etc.
 
110
     */
 
111
    public static final String SELECTEDHULL = "selectionConvexHull";
 
112
 
 
113
    /**
 
114
     * Constructor.
 
115
     * 
 
116
     * @param task Task
 
117
     */
 
118
    public Instance(VisualizationTask task) {
 
119
      super(task);
 
120
      context.addResultListener(this);
 
121
      context.addDataStoreListener(this);
 
122
      incrementalRedraw();
 
123
    }
 
124
 
 
125
    @Override
 
126
    protected void redraw() {
 
127
      addCSSClasses(svgp);
 
128
      DBIDSelection selContext = context.getSelection();
 
129
      if(selContext != null) {
 
130
        DBIDs selection = selContext.getSelectedIds();
 
131
        GrahamScanConvexHull2D hull = new GrahamScanConvexHull2D();
 
132
        for(DBIDIter iter = selection.iter(); iter.valid(); iter.advance()) {
 
133
          try {
 
134
            hull.add(new Vector(proj.fastProjectDataToRenderSpace(rel.get(iter))));
 
135
          }
 
136
          catch(ObjectNotFoundException e) {
 
137
            // ignore
 
138
          }
 
139
        }
 
140
        Polygon chres = hull.getHull();
 
141
        if(chres != null && chres.size() >= 3) {
 
142
          SVGPath path = new SVGPath(chres);
 
143
 
 
144
          Element selHull = path.makeElement(svgp);
 
145
          SVGUtil.addCSSClass(selHull, SELECTEDHULL);
 
146
          // TODO: use relative selection size for opacity?
 
147
          layer.appendChild(selHull);
 
148
        }
 
149
      }
 
150
    }
 
151
 
 
152
    /**
 
153
     * Adds the required CSS-Classes
 
154
     * 
 
155
     * @param svgp SVG-Plot
 
156
     */
 
157
    private void addCSSClasses(SVGPlot svgp) {
 
158
      // Class for the dot markers
 
159
      if(!svgp.getCSSClassManager().contains(SELECTEDHULL)) {
 
160
        final StyleLibrary style = context.getStyleResult().getStyleLibrary();
 
161
        CSSClass cls = new CSSClass(this, SELECTEDHULL);
 
162
        // cls = new CSSClass(this, CONVEXHULL);
 
163
        cls.setStatement(SVGConstants.CSS_STROKE_PROPERTY, style.getColor(StyleLibrary.SELECTION));
 
164
        cls.setStatement(SVGConstants.CSS_STROKE_WIDTH_PROPERTY, style.getLineWidth(StyleLibrary.SELECTION));
 
165
        cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, style.getColor(StyleLibrary.SELECTION));
 
166
        cls.setStatement(SVGConstants.CSS_OPACITY_PROPERTY, ".25");
 
167
        cls.setStatement(SVGConstants.CSS_STROKE_LINECAP_PROPERTY, SVGConstants.CSS_ROUND_VALUE);
 
168
        cls.setStatement(SVGConstants.CSS_STROKE_LINEJOIN_PROPERTY, SVGConstants.CSS_ROUND_VALUE);
 
169
        svgp.addCSSClassOrLogError(cls);
169
170
      }
170
171
    }
171
172
  }