1:
45:
46: package ;
47:
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60:
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69:
70:
73: public class WaferMapPlot extends Plot implements RendererChangeListener,
74: Cloneable,
75: Serializable {
76:
77:
78: private static final long serialVersionUID = 4668320403707308155L;
79:
80:
81: public static final Stroke DEFAULT_GRIDLINE_STROKE = new BasicStroke(0.5f,
82: BasicStroke.CAP_BUTT,
83: BasicStroke.JOIN_BEVEL,
84: 0.0f,
85: new float[] {2.0f, 2.0f},
86: 0.0f);
87:
88:
89: public static final Paint DEFAULT_GRIDLINE_PAINT = Color.lightGray;
90:
91:
92: public static final boolean DEFAULT_CROSSHAIR_VISIBLE = false;
93:
94:
95: public static final Stroke DEFAULT_CROSSHAIR_STROKE
96: = DEFAULT_GRIDLINE_STROKE;
97:
98:
99: public static final Paint DEFAULT_CROSSHAIR_PAINT = Color.blue;
100:
101:
102: protected static ResourceBundle localizationResources =
103: ResourceBundle.getBundle("org.jfree.chart.plot.LocalizationBundle");
104:
105:
109: private PlotOrientation orientation;
110:
111:
112: private WaferMapDataset dataset;
113:
114:
118: private WaferMapRenderer renderer;
119:
120:
123: public WaferMapPlot() {
124: this(null);
125: }
126:
127:
132: public WaferMapPlot(WaferMapDataset dataset) {
133: this(dataset, null);
134: }
135:
136:
142: public WaferMapPlot(WaferMapDataset dataset, WaferMapRenderer renderer) {
143:
144: super();
145:
146: this.orientation = PlotOrientation.VERTICAL;
147:
148: this.dataset = dataset;
149: if (dataset != null) {
150: dataset.addChangeListener(this);
151: }
152:
153: this.renderer = renderer;
154: if (renderer != null) {
155: renderer.setPlot(this);
156: renderer.addChangeListener(this);
157: }
158:
159: }
160:
161:
166: public String getPlotType() {
167: return ("WMAP_Plot");
168: }
169:
170:
175: public WaferMapDataset getDataset() {
176: return this.dataset;
177: }
178:
179:
185: public void setDataset(WaferMapDataset dataset) {
186:
187:
188: if (this.dataset != null) {
189: this.dataset.removeChangeListener(this);
190: }
191:
192:
193: this.dataset = dataset;
194: if (dataset != null) {
195: setDatasetGroup(dataset.getGroup());
196: dataset.addChangeListener(this);
197: }
198:
199:
200: datasetChanged(new DatasetChangeEvent(this, dataset));
201: }
202:
203:
210: public void setRenderer(WaferMapRenderer renderer) {
211: if (this.renderer != null) {
212: this.renderer.removeChangeListener(this);
213: }
214: this.renderer = renderer;
215: if (renderer != null) {
216: renderer.setPlot(this);
217: }
218: fireChangeEvent();
219: }
220:
221:
230: public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor,
231: PlotState state,
232: PlotRenderingInfo info) {
233:
234:
235: boolean b1 = (area.getWidth() <= MINIMUM_WIDTH_TO_DRAW);
236: boolean b2 = (area.getHeight() <= MINIMUM_HEIGHT_TO_DRAW);
237: if (b1 || b2) {
238: return;
239: }
240:
241:
242: if (info != null) {
243: info.setPlotArea(area);
244: }
245:
246:
247: RectangleInsets insets = getInsets();
248: insets.trim(area);
249:
250: drawChipGrid(g2, area);
251: drawWaferEdge(g2, area);
252:
253: }
254:
255:
261: protected void drawChipGrid(Graphics2D g2, Rectangle2D plotArea) {
262:
263: Shape savedClip = g2.getClip();
264: g2.setClip(getWaferEdge(plotArea));
265: Rectangle2D chip = new Rectangle2D.Double();
266: int xchips = 35;
267: int ychips = 20;
268: double space = 1d;
269: if (this.dataset != null) {
270: xchips = this.dataset.getMaxChipX() + 2;
271: ychips = this.dataset.getMaxChipY() + 2;
272: space = this.dataset.getChipSpace();
273: }
274: double startX = plotArea.getX();
275: double startY = plotArea.getY();
276: double chipWidth = 1d;
277: double chipHeight = 1d;
278: if (plotArea.getWidth() != plotArea.getHeight()) {
279: double major = 0d;
280: double minor = 0d;
281: if (plotArea.getWidth() > plotArea.getHeight()) {
282: major = plotArea.getWidth();
283: minor = plotArea.getHeight();
284: }
285: else {
286: major = plotArea.getHeight();
287: minor = plotArea.getWidth();
288: }
289:
290: if (plotArea.getWidth() == minor) {
291: startY += (major - minor) / 2;
292: chipWidth = (plotArea.getWidth() - (space * xchips - 1))
293: / xchips;
294: chipHeight = (plotArea.getWidth() - (space * ychips - 1))
295: / ychips;
296: }
297: else {
298: startX += (major - minor) / 2;
299: chipWidth = (plotArea.getHeight() - (space * xchips - 1))
300: / xchips;
301: chipHeight = (plotArea.getHeight() - (space * ychips - 1))
302: / ychips;
303: }
304: }
305:
306: for (int x = 1; x <= xchips; x++) {
307: double upperLeftX = (startX - chipWidth) + (chipWidth * x)
308: + (space * (x - 1));
309: for (int y = 1; y <= ychips; y++) {
310: double upperLeftY = (startY - chipHeight) + (chipHeight * y)
311: + (space * (y - 1));
312: chip.setFrame(upperLeftX, upperLeftY, chipWidth, chipHeight);
313: g2.setColor(Color.white);
314: if (this.dataset.getChipValue(x - 1, ychips - y - 1) != null) {
315: g2.setPaint(
316: this.renderer.getChipColor(
317: this.dataset.getChipValue(x - 1, ychips - y - 1)
318: )
319: );
320: }
321: g2.fill(chip);
322: g2.setColor(Color.lightGray);
323: g2.draw(chip);
324: }
325: }
326: g2.setClip(savedClip);
327: }
328:
329:
336: protected Ellipse2D getWaferEdge(Rectangle2D plotArea) {
337: Ellipse2D edge = new Ellipse2D.Double();
338: double diameter = plotArea.getWidth();
339: double upperLeftX = plotArea.getX();
340: double upperLeftY = plotArea.getY();
341:
342: if (plotArea.getWidth() != plotArea.getHeight()) {
343: double major = 0d;
344: double minor = 0d;
345: if (plotArea.getWidth() > plotArea.getHeight()) {
346: major = plotArea.getWidth();
347: minor = plotArea.getHeight();
348: }
349: else {
350: major = plotArea.getHeight();
351: minor = plotArea.getWidth();
352: }
353:
354: diameter = minor;
355:
356: if (plotArea.getWidth() == minor) {
357: upperLeftY = plotArea.getY() + (major - minor) / 2;
358: }
359: else {
360: upperLeftX = plotArea.getX() + (major - minor) / 2;
361: }
362: }
363: edge.setFrame(upperLeftX, upperLeftY, diameter, diameter);
364: return edge;
365: }
366:
367:
373: protected void drawWaferEdge(Graphics2D g2, Rectangle2D plotArea) {
374:
375: Ellipse2D waferEdge = getWaferEdge(plotArea);
376: g2.setColor(Color.black);
377: g2.draw(waferEdge);
378:
379:
380:
381: Arc2D notch = null;
382: Rectangle2D waferFrame = waferEdge.getFrame();
383: double notchDiameter = waferFrame.getWidth() * 0.04;
384: if (this.orientation == PlotOrientation.HORIZONTAL) {
385: Rectangle2D notchFrame =
386: new Rectangle2D.Double(
387: waferFrame.getX() + waferFrame.getWidth()
388: - (notchDiameter / 2), waferFrame.getY()
389: + (waferFrame.getHeight() / 2) - (notchDiameter / 2),
390: notchDiameter, notchDiameter
391: );
392: notch = new Arc2D.Double(notchFrame, 90d, 180d, Arc2D.OPEN);
393: }
394: else {
395: Rectangle2D notchFrame =
396: new Rectangle2D.Double(
397: waferFrame.getX() + (waferFrame.getWidth() / 2)
398: - (notchDiameter / 2), waferFrame.getY()
399: + waferFrame.getHeight() - (notchDiameter / 2),
400: notchDiameter, notchDiameter
401: );
402: notch = new Arc2D.Double(notchFrame, 0d, 180d, Arc2D.OPEN);
403: }
404: g2.setColor(Color.white);
405: g2.fill(notch);
406: g2.setColor(Color.black);
407: g2.draw(notch);
408:
409: }
410:
411:
416: public LegendItemCollection getLegendItems() {
417: return this.renderer.getLegendCollection();
418: }
419:
420:
425: public void rendererChanged(RendererChangeEvent event) {
426: fireChangeEvent();
427: }
428:
429: }