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