• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /barrelfish-2018-10-04/usr/eclipseclp/Visualisation/src/com/parctechnologies/eclipse/visualisation/viewers/
1// BEGIN LICENSE BLOCK
2// Version: CMPL 1.1
3//
4// The contents of this file are subject to the Cisco-style Mozilla Public
5// License Version 1.1 (the "License"); you may not use this file except
6// in compliance with the License.  You may obtain a copy of the License
7// at www.eclipse-clp.org/license.
8//
9// Software distributed under the License is distributed on an "AS IS"
10// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11// the License for the specific language governing rights and limitations
12// under the License.
13//
14// The Original Code is  The ECLiPSe Constraint Logic Programming System.
15// The Initial Developer of the Original Code is  Cisco Systems, Inc.
16// Portions created by the Initial Developer are
17// Copyright (C) 2006 Cisco Systems, Inc.  All Rights Reserved.
18//
19// Contributor(s):
20//
21// END LICENSE BLOCK
22
23package com.parctechnologies.eclipse.visualisation.viewers;
24
25import com.parctechnologies.eclipse.*;
26import com.parctechnologies.eclipse.visualisation.*;
27
28import java.awt.Rectangle;
29import java.awt.Shape;
30import java.awt.geom.*;
31import java.awt.Color;
32import java.awt.Component;
33import java.awt.Dimension;
34import java.awt.Graphics;
35import java.awt.Graphics2D;
36import java.util.*;
37import java.awt.event.ActionEvent;
38import javax.swing.*;
39import javax.swing.table.*;
40import att.grappa.*;
41
42
43/**
44 * Display a task in a gantt viewer
45 **/
46public class ChartBarViewletType extends BoundsViewletType {
47
48  /** The factor by which to stretch the displayy in the x direction **/
49  double xScale = 1.0;
50
51  /** The factor by which to stretch the displayy in the y direction **/
52  double yScale = 1.0;
53
54  /** defualt line color **/
55  final Color DEFAULT_COLOR = Color.blue;
56
57  /** The color to use when drawing tasks **/
58  Color color;
59
60  public ChartBarViewletType(String changeable) {
61    super(changeable);
62  }
63
64  public ViewletData build()
65  {
66    return new Data();
67  }
68
69  public String getDescription()
70  {
71    return("ChartBar viewlet");
72  }
73
74
75  void fixBounds(ViewletDataStore store) {
76    double max = 1.0;
77    // find largest max
78    for(Iterator it = store.getEntireViewletRange().iterator();
79        it.hasNext(); ) {
80      java.util.List index = (java.util.List)it.next();
81      Data data = (Data)store.getViewletDataAt(index);
82      if (data.absoluteMax > max) {
83        max = data.absoluteMax;
84      }
85    }
86    // set all absolute min to 0.0 and max to largest max
87    for(Iterator it = store.getEntireViewletRange().iterator();
88        it.hasNext(); ) {
89      java.util.List index = (java.util.List)it.next();
90      Data data = (Data)store.getViewletDataAt(index);
91      data.absoluteMin = 0.0;
92      data.absoluteMax = max;
93      store.setViewletDataAt(index,data);
94    }
95  }
96
97  public void startBuild(Viewer viewer,
98                         ViewletDataStore store,
99                         ViewletRange range,
100                         List results) {
101    super.startBuild(viewer, store, range, results);
102    fixBounds(store);
103  }
104
105  public Class getCustomRendererClass() {
106    return BarRenderer.class;
107    //return Renderer.class;
108    //return PointRenderer.class;
109  }
110
111  public void setXScale(double xScale) {
112    this.xScale = xScale;
113  }
114
115  public void setYScale(double yScale) {
116    this.yScale = yScale;
117  }
118
119  public void setFillColor(Color color) {
120    this.color = color;
121  }
122
123  /** Calculate a unique index for each index ("index") with a store
124   *  of size "size"
125   **/
126  protected int calcIndex(List size, List index) {
127    int mult = 1;
128    int x = 0;
129    for(int i = 0; i < size.size(); i++) {
130      Integer pitch = (Integer)(size.get(i));
131      Integer offset = (Integer)(index.get(i));
132      x += offset.intValue() * mult;
133      mult *= pitch.intValue()+1;
134    }
135    return x;
136  }
137
138  public void customizeElement(ViewletDataStore store,
139                               java.util.List index,
140                               Element element) {
141    if (DebuggingSupport.logMessages) {
142      DebuggingSupport.logMessage(this,"ChartBar Viewlet customize, element="+element);
143    }
144    if (element==null) {
145      return;
146    }
147    Data data = (Data)store.getViewletDataAt(index);
148    data.vertical = true;
149    List size = store.getSize();
150    int xIndex = calcIndex(size,index);
151
152    // set the custom renderer
153    double width=(1)*xScale / GrappaConstants.PointsPerInch;
154    double height=(data.absoluteMax-data.absoluteMin)*yScale / GrappaConstants.PointsPerInch;
155
156    double x = ((double)xIndex + 0.5)*xScale;
157    double y = -(((data.absoluteMax-data.absoluteMin)*yScale) / 2);
158    element.setAttribute("pos",x+","+y);
159    element.setAttribute("width",""+width);
160    element.setAttribute("height",""+height);
161    element.getGrappaNexus().updateShape();
162    if (DebuggingSupport.logMessages) {
163      DebuggingSupport.logMessage(this,"data="+data+" pos="+x+","+y+" width="+width+" height="+height);
164      DebuggingSupport.logMessage(this,"element.getAttribute(width)="+element.getAttribute("width"));
165      DebuggingSupport.logMessage(this,"element.getAttribute(height)="+element.getAttribute("height"));
166    }
167    element.setAttribute("shape",new Integer(Grappa.CUSTOM_SHAPE));
168    element.setAttribute(Grappa.CUSTOM_ATTR,getCustomRendererClass().getName());
169
170    // set background color
171    Color backColor = (color==null?DEFAULT_COLOR:color);
172    element.setAttribute("style", "filled");
173    if (data.getHoldsOnUpdates()) {
174      element.setAttribute("color", backColor.darker());
175    } else {
176      element.setAttribute("color", backColor);
177    }
178    // force shape update
179    element.object = data;
180    element.setAttribute("label","");
181    element.getGrappaNexus().updateText();
182    element.getGrappaNexus().updateShape();
183  }
184
185  /**
186   * Return a collection of actions which can be applied to viewlets
187   * in this table
188   */
189  public Collection getActions(ViewletDataStore store,
190                               ViewletRange range) {
191    Collection ll = new LinkedList();
192    if ((range != null) & (!range.isEmpty())) {
193      // Add new actions here
194      ll.add((new ToggleHoldAction()).createCompoundAction(store, range));
195    }
196    if ((range != null) & (range.size()==1)) {
197      java.util.List index = (java.util.List)(range.iterator().next());
198      // Add new actions here which apply only to single viewlets
199      ll.add(new DisplayBoundsInDetailAction(store, index));
200    }
201    return ll;
202  }
203
204  /**
205   * For the given index, return the smallest pertinent value
206   **/
207  public double getMin(ViewletDataStore store, List index) {
208    return ((Data)(store.getViewletDataAt(index))).min;
209  }
210
211  /**
212   * For the given index, return the largest pertinent value
213   **/
214  public double getMax(ViewletDataStore store, List index) {
215    return ((Data)(store.getViewletDataAt(index))).max;
216  }
217
218
219
220  public static class Data extends BoundsViewletType.Data {
221    public Data() {
222      super();
223    }
224    public String toString() {
225      return Double.toString(max);
226    }
227  }
228
229  public static class BarRenderer extends BoundsViewletType.Renderer {
230    public BarRenderer(Element element,
231                       double x, double y, double w, double h) {
232      super(element, x, y, w, h);
233      if (DebuggingSupport.logMessages) {
234        DebuggingSupport.logMessage(this,"ChartBar renderer constructed for element "+element);
235      }
236    }
237
238    public void configure(Rectangle2D bounds,
239                          double absoluteMin, double absoluteMax,
240                          double initialMin, double initialMax,
241                          double min, double max, boolean vertical) {
242      // draw a "box and stick" diagram within the specified bounds
243      //
244      // G  +--------+                 --+
245      //    |        |                   |
246      // H  |        +-------+
247      //    |                |
248      // I  |                |
249      //    |                |
250      // J  |        +-------+
251      //    |        |                   |
252      // K  +--------+                 --+
253      //    A        C       D           F
254      //
255      //Rectangle2D bounds = getBounds2D();
256      float A,B,C,D,E,F,G,H,I,I1,I2,J,K;
257      if (vertical) {
258        F = (float)bounds.getMinY();
259        A = (float)bounds.getMaxY();
260      } else {
261        A = (float)bounds.getMinX();
262        F = (float)bounds.getMaxX();
263      }
264      // remove potential for divide by zero
265      if (absoluteMax == absoluteMin) {
266        absoluteMax++;
267      }
268      // calculate scale for drawing
269      float scaleX = (F-A) / (float)(absoluteMax - absoluteMin);
270      B = A + (float)initialMin * scaleX;
271      C = A + (float)min * scaleX;
272      D = A + (float)max * scaleX;
273      E = A + (float)initialMax * scaleX;
274
275      if (vertical) {
276        G = (float)bounds.getMinX();
277        K = (float)bounds.getMaxX();
278      } else {
279        G = (float)bounds.getMinY();
280        K = (float)bounds.getMaxY();
281      }
282      float sixteenth = (K-G)/16;
283      I = G+8*sixteenth;
284
285      H  = I - 4*sixteenth;
286      I1 = I - 1*sixteenth;
287      I2 = I + 1*sixteenth;
288      J  = I + 4*sixteenth;
289
290      // draw outline
291      float vertices[][];
292
293      if (vertical) {
294        float vert[][] = {{G,A},{G,C},{H,C},{H,D},
295                          {J,D},{J,C},{K,C},{K,A}};
296        vertices = vert;
297      } else {
298        float horiz[][] = {{A,G},{C,G},{C,H},{D,H},
299                           {D,J},{C,J},{C,K},{A,K}};
300        vertices = horiz;
301      }
302      path.moveTo(vertices[0][0], vertices[0][1]);
303      for(int i = 1; i < vertices.length; i++) {
304        if (DebuggingSupport.logMessages) {
305          DebuggingSupport.logMessage(this,"Bounds point "+i+
306                                      " x="+vertices[i][0]+
307                                      " y="+vertices[i][1]);
308        }
309        path.lineTo(vertices[i][0], vertices[i][1]);
310      }
311      path.closePath();
312    }
313  }
314
315  public static class PointRenderer extends BoundsViewletType.Renderer {
316    public PointRenderer(Element element,
317                       double x, double y, double w, double h) {
318      super(element, x, y, w, h);
319      if (DebuggingSupport.logMessages) {
320        DebuggingSupport.logMessage(this,"ChartBar point renderer constructed for element "+element);
321      }
322    }
323
324    public void configure(Rectangle2D bounds,
325                          double absoluteMin, double absoluteMax,
326                          double initialMin, double initialMax,
327                          double min, double max, boolean vertical) {
328      // draw a small box from min to max
329      //
330      // G  +--                        --+
331      //    |                            |
332      // H           +-------+
333      //             |       |
334      // I           |       |
335      //             |       |
336      // J           +-------+
337      //    |                            |
338      // K  +--                        --+
339      //    A        C       D           F
340      //
341      float A,B,C,D,E,F,G,H,I,I1,I2,J,K;
342      if (vertical) {
343        F = (float)bounds.getMinY();
344        A = (float)bounds.getMaxY();
345      } else {
346        A = (float)bounds.getMinX();
347        F = (float)bounds.getMaxX();
348      }
349      // remove potential for divide by zero
350      if (absoluteMax == absoluteMin) {
351        absoluteMax++;
352      }
353      // calculate scale for drawing
354      float scaleX = (F-A) / (float)(absoluteMax - absoluteMin);
355      C = A + (float)min * scaleX;
356      D = A + (float)max * scaleX;
357
358      if (vertical) {
359        G = (float)bounds.getMinX();
360        K = (float)bounds.getMaxX();
361      } else {
362        G = (float)bounds.getMinY();
363        K = (float)bounds.getMaxY();
364      }
365      float sixteenth = (K-G)/16;
366      I = G+8*sixteenth;
367
368      H  = I - 4*sixteenth;
369      J  = I + 4*sixteenth;
370
371      // draw outline
372      float vertices[][];
373
374      if (vertical) {
375        float vert[][] = {{H,C},{H,D},{J,D},{J,C}};
376        vertices = vert;
377      } else {
378        float horiz[][] = {{C,H},{D,H},{D,J},{C,J}};
379        vertices = horiz;
380      }
381      path.moveTo(vertices[0][0], vertices[0][1]);
382      for(int i = 1; i < vertices.length; i++) {
383        if (DebuggingSupport.logMessages) {
384          DebuggingSupport.logMessage(this,"Bounds point "+i+
385                                      " x="+vertices[i][0]+
386                                      " y="+vertices[i][1]);
387        }
388        path.lineTo(vertices[i][0], vertices[i][1]);
389      }
390      path.closePath();
391    }
392  }
393}
394
395
396
397
398