001: /**
002: * Chart2D, a java library for drawing two dimensional charts.
003: * Copyright (C) 2001 Jason J. Simas
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * The author of this library may be contacted at:
019: * E-mail: jjsimas@users.sourceforge.net
020: * Street Address: J J Simas, 887 Tico Road, Ojai, CA 93023-3555 USA
021: */package net.sourceforge.chart2d;
022:
023: import java.awt.*;
024: import java.util.*;
025:
026: /**
027: * A graph chart with the data category lables located along the botton of the
028: * graph chart. A graph chart is a bar chart, a line chart, a scatter plot
029: * chart or any combination (i.e. any chart where data is represented in a
030: * cartesian coordinate system). This class manages the xAxis, yAxis, legend,
031: * and graph areas of the chart. This class cannot be added to a content pane;
032: * if that is desired, use LBChart2D. This class is for custom painting, such
033: * as custom painting a JComponent (i.e. overriding the
034: * paintComponent (Graphics g) method). For customizing the LBChart2D class
035: * to use with your data set and needs, you'll have to use this class
036: * LBChartArea. You'll have to pass it your data sets in an array at least.
037: * You'll also want to set the title of this class, and also get its
038: * xAxis and other parts for setting their titles, labels, and so on.
039: */
040: final class LBChartArea extends GraphChartArea {
041:
042: private Rectangle maxBounds;
043: private Rectangle minBounds;
044: private Dimension prefSize;
045: private XAxisArea xAxis;
046: private YAxisArea yAxis;
047: private LegendArea legend;
048: private boolean needsUpdate;
049:
050: /**
051: * Creates LBChartArea with ChartArea's defaults.
052: */
053: LBChartArea() {
054:
055: xAxis = getXAxis();
056: yAxis = getYAxis();
057: legend = getLegend();
058: minBounds = new Rectangle();
059: needsUpdate = true;
060: }
061:
062: /**
063: * Returns the minimum size that the chart would need if it was to be redrawn,
064: * the "preferred" size. The preferred size is the minimum size which would
065: * need to be set as the maxmodel size of the chart, if the chart was to be
066: * redrawn (assuming magnification is disabled).
067: * @param g2D The graphics context for calculations and painting.
068: * @return The size of the minimum maxmodel for a redraw.
069: */
070: final Dimension getPrefSize(Graphics2D g2D) {
071:
072: updateLBChartArea(g2D);
073: return prefSize;
074: }
075:
076: /**
077: * Indicates whether some property of this class has changed.
078: * @return True if some property has changed.
079: */
080: final boolean getLBChartAreaNeedsUpdate() {
081:
082: if (needsUpdate || getGraphChartAreaNeedsUpdate())
083: return true;
084: Vector graphVector = getGraphVector();
085: for (int i = 0; i < graphVector.size(); ++i) {
086: if (((LBGraphArea) graphVector.get(i))
087: .getLBGraphAreaNeedsUpdate())
088: return true;
089: }
090: return false;
091: }
092:
093: /**
094: * Resets the model for this class. The model is used for shrinking and
095: * growing of its components based on the maximum size of this class. If this
096: * method is called, then the next time the maximum size is set, this classes
097: * model maximum size will be made equal to the new maximum size. Effectively
098: * what this does is ensure that whenever this objects maximum size is equal
099: * to the one given, then all of the components will take on their default
100: * model sizes. Note: This is only useful when auto model max sizing is
101: * disabled.
102: * @param reset True causes the max model to be reset upon next max sizing.
103: */
104: final void resetLBChartAreaModel(boolean reset) {
105:
106: needsUpdate = true;
107: resetGraphChartAreaModel(reset);
108: Vector graphVector = this .getGraphVector();
109: for (int i = 0; i < graphVector.size(); ++i) {
110: ((LBGraphArea) graphVector.get(i))
111: .resetLBGraphAreaModel(reset);
112: }
113: }
114:
115: /**
116: * Updates this parent's variables, and this' variables.
117: * @param g2D The graphics context to use for calculations.
118: */
119: final void updateLBChartArea(Graphics2D g2D) {
120:
121: if (getLBChartAreaNeedsUpdate()) {
122:
123: updateGraphChartArea(g2D);
124: update(g2D);
125:
126: Vector graphVector = getGraphVector();
127: for (int i = 0; i < graphVector.size(); ++i) {
128: ((LBGraphArea) graphVector.get(i)).updateLBGraphArea();
129: }
130:
131: Vector warningRegions = getWarningRegions();
132: for (int i = 0; i < warningRegions.size(); ++i) {
133: ((WarningRegion) warningRegions.get(i))
134: .updateWarningRegion();
135: }
136:
137: legend.updateLegendArea(g2D);
138: xAxis.updateXAxisArea(g2D);
139: yAxis.updateYAxisArea(g2D);
140: }
141: needsUpdate = false;
142: }
143:
144: /**
145: * Paints all the components of this class. First all variables are updated.
146: * @param g2D The graphics context for calculations and painting.
147: */
148: final void paintComponent(Graphics2D g2D) {
149:
150: updateLBChartArea(g2D);
151: super .paintComponent(g2D);
152:
153: Vector graphVector = getGraphVector();
154: for (int i = graphVector.size() - 1; i >= 0; --i) {
155: ((LBGraphArea) graphVector.get(i)).paintComponent(g2D);
156: }
157: }
158:
159: private void update(Graphics2D g2D) {
160:
161: Vector graphVector = getGraphVector();
162: Vector datasetVector = getDatasetVector();
163:
164: int colorOffset = 0;
165: for (int i = 0; i < graphVector.size(); ++i) {
166:
167: int datasetsLength = ((Dataset) datasetVector.get(i))
168: .getNumSets();
169: Color[] graphColors = getDatasetColors(colorOffset,
170: colorOffset + datasetsLength);
171:
172: LBGraphArea this Graph = (LBGraphArea) graphVector.get(i);
173: this Graph.setBarColors(graphColors);
174: this Graph.setDotColors(graphColors);
175: this Graph.setLineColors(graphColors);
176: this Graph.setWarningRegions(getWarningRegions());
177: this Graph
178: .setComponentsColoringByCat(getGraphComponentsColoringByCat());
179: this Graph
180: .setComponentsColorsByCat(getGraphComponentsColorsByCat());
181: colorOffset += datasetsLength;
182: }
183:
184: float widthRatio = getRatio(WIDTH);
185: float heightRatio = getRatio(HEIGHT);
186: xAxis.setCustomRatio(WIDTH, true, widthRatio);
187: xAxis.setCustomRatio(HEIGHT, true, heightRatio);
188: yAxis.setCustomRatio(WIDTH, true, widthRatio);
189: yAxis.setCustomRatio(HEIGHT, true, heightRatio);
190: legend.setCustomRatio(WIDTH, true, widthRatio);
191: legend.setCustomRatio(HEIGHT, true, heightRatio);
192: for (int i = 0; i < graphVector.size(); ++i) {
193: ((LBGraphArea) graphVector.get(i)).setCustomRatio(WIDTH,
194: true, widthRatio);
195: ((LBGraphArea) graphVector.get(i)).setCustomRatio(HEIGHT,
196: true, heightRatio);
197: ((LBGraphArea) graphVector.get(i))
198: .setLabelsAxisTicksAlignment(xAxis
199: .getTicksAlignment());
200: }
201:
202: maxBounds = getMaxEntitledSpaceBounds(g2D);
203:
204: float xAxisToHeightRatio = getXAxisToHeightRatio();
205: float yAxisToHeightRatio = getYAxisToHeightRatio();
206: float graphToHeightRatio = getGraphToHeightRatio();
207: float legendToHeightRatio = getLegendToHeightRatio();
208:
209: float xAxisToWidthRatio = getXAxisToWidthRatio();
210: float yAxisToWidthRatio = getYAxisToWidthRatio();
211: float graphToWidthRatio = getGraphToWidthRatio();
212: float legendToWidthRatio = getLegendToWidthRatio();
213:
214: int betweenChartAndLegendGapThickness = 0;
215: int availableWidth = maxBounds.width;
216: if (getBetweenChartAndLegendGapExistence()
217: && getLegendExistence()) {
218: betweenChartAndLegendGapThickness = applyRatio(
219: getBetweenChartAndLegendGapThicknessModel(),
220: getRatio(WIDTH));
221: betweenChartAndLegendGapThickness = betweenChartAndLegendGapThickness <= availableWidth ? betweenChartAndLegendGapThickness
222: : availableWidth;
223: availableWidth -= betweenChartAndLegendGapThickness;
224: }
225:
226: int width = 0, height = 0;
227: if (getLegendExistence()) {
228: height = (int) (legendToHeightRatio * maxBounds.height);
229: width = (int) (legendToWidthRatio * availableWidth);
230: }
231: legend.setSize(MAX, new Dimension(width, height));
232:
233: VerticalTextListArea yTextList = yAxis.getTextList();
234: yTextList.setCustomSpaceMinHeight(false, 0);
235: height = (int) (yAxisToHeightRatio * maxBounds.height);
236: width = (int) (yAxisToWidthRatio * availableWidth);
237: yAxis.setSize(MAX, new Dimension(width, height));
238:
239: HorizontalTextListArea xTextList = xAxis.getTextList();
240: xTextList.setCustomSpaceMinWidth(false, 0);
241: height = (int) (xAxisToHeightRatio * maxBounds.height);
242: width = (int) (xAxisToWidthRatio * availableWidth);
243: xAxis.setSize(MAX, new Dimension(width, height));
244:
245: height = (int) (graphToHeightRatio * maxBounds.height);
246: width = (int) (graphToWidthRatio * availableWidth);
247: for (int i = 0; i < graphVector.size(); ++i) {
248: ((LBGraphArea) graphVector.get(i)).setSize(MAX,
249: new Dimension(width, height));
250: }
251:
252: xAxis.setNumTicks(xTextList.getNumBullets()); //sets here to hold intermediate calculation
253: yAxis.setNumTicks(getNumPlotAxisLabels()); //sets here too because of above case
254:
255: float greatestValue = -9999999999999999f;
256: float leastValue = 9999999999999999f;
257: for (int i = 0; i < datasetVector.size(); ++i) {
258: greatestValue = ((Dataset) datasetVector.get(i))
259: .getGreatest() > greatestValue ? ((Dataset) datasetVector
260: .get(i)).getGreatest()
261: : greatestValue;
262: leastValue = ((Dataset) datasetVector.get(i)).getLeast() < leastValue ? ((Dataset) datasetVector
263: .get(i)).getLeast()
264: : leastValue;
265: }
266:
267: greatestValue = getCustomizeGreatestValue()
268: && (getCustomGreatestValue() > greatestValue) ? getCustomGreatestValue()
269: : greatestValue;
270: leastValue = getCustomizeLeastValue()
271: && (getCustomLeastValue() < leastValue) ? getCustomLeastValue()
272: : leastValue;
273:
274: float maxValue = getGraphableToAvailableRatio() > 0 ? (greatestValue - leastValue)
275: / getGraphableToAvailableRatio()
276: : 0f;
277: float emptyValue = maxValue - (greatestValue - leastValue);
278:
279: int dataSign = GraphArea.NEG;
280: if (greatestValue > 0f && leastValue < 0f) {
281: greatestValue = greatestValue + (emptyValue / 2f);
282: leastValue = leastValue - (emptyValue / 2f);
283: float nomValue = Math.abs(greatestValue) > Math
284: .abs(leastValue) ? Math.abs(greatestValue) : Math
285: .abs(leastValue);
286: greatestValue = nomValue;
287: leastValue = -nomValue;
288: dataSign = GraphArea.MIX;
289: } else if (greatestValue >= 0f && leastValue >= 0f) {
290: greatestValue = greatestValue + emptyValue;
291: if (!getCustomizeLeastValue())
292: leastValue = 0f;
293: dataSign = GraphArea.POS;
294: } else {
295: leastValue = leastValue - emptyValue;
296: if (!getCustomizeGreatestValue())
297: greatestValue = 0f;
298: }
299:
300: int precisionNum = getLabelsPrecisionNum();
301: greatestValue = getPrecisionCeil(greatestValue, precisionNum);
302: leastValue = getPrecisionFloor(leastValue, precisionNum);
303: maxValue = greatestValue - leastValue;
304:
305: float difference = 0;
306: float label = 0;
307: if (getNumPlotAxisLabels() > 1) {
308: difference = maxValue / (getNumPlotAxisLabels() - 1);
309: label = leastValue;
310: } else {
311: label = maxValue / 2f;
312: }
313:
314: String[] labels = new String[getNumPlotAxisLabels()];
315: String lastLabel = null;
316: for (int i = getNumPlotAxisLabels() - 1; i >= 0; --i) {
317: float sign = label > 0 ? 1f : -1f;
318: if (i == getNumPlotAxisLabels() - 1 || i == 0) {
319: labels[i] = getFloatToString(
320: sign
321: * getPrecisionRound(sign * label,
322: precisionNum), precisionNum);
323: } else {
324: labels[i] = getFloatToString(label, precisionNum);
325: }
326: label += difference;
327: if (labels[i].equals(lastLabel))
328: labels[i] = "^";
329: else
330: lastLabel = labels[i];
331: }
332: yAxis.getTextList().setLabels(labels);
333:
334: int graphPrefWidth = 0;
335: for (int i = 0; i < graphVector.size(); ++i) {
336: int numSets = ((Dataset) datasetVector.get(i)).getNumSets();
337: int numCats = ((Dataset) datasetVector.get(i)).getNumCats();
338: int numCompsPerCat = ((Dataset) datasetVector.get(i))
339: .getNumItems();
340: int tempWidth = ((LBGraphArea) graphVector.get(i))
341: .getPrefSpaceWidth(numSets, numCats, numCompsPerCat);
342: graphPrefWidth = tempWidth > graphPrefWidth ? tempWidth
343: : graphPrefWidth;
344: ((LBGraphArea) graphVector.get(i)).setDataSign(dataSign);
345: }
346:
347: xTextList.setCustomSpaceMinWidth(true, graphPrefWidth);
348: xAxis.updateXAxisArea(g2D);
349: int minSpaceWidth = xAxis.getSpaceSize(MIN).width;
350:
351: yAxis.updateYAxisArea(g2D);
352: int minSpaceHeight = 0;
353: Rectangle[] yAxisTicks = yAxis.getTicks(g2D);
354: if (yAxisTicks.length > 0) {
355: minSpaceHeight = yAxisTicks[yAxisTicks.length - 1].y
356: - yAxisTicks[0].y + yAxisTicks[0].height;
357: }
358:
359: Dimension minGraphSpaceSize = new Dimension(minSpaceWidth,
360: minSpaceHeight);
361: for (int i = 0; i < graphVector.size(); ++i) {
362: ((LBGraphArea) graphVector.get(i)).setSpaceSize(MIN,
363: minGraphSpaceSize);
364: }
365:
366: LBGraphArea graphFirst = (LBGraphArea) graphVector
367: .get(graphVector.size() - 1);
368: int graphMinSizeWidth = 0;
369: int graphMinSizeHeight = 0;
370: if (graphVector.size() > 0) {
371: graphMinSizeWidth = graphFirst.getSize(MIN).width;
372: graphMinSizeHeight = graphFirst.getSize(MIN).height;
373: }
374:
375: legend.updateLegendArea(g2D);
376:
377: int width1 = yAxis.getSize(MIN).width + graphMinSizeWidth
378: + betweenChartAndLegendGapThickness
379: + legend.getSize(MIN).width;
380: int width2 = yAxis.getSize(MIN).width
381: + xAxis.getSize(MIN).width
382: + betweenChartAndLegendGapThickness
383: + legend.getSize(MIN).width;
384: width = width1 > width2 ? width1 : width2;
385:
386: int topTickY = yAxis.getTicks(g2D)[0].y;
387: int titleTopY = yAxis.getSizeLocation(MIN).y
388: + (int) ((yAxis.getSize(MIN).height - yAxis.getTitle()
389: .getSize(MIN).height) / 2f);
390: int labelTopY = yTextList.getLabels(g2D)[0]
391: .getSizeLocation(MIN).y;
392: int graphTopY = topTickY - graphFirst.getBorderThickness(TOP);
393: int topY = titleTopY < labelTopY ? titleTopY : labelTopY;
394: topY = topY < graphTopY ? topY : graphTopY;
395:
396: int bottomTickY = yAxis.getTicks(g2D)[yAxis.getTicks(g2D).length - 1].y;
397: int tickHeight = yAxis.getTicks(g2D)[0].height;
398: int graphBottomY = bottomTickY + tickHeight + //bottom graph, top x axis
399: graphFirst.getBorderThickness(BOTTOM);
400: int titleBottomY = titleTopY
401: + yAxis.getTitle().getSize(MIN).height; //title Y
402: TextArea yAxisLabelBottom = yTextList.getLabels(g2D)[yTextList
403: .getLabels(g2D).length - 1];
404: int labelBottomY = yAxisLabelBottom.getSizeLocation(MIN).y + //label Y
405: yAxisLabelBottom.getSize(MIN).height;
406: int xAxisBottomY = graphBottomY + xAxis.getSize(MIN).height; //x axis Y
407: int bottomY = titleBottomY > labelBottomY ? titleBottomY
408: : labelBottomY;
409: bottomY = bottomY > xAxisBottomY ? bottomY : xAxisBottomY;
410:
411: int height1 = legend.getSize(MIN).height;
412: int height2 = (bottomY - topY);
413: height = height1 > height2 ? height1 : height2;
414: int heightForDeficient = (labelBottomY > xAxisBottomY ? labelBottomY
415: : xAxisBottomY)
416: - (labelTopY < graphTopY ? labelTopY : graphTopY);
417:
418: if (getAutoSetLayoutRatios()) {
419:
420: yAxisToWidthRatio = width > 0 ? yAxis.getSize(MIN).width
421: / (float) width : 0f;
422: yAxisToWidthRatio = yAxisToWidthRatio < 1f ? yAxisToWidthRatio
423: : 1f;
424: xAxisToWidthRatio = width > 0 ? xAxis.getSize(MIN).width
425: / (float) width : 0f;
426: xAxisToWidthRatio = xAxisToWidthRatio < 1f ? xAxisToWidthRatio
427: : 1f;
428: graphToWidthRatio = width > 0 ? graphMinSizeWidth
429: / (float) width : 0f;
430: graphToWidthRatio = graphToWidthRatio < 1f ? graphToWidthRatio
431: : 1f;
432: if (xAxisToWidthRatio > graphToWidthRatio)
433: graphToWidthRatio = xAxisToWidthRatio;
434: else
435: xAxisToWidthRatio = graphToWidthRatio;
436:
437: yAxisToHeightRatio = height > 0 ? yAxis.getSize(MIN).height
438: / (float) height : 0f;
439: yAxisToHeightRatio = yAxisToHeightRatio < 1f ? yAxisToHeightRatio
440: : 1f;
441: xAxisToHeightRatio = height > 0 ? xAxis.getSize(MIN).height
442: / (float) height : 0f;
443: xAxisToHeightRatio = xAxisToHeightRatio < 1f ? xAxisToHeightRatio
444: : 1f;
445: graphToHeightRatio = height > 0 ? graphMinSizeHeight
446: / (float) height : 0f;
447: graphToHeightRatio = graphToHeightRatio < 1f ? graphToHeightRatio
448: : 1f;
449: if (yAxisToHeightRatio > graphToHeightRatio)
450: graphToHeightRatio = yAxisToHeightRatio;
451: else
452: yAxisToHeightRatio = graphToHeightRatio;
453:
454: if (yAxisToWidthRatio <= 0f || yAxisToHeightRatio <= 0f) {
455: yAxisToWidthRatio = yAxisToHeightRatio = 0f;
456: }
457: if (xAxisToWidthRatio <= 0f || xAxisToHeightRatio <= 0f) {
458: xAxisToWidthRatio = xAxisToHeightRatio = 0f;
459: }
460: if (graphToWidthRatio <= 0f || graphToHeightRatio <= 0f) {
461: graphToWidthRatio = graphToHeightRatio = 0f;
462: }
463: legendToWidthRatio = 1f - yAxisToWidthRatio
464: - graphToWidthRatio;
465: legendToHeightRatio = 1f;
466: if (legendToWidthRatio <= 0f || legendToHeightRatio <= 0f) {
467: legendToWidthRatio = legendToHeightRatio = 0f;
468: }
469:
470: setYAxisToWidthRatio(yAxisToWidthRatio);
471: setXAxisToWidthRatio(xAxisToWidthRatio);
472: setGraphToWidthRatio(graphToWidthRatio);
473: setLegendToWidthRatio(legendToWidthRatio);
474:
475: setYAxisToHeightRatio(yAxisToHeightRatio);
476: setXAxisToHeightRatio(xAxisToHeightRatio);
477: setGraphToHeightRatio(graphToHeightRatio);
478: setLegendToHeightRatio(legendToHeightRatio);
479:
480: setAutoSetLayoutRatios(false);
481: }
482:
483: Dimension titleSize = getTitleSize(MIN, g2D);
484: int widthForDeficient = width;
485: width = width > titleSize.width ? width : titleSize.width;
486: int prefWidth = width
487: + (getSize(MIN).width - getSpaceSize(MIN).width);
488: int prefHeight = height
489: + (getSize(MIN).height - getSpaceSize(MIN).height)
490: + titleSize.height
491: + getBetweenTitleAndSpaceGapThickness(g2D);
492: prefSize = new Dimension((int) (1.3f * prefWidth),
493: (int) (1.3f * prefHeight));
494:
495: int deficientHeight = 0;
496: int deficientWidth = 0;
497: if (getAutoSize(MIN)) {
498: deficientWidth = maxBounds.width - widthForDeficient;
499: deficientHeight = maxBounds.height - heightForDeficient;
500: } else {
501: deficientWidth = width - widthForDeficient;
502: deficientHeight = height - heightForDeficient;
503: }
504:
505: graphPrefWidth = minSpaceWidth + deficientWidth;
506: xTextList.setCustomSpaceMinWidth(true, graphPrefWidth);
507: xAxis.updateXAxisArea(g2D);
508: minSpaceWidth = xAxis.getSpaceSize(MIN).width;
509:
510: deficientHeight += (deficientHeight / getNumPlotAxisLabels());
511: int yAxisPrefHeight = yTextList.getSize(MIN).height
512: + deficientHeight;
513: yTextList.setCustomSpaceMinHeight(true, yAxisPrefHeight);
514:
515: yAxis.updateYAxisArea(g2D);
516: minSpaceHeight = 0;
517: yAxisTicks = yAxis.getTicks(g2D);
518: if (yAxisTicks.length > 0) {
519: minSpaceHeight = yAxisTicks[yAxisTicks.length - 1].y
520: - yAxisTicks[0].y + yAxisTicks[0].height;
521: }
522:
523: minGraphSpaceSize = new Dimension(minSpaceWidth, minSpaceHeight);
524: for (int i = 0; i < graphVector.size(); ++i) {
525: ((LBGraphArea) graphVector.get(i)).setSpaceSize(MIN,
526: minGraphSpaceSize);
527: }
528:
529: graphMinSizeWidth = 0;
530: graphMinSizeHeight = 0;
531: if (graphVector.size() > 0) {
532: graphMinSizeWidth = graphFirst.getSize(MIN).width;
533: graphMinSizeHeight = graphFirst.getSize(MIN).height;
534: }
535:
536: legend.updateLegendArea(g2D);
537:
538: width1 = yAxis.getSize(MIN).width + graphMinSizeWidth
539: + betweenChartAndLegendGapThickness
540: + legend.getSize(MIN).width;
541: width2 = yAxis.getSize(MIN).width + xAxis.getSize(MIN).width
542: + betweenChartAndLegendGapThickness
543: + legend.getSize(MIN).width;
544: width = width1 > width2 ? width1 : width2;
545: width = width > titleSize.width ? width : titleSize.width;
546:
547: topTickY = yAxis.getTicks(g2D)[0].y;
548: titleTopY = yAxis.getSizeLocation(MIN).y
549: + (int) ((yAxis.getSize(MIN).height - yAxis.getTitle()
550: .getSize(MIN).height) / 2f);
551: labelTopY = yTextList.getLabels(g2D)[0].getSizeLocation(MIN).y;
552: graphTopY = topTickY - graphFirst.getBorderThickness(TOP);
553: topY = titleTopY < labelTopY ? titleTopY : labelTopY;
554: topY = topY < graphTopY ? topY : graphTopY;
555:
556: bottomTickY = yAxis.getTicks(g2D)[yAxis.getTicks(g2D).length - 1].y;
557: tickHeight = yAxis.getTicks(g2D)[0].height;
558: graphBottomY = bottomTickY + tickHeight
559: + graphFirst.getBorderThickness(BOTTOM);
560: titleBottomY = titleTopY + yAxis.getTitle().getSize(MIN).height;
561: yAxisLabelBottom = yTextList.getLabels(g2D)[yTextList
562: .getLabels(g2D).length - 1];
563: labelBottomY = yAxisLabelBottom.getSizeLocation(MIN).y
564: + yAxisLabelBottom.getSize(MIN).height;
565: xAxisBottomY = graphBottomY + xAxis.getSize(MIN).height;
566: bottomY = titleBottomY > labelBottomY ? titleBottomY
567: : labelBottomY;
568: bottomY = bottomY > xAxisBottomY ? bottomY : xAxisBottomY;
569:
570: height1 = legend.getSize(MIN).height;
571: height2 = (bottomY - topY);
572: height = height1 > height2 ? height1 : height2;
573:
574: float heightMultiplier = maxValue != 0 ? (float) (minSpaceHeight)
575: / maxValue
576: : 0;
577: int graphLinesFillInteriorBaseValue = 0;
578: if (greatestValue > 0 & leastValue < 0)
579: graphLinesFillInteriorBaseValue = (int) Math.ceil(maxValue
580: / 2f * heightMultiplier);
581: else if (greatestValue > 0)
582: graphLinesFillInteriorBaseValue = 0;
583: else
584: graphLinesFillInteriorBaseValue = (int) Math.ceil(maxValue
585: * heightMultiplier);
586:
587: for (int k = 0; k < graphVector.size(); ++k) {
588: float[][] this DataSet = ((Dataset) datasetVector.get(k))
589: .getOldGraphStruct();
590: int numSets = this DataSet.length;
591: int numHeights = numSets > 0 ? this DataSet[0].length : 0;
592: int[][] heights = new int[numSets][numHeights];
593: int[][] barLowHeights = new int[numSets][numHeights];
594: for (int i = 0; i < numHeights; ++i) {
595: for (int j = 0; j < numSets; ++j) {
596: if (greatestValue > 0 && leastValue < 0) {
597: heights[j][i] = (int) ((this DataSet[j][i] + maxValue / 2f) * heightMultiplier);
598: barLowHeights[j][i] = (int) Math.ceil(maxValue
599: / 2f * heightMultiplier);
600: } else if (greatestValue > 0) {
601: heights[j][i] = (int) ((this DataSet[j][i] - leastValue) * heightMultiplier);
602: barLowHeights[j][i] = 0;
603: } else {
604: heights[j][i] = (int) ((this DataSet[j][i]
605: + maxValue - greatestValue) * heightMultiplier);
606: barLowHeights[j][i] = (int) Math.ceil(maxValue
607: * heightMultiplier);
608: }
609: }
610: }
611: ((LBGraphArea) graphVector.get(k)).setGraphValues(heights);
612: ((LBGraphArea) graphVector.get(k))
613: .setBarLowValues(barLowHeights);
614: ((LBGraphArea) graphVector.get(k))
615: .setLinesFillInteriorBaseValue(graphLinesFillInteriorBaseValue);
616: ((LBGraphArea) graphVector.get(k)).setXTicks(xAxis
617: .getTicks(g2D));
618: ((LBGraphArea) graphVector.get(k)).setYTicks(yAxis
619: .getTicks(g2D));
620: ((LBGraphArea) graphVector.get(k)).updateLBGraphArea();
621: }
622:
623: Vector warningRegions = getWarningRegions();
624: for (int i = 0; i < warningRegions.size(); ++i) {
625: WarningRegion warningRegion = (WarningRegion) warningRegions
626: .get(i);
627: if (greatestValue > 0 && leastValue < 0) {
628:
629: warningRegion
630: .setHighGraph(warningRegion.getHigh() == Float.POSITIVE_INFINITY ? minSpaceHeight
631: : (int) ((warningRegion.getHigh() + maxValue / 2f) * heightMultiplier));
632: warningRegion
633: .setLowGraph(warningRegion.getLow() == Float.NEGATIVE_INFINITY ? 0f
634: : (int) ((warningRegion.getLow() + maxValue / 2f) * heightMultiplier));
635: } else if (greatestValue >= 0) {
636: warningRegion
637: .setHighGraph(warningRegion.getHigh() == Float.POSITIVE_INFINITY ? minSpaceHeight
638: : (int) ((warningRegion.getHigh() - leastValue) * heightMultiplier));
639: warningRegion
640: .setLowGraph(warningRegion.getLow() == Float.NEGATIVE_INFINITY ? 0f
641: : (int) ((warningRegion.getLow() - leastValue) * heightMultiplier));
642: } else {
643: warningRegion
644: .setHighGraph(warningRegion.getHigh() == Float.POSITIVE_INFINITY ? minSpaceHeight
645: : (int) ((warningRegion.getHigh()
646: + maxValue - greatestValue) * heightMultiplier));
647: warningRegion
648: .setLowGraph(warningRegion.getLow() == Float.NEGATIVE_INFINITY ? 0f
649: : (int) ((warningRegion.getLow()
650: + maxValue - greatestValue) * heightMultiplier));
651: }
652: if (warningRegion.getHighGraph() > minSpaceHeight)
653: warningRegion.setHighGraph(minSpaceHeight);
654: if (warningRegion.getLowGraph() < 0)
655: warningRegion.setLowGraph(0);
656: if (warningRegion.getHighGraph() < warningRegion
657: .getLowGraph())
658: warningRegion.setHighGraph(warningRegion.getLowGraph());
659: if (warningRegion.getLowGraph() > warningRegion
660: .getHighGraph())
661: warningRegion.setLowGraph(warningRegion.getHighGraph());
662: if (heightMultiplier <= 0f) {
663: warningRegion.setHighGraph(0);
664: warningRegion.setLowGraph(0);
665: }
666: }
667: //no need to set warning regions for graph areas because this has already been done
668:
669: minBounds.setSize(width, height);
670: if (!getAutoSize(MIN)) {
671: int minWidth = titleSize.width > minBounds.width ? titleSize.width
672: : minBounds.width;
673: int minHeight;
674: if (titleSize.height > 0 && minBounds.height > 0) {
675: minHeight = titleSize.height
676: + getBetweenTitleAndSpaceGapThickness(g2D)
677: + minBounds.height;
678: } else
679: minHeight = titleSize.height + minBounds.height;
680: setSpaceSize(MIN, new Dimension(minWidth, minHeight));
681: }
682:
683: int x = maxBounds.x + (maxBounds.width - minBounds.width) / 2;
684: int y = maxBounds.y + (maxBounds.height - minBounds.height) / 2;
685: minBounds.setLocation(x, y);
686:
687: int graphBetweenWidth = graphFirst.getSpaceSizeLocation(MIN).x
688: - graphFirst.getSizeLocation(MIN).x;
689: int graphBetweenHeight = graphFirst.getSpaceSizeLocation(MIN).y
690: - graphFirst.getSizeLocation(MIN).y;
691: int legendBetweenWidth = legend.getSpaceSizeLocation(MIN).x
692: - legend.getSizeLocation(MIN).x;
693:
694: int yAxisX, yAxisY, xAxisX, xAxisY, graphX, graphY, legendX, legendY;
695:
696: yAxisX = minBounds.x;
697: graphX = yAxisX + yAxis.getSize(MIN).width + graphBetweenWidth;
698: xAxisX = graphX;
699: legendX = minBounds.x + minBounds.width
700: - legend.getSize(MIN).width + legendBetweenWidth;
701: int yAxisTopY = titleTopY < labelTopY ? titleTopY : labelTopY;
702: int yAxisOffsetY = yAxisTopY - topY;
703: yAxisY = minBounds.y + yAxisOffsetY
704: - (yAxisTopY - yAxis.getSpaceSizeLocation(MIN).y);
705: int graphOffsetY = graphTopY - topY;
706: graphY = minBounds.y + graphOffsetY + graphBetweenHeight;
707: xAxisY = graphY - graphBetweenHeight
708: + graphFirst.getSize(MIN).height;
709: if (legend.getSize(MIN).height <= graphFirst.getSize(MIN).height) {
710: legendY = graphY
711: + (graphFirst.getSpaceSize(MIN).height - legend
712: .getSpaceSize(MIN).height) / 2;
713: } else {
714: if (legend.getSize(MIN).height <= minBounds.y
715: + minBounds.height - graphY) {
716: legendY = graphY;
717: } else {
718: legendY = minBounds.y
719: + (minBounds.height - legend.getSpaceSize(MIN).height)
720: / 2;
721: }
722: }
723:
724: legend.setSpaceSizeLocation(MIN, new Point(legendX, legendY));
725: legend.updateLegendArea(g2D);
726: xAxis.setSpaceSizeLocation(MIN, new Point(xAxisX, xAxisY));
727: xAxis.updateXAxisArea(g2D);
728: yAxis.setSpaceSizeLocation(MIN, new Point(yAxisX, yAxisY));
729: yAxis.updateYAxisArea(g2D);
730:
731: for (int i = 0; i < graphVector.size(); ++i) {
732:
733: ((LBGraphArea) graphVector.get(i)).setSpaceSizeLocation(
734: MIN, new Point(graphX, graphY));
735: ((LBGraphArea) graphVector.get(i)).setXTicks(xAxis
736: .getTicks(g2D));
737: ((LBGraphArea) graphVector.get(i)).setYTicks(yAxis
738: .getTicks(g2D));
739: ((LBGraphArea) graphVector.get(i)).updateLBGraphArea();
740: }
741:
742: for (int i = 0; i < warningRegions.size(); ++i) {
743:
744: WarningRegion warningRegion = (WarningRegion) warningRegions
745: .get(i);
746: warningRegion.setGraphSpaceX(graphFirst
747: .getSpaceSizeLocation(MIN).x);
748: warningRegion.setGraphSpaceY(graphFirst
749: .getSpaceSizeLocation(MIN).y);
750: warningRegion.setGraphSpaceWidth(graphFirst
751: .getSpaceSize(MIN).width);
752: warningRegion.setGraphSpaceHeight(graphFirst
753: .getSpaceSize(MIN).height);
754: }
755:
756: if (getTitleSqueeze()) {
757: int titleX = minBounds.x
758: + (minBounds.width - titleSize.width) / 2;
759: int titleY = minBounds.y
760: - getBetweenTitleAndSpaceGapThickness(g2D)
761: - getTitle().getSize(MIN).height;
762: setTitleLocation(new Point(titleX, titleY));
763: }
764: }
765: }
|