1:
49:
50: package ;
51:
52: import ;
53: import ;
54: import ;
55:
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67:
68:
78: public class CyclicXYItemRenderer extends StandardXYItemRenderer
79: implements Serializable {
80:
81:
82: private static final long serialVersionUID = 4035912243303764892L;
83:
84:
87: public CyclicXYItemRenderer() {
88: super();
89: }
90:
91:
96: public CyclicXYItemRenderer(int type) {
97: super(type);
98: }
99:
100:
106: public CyclicXYItemRenderer(int type, XYToolTipGenerator labelGenerator) {
107: super(type, labelGenerator);
108: }
109:
110:
117: public CyclicXYItemRenderer(int type,
118: XYToolTipGenerator labelGenerator,
119: XYURLGenerator urlGenerator) {
120: super(type, labelGenerator, urlGenerator);
121: }
122:
123:
124:
145: public void drawItem(Graphics2D g2,
146: XYItemRendererState state,
147: Rectangle2D dataArea,
148: PlotRenderingInfo info,
149: XYPlot plot,
150: ValueAxis domainAxis,
151: ValueAxis rangeAxis,
152: XYDataset dataset,
153: int series,
154: int item,
155: CrosshairState crosshairState,
156: int pass) {
157:
158: if ((!getPlotLines()) || ((!(domainAxis instanceof CyclicNumberAxis))
159: && (!(rangeAxis instanceof CyclicNumberAxis))) || (item <= 0)) {
160: super.drawItem(g2, state, dataArea, info, plot, domainAxis,
161: rangeAxis, dataset, series, item, crosshairState, pass);
162: return;
163: }
164:
165:
166: double xn = dataset.getXValue(series, item - 1);
167: double yn = dataset.getYValue(series, item - 1);
168:
169: if (Double.isNaN(yn)) {
170: super.drawItem(g2, state, dataArea, info, plot, domainAxis,
171: rangeAxis, dataset, series, item, crosshairState, pass);
172: return;
173: }
174: double[] x = new double[2];
175: double[] y = new double[2];
176: x[0] = xn;
177: y[0] = yn;
178:
179:
180: xn = dataset.getXValue(series, item);
181: yn = dataset.getYValue(series, item);
182:
183: if (Double.isNaN(yn)) {
184: return;
185: }
186: x[1] = xn;
187: y[1] = yn;
188:
189:
190: double xcycleBound = Double.NaN;
191: double ycycleBound = Double.NaN;
192: boolean xBoundMapping = false, yBoundMapping = false;
193: CyclicNumberAxis cnax = null, cnay = null;
194:
195: if (domainAxis instanceof CyclicNumberAxis) {
196: cnax = (CyclicNumberAxis) domainAxis;
197: xcycleBound = cnax.getCycleBound();
198: xBoundMapping = cnax.isBoundMappedToLastCycle();
199:
200:
201:
202: if ((x[0] != x[1])
203: && ((xcycleBound >= x[0])
204: && (xcycleBound <= x[1])
205: || (xcycleBound >= x[1])
206: && (xcycleBound <= x[0]))) {
207: double[] nx = new double[3];
208: double[] ny = new double[3];
209: nx[0] = x[0]; nx[2] = x[1]; ny[0] = y[0]; ny[2] = y[1];
210: nx[1] = xcycleBound;
211: ny[1] = (y[1] - y[0]) * (xcycleBound - x[0])
212: / (x[1] - x[0]) + y[0];
213: x = nx; y = ny;
214: }
215: }
216:
217: if (rangeAxis instanceof CyclicNumberAxis) {
218: cnay = (CyclicNumberAxis) rangeAxis;
219: ycycleBound = cnay.getCycleBound();
220: yBoundMapping = cnay.isBoundMappedToLastCycle();
221:
222:
223: if ((y[0] != y[1]) && ((ycycleBound >= y[0])
224: && (ycycleBound <= y[1])
225: || (ycycleBound >= y[1]) && (ycycleBound <= y[0]))) {
226: double[] nx = new double[x.length + 1];
227: double[] ny = new double[y.length + 1];
228: nx[0] = x[0]; nx[2] = x[1]; ny[0] = y[0]; ny[2] = y[1];
229: ny[1] = ycycleBound;
230: nx[1] = (x[1] - x[0]) * (ycycleBound - y[0])
231: / (y[1] - y[0]) + x[0];
232: if (x.length == 3) {
233: nx[3] = x[2]; ny[3] = y[2];
234: }
235: x = nx; y = ny;
236: }
237: else if ((x.length == 3) && (y[1] != y[2]) && ((ycycleBound >= y[1])
238: && (ycycleBound <= y[2])
239: || (ycycleBound >= y[2]) && (ycycleBound <= y[1]))) {
240: double[] nx = new double[4];
241: double[] ny = new double[4];
242: nx[0] = x[0]; nx[1] = x[1]; nx[3] = x[2];
243: ny[0] = y[0]; ny[1] = y[1]; ny[3] = y[2];
244: ny[2] = ycycleBound;
245: nx[2] = (x[2] - x[1]) * (ycycleBound - y[1])
246: / (y[2] - y[1]) + x[1];
247: x = nx; y = ny;
248: }
249: }
250:
251:
252: if (x.length == 2) {
253: super.drawItem(g2, state, dataArea, info, plot, domainAxis,
254: rangeAxis, dataset, series, item, crosshairState, pass);
255: return;
256: }
257:
258: OverwriteDataSet newset = new OverwriteDataSet(x, y, dataset);
259:
260: if (cnax != null) {
261: if (xcycleBound == x[0]) {
262: cnax.setBoundMappedToLastCycle(x[1] <= xcycleBound);
263: }
264: if (xcycleBound == x[1]) {
265: cnax.setBoundMappedToLastCycle(x[0] <= xcycleBound);
266: }
267: }
268: if (cnay != null) {
269: if (ycycleBound == y[0]) {
270: cnay.setBoundMappedToLastCycle(y[1] <= ycycleBound);
271: }
272: if (ycycleBound == y[1]) {
273: cnay.setBoundMappedToLastCycle(y[0] <= ycycleBound);
274: }
275: }
276: super.drawItem(
277: g2, state, dataArea, info, plot, domainAxis, rangeAxis,
278: newset, series, 1, crosshairState, pass
279: );
280:
281: if (cnax != null) {
282: if (xcycleBound == x[1]) {
283: cnax.setBoundMappedToLastCycle(x[2] <= xcycleBound);
284: }
285: if (xcycleBound == x[2]) {
286: cnax.setBoundMappedToLastCycle(x[1] <= xcycleBound);
287: }
288: }
289: if (cnay != null) {
290: if (ycycleBound == y[1]) {
291: cnay.setBoundMappedToLastCycle(y[2] <= ycycleBound);
292: }
293: if (ycycleBound == y[2]) {
294: cnay.setBoundMappedToLastCycle(y[1] <= ycycleBound);
295: }
296: }
297: super.drawItem(g2, state, dataArea, info, plot, domainAxis, rangeAxis,
298: newset, series, 2, crosshairState, pass);
299:
300: if (x.length == 4) {
301: if (cnax != null) {
302: if (xcycleBound == x[2]) {
303: cnax.setBoundMappedToLastCycle(x[3] <= xcycleBound);
304: }
305: if (xcycleBound == x[3]) {
306: cnax.setBoundMappedToLastCycle(x[2] <= xcycleBound);
307: }
308: }
309: if (cnay != null) {
310: if (ycycleBound == y[2]) {
311: cnay.setBoundMappedToLastCycle(y[3] <= ycycleBound);
312: }
313: if (ycycleBound == y[3]) {
314: cnay.setBoundMappedToLastCycle(y[2] <= ycycleBound);
315: }
316: }
317: super.drawItem(g2, state, dataArea, info, plot, domainAxis,
318: rangeAxis, newset, series, 3, crosshairState, pass);
319: }
320:
321: if (cnax != null) {
322: cnax.setBoundMappedToLastCycle(xBoundMapping);
323: }
324: if (cnay != null) {
325: cnay.setBoundMappedToLastCycle(yBoundMapping);
326: }
327: }
328:
329:
332: protected static class OverwriteDataSet implements XYDataset {
333:
334:
335: protected XYDataset delegateSet;
336:
337:
338: Double[] x, y;
339:
340:
347: public OverwriteDataSet(double [] x, double[] y,
348: XYDataset delegateSet) {
349: this.delegateSet = delegateSet;
350: this.x = new Double[x.length]; this.y = new Double[y.length];
351: for (int i = 0; i < x.length; ++i) {
352: this.x[i] = new Double(x[i]);
353: this.y[i] = new Double(y[i]);
354: }
355: }
356:
357:
362: public DomainOrder getDomainOrder() {
363: return DomainOrder.NONE;
364: }
365:
366:
373: public int getItemCount(int series) {
374: return this.x.length;
375: }
376:
377:
385: public Number getX(int series, int item) {
386: return this.x[item];
387: }
388:
389:
398: public double getXValue(int series, int item) {
399: double result = Double.NaN;
400: Number x = getX(series, item);
401: if (x != null) {
402: result = x.doubleValue();
403: }
404: return result;
405: }
406:
407:
415: public Number getY(int series, int item) {
416: return this.y[item];
417: }
418:
419:
428: public double getYValue(int series, int item) {
429: double result = Double.NaN;
430: Number y = getY(series, item);
431: if (y != null) {
432: result = y.doubleValue();
433: }
434: return result;
435: }
436:
437:
442: public int getSeriesCount() {
443: return this.delegateSet.getSeriesCount();
444: }
445:
446:
453: public Comparable getSeriesKey(int series) {
454: return this.delegateSet.getSeriesKey(series);
455: }
456:
457:
464: public int indexOf(Comparable seriesName) {
465: return this.delegateSet.indexOf(seriesName);
466: }
467:
468:
473: public void addChangeListener(DatasetChangeListener listener) {
474:
475: }
476:
477:
482: public void removeChangeListener(DatasetChangeListener listener) {
483:
484: }
485:
486:
491: public DatasetGroup getGroup() {
492:
493: return this.delegateSet.getGroup();
494: }
495:
496:
501: public void setGroup(DatasetGroup group) {
502:
503: }
504:
505: }
506:
507: }
508:
509: