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 left 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 is particulary suited for a
031: * horizontal bar chart. This class manages the xAxis, yAxis, legend,
032: * and graph areas of the chart. This class cannot be added to a content pane;
033: * if that is desired, use LLChart2D. This class is for custom painting, such
034: * as custom painting a JComponent (i.e. overriding the
035: * paintComponent (Graphics g) method). For customizing the LLChart2D class
036: * to use with your data set and needs, you'll have to get this class
037: * LLChartArea. You'll have to pass it your data sets in an array at least.
038: * You'll also want to set the title of this class, and also get its
039: * yAxis and other parts for setting their titles, labels, and so on.
040: */
041: final class LLChartArea extends GraphChartArea {
042:
043: private Rectangle maxBounds;
044: private Rectangle minBounds;
045: private Dimension prefSize;
046: private XAxisArea xAxis;
047: private YAxisArea yAxis;
048: private LegendArea legend;
049: private boolean needsUpdate;
050:
051: /**
052: * Creates LLChartArea with GraphChartArea's defaults, and its defaults.
053: */
054: LLChartArea() {
055:
056: xAxis = getXAxis();
057: yAxis = getYAxis();
058: legend = getLegend();
059: minBounds = new Rectangle();
060: prefSize = new Dimension();
061:
062: xAxis.setType(LABELSLEFT);
063: yAxis.setType(LABELSLEFT);
064: }
065:
066: /**
067: * Returns the minimum size that the chart would need if it was to be redrawn,
068: * the "preferred" size. The preferred size is the minimum size which would
069: * need to be set as the maxmodel size of the chart, if the chart was to be
070: * redrawn (assuming magnification is disabled).
071: * @param g2D The graphics context for calculations and painting.
072: * @return The size of the minimum maxmodel for a redraw.
073: */
074: final Dimension getPrefSize(Graphics2D g2D) {
075:
076: updateLLChartArea(g2D);
077: return prefSize;
078: }
079:
080: /**
081: * Indicates whether some property of this class has changed.
082: * @return True if some property has changed.
083: */
084: final boolean getLLChartAreaNeedsUpdate() {
085:
086: if (needsUpdate || getGraphChartAreaNeedsUpdate())
087: return true;
088: Vector graphVector = getGraphVector();
089: for (int i = 0; i < graphVector.size(); ++i) {
090: if (((LLGraphArea) graphVector.get(i))
091: .getLLGraphAreaNeedsUpdate())
092: return true;
093: }
094: return false;
095: }
096:
097: /**
098: * Resets the model for this class. The model is used for shrinking and
099: * growing of its components based on the maximum size of this class. If this
100: * method is called, then the next time the maximum size is set, this classes
101: * model maximum size will be made equal to the new maximum size. Effectively
102: * what this does is ensure that whenever this objects maximum size is equal
103: * to the one given, then all of the components will take on their default
104: * model sizes. Note: This is only useful when auto model max sizing is
105: * disabled.
106: * @param reset True causes the max model to be reset upon next max sizing.
107: */
108: final void resetLLChartAreaModel(boolean reset) {
109:
110: needsUpdate = true;
111: resetGraphChartAreaModel(reset);
112: Vector graphVector = this .getGraphVector();
113: for (int i = 0; i < graphVector.size(); ++i) {
114: ((LLGraphArea) graphVector.get(i))
115: .resetLLGraphAreaModel(reset);
116: }
117: }
118:
119: /**
120: * Updates this parent's variables, and this' variables.
121: * @param g2D The graphics context to use for calculations.
122: */
123: final void updateLLChartArea(Graphics2D g2D) {
124:
125: if (getLLChartAreaNeedsUpdate()) {
126: updateGraphChartArea(g2D);
127: update(g2D);
128: Vector graphVector = getGraphVector();
129: for (int i = 0; i < graphVector.size(); ++i) {
130: ((LLGraphArea) graphVector.get(i)).updateLLGraphArea();
131: }
132: Vector warningRegions = getWarningRegions();
133: for (int i = 0; i < warningRegions.size(); ++i) {
134: ((WarningRegion) warningRegions.get(i))
135: .updateWarningRegion();
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: updateLLChartArea(g2D);
151: super .paintComponent(g2D);
152:
153: Vector graphVector = getGraphVector();
154: for (int i = graphVector.size() - 1; i >= 0; --i) {
155: ((LLGraphArea) 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: LLGraphArea this Graph = (LLGraphArea) 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: ((LLGraphArea) graphVector.get(i)).setCustomRatio(WIDTH,
194: true, widthRatio);
195: ((LLGraphArea) graphVector.get(i)).setCustomRatio(HEIGHT,
196: true, heightRatio);
197: ((LLGraphArea) graphVector.get(i))
198: .setLabelsAxisTicksAlignment(yAxis
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: ((LLGraphArea) graphVector.get(i)).setSize(MAX,
249: new Dimension(width, height));
250: }
251:
252: xAxis.setNumTicks(getNumPlotAxisLabels()); //sets here to because of below case
253: yAxis.setNumTicks(yTextList.getNumBullets()); //sets here to hold intermediate calculation
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 = 0; i < getNumPlotAxisLabels(); ++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: xAxis.getTextList().setLabels(labels);
333:
334: int graphPrefHeight = 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 tempHeight = ((LLGraphArea) graphVector.get(i))
341: .getPrefSpaceHeight(numSets, numCats,
342: numCompsPerCat);
343: graphPrefHeight = tempHeight > graphPrefHeight ? tempHeight
344: : graphPrefHeight;
345: ((LLGraphArea) graphVector.get(i)).setDataSign(dataSign);
346: }
347:
348: yTextList.setCustomSpaceMinHeight(true, graphPrefHeight);
349: yAxis.updateYAxisArea(g2D);
350: int minSpaceHeight = yAxis.getSpaceSize(MIN).height;
351:
352: xAxis.updateXAxisArea(g2D);
353: int minSpaceWidth = 0;
354: Rectangle[] xAxisTicks = xAxis.getTicks(g2D);
355: if (xAxisTicks.length > 0) {
356: minSpaceWidth = xAxisTicks[xAxisTicks.length - 1].x
357: - xAxisTicks[0].x + xAxisTicks[0].width;
358: }
359:
360: Dimension minGraphSpaceSize = new Dimension(minSpaceWidth,
361: minSpaceHeight);
362: for (int i = 0; i < graphVector.size(); ++i) {
363: ((LLGraphArea) graphVector.get(i)).setSpaceSize(MIN,
364: minGraphSpaceSize);
365: }
366:
367: LLGraphArea graphFirst = (LLGraphArea) graphVector
368: .get(graphVector.size() - 1);
369: int graphMinSizeWidth = 0;
370: int graphMinSizeHeight = 0;
371: if (graphVector.size() > 0) {
372: graphMinSizeWidth = graphFirst.getSize(MIN).width;
373: graphMinSizeHeight = graphFirst.getSize(MIN).height;
374: }
375:
376: legend.updateLegendArea(g2D);
377:
378: int height1 = xAxis.getSize(MIN).height + graphMinSizeHeight;
379: int height2 = xAxis.getSize(MIN).height
380: + yAxis.getSize(MIN).height;
381: height = height1 > height2 ? height1 : height2;
382: int heightForDeficient = height;
383:
384: int leftTickX = xAxis.getTicks(g2D)[0].x;
385: int titleLeftX = xAxis.getSizeLocation(MIN).x
386: + (int) ((xAxis.getSize(MIN).width - xAxis.getTitle()
387: .getSize(MIN).width) / 2f);
388: int labelLeftX = xTextList.getLabels(g2D)[0]
389: .getSizeLocation(MIN).x;
390: int yAxisLeftX = leftTickX
391: - graphFirst.getBorderThickness(LEFT)
392: - yAxis.getSize(MIN).width;
393: int leftX = titleLeftX < labelLeftX ? titleLeftX : labelLeftX;
394: leftX = leftX < yAxisLeftX ? leftX : yAxisLeftX;
395:
396: int rightTickX = xAxis.getTicks(g2D)[xAxis.getTicks(g2D).length - 1].x;
397: int tickWidth = xAxis.getTicks(g2D)[0].width;
398: int graphRightX = rightTickX + tickWidth
399: + graphFirst.getBorderThickness(RIGHT);
400: int titleRightX = titleLeftX
401: + xAxis.getTitle().getSize(MIN).width;
402: TextArea xAxisLabelRight = xTextList.getLabels(g2D)[xTextList
403: .getLabels(g2D).length - 1];
404: int labelRightX = xAxisLabelRight.getSizeLocation(MIN).x
405: + xAxisLabelRight.getSize(MIN).width;
406: int legendRightX = graphRightX
407: + betweenChartAndLegendGapThickness
408: + legend.getSize(MIN).width;
409: int rightX = titleRightX > labelRightX ? titleRightX
410: : labelRightX;
411: rightX = rightX > legendRightX ? rightX : legendRightX;
412:
413: width = (rightX - leftX);
414:
415: if (getAutoSetLayoutRatios()) {
416:
417: yAxisToWidthRatio = width > 0 ? yAxis.getSize(MIN).width
418: / (float) width : 0f;
419: yAxisToWidthRatio = yAxisToWidthRatio < 1f ? yAxisToWidthRatio
420: : 1f;
421: xAxisToWidthRatio = width > 0 ? xAxis.getSize(MIN).width
422: / (float) width : 0f;
423: xAxisToWidthRatio = xAxisToWidthRatio < 1f ? xAxisToWidthRatio
424: : 1f;
425: graphToWidthRatio = width > 0 ? graphMinSizeWidth
426: / (float) width : 0f;
427: graphToWidthRatio = graphToWidthRatio < 1f ? graphToWidthRatio
428: : 1f;
429: if (xAxisToWidthRatio > graphToWidthRatio)
430: graphToWidthRatio = xAxisToWidthRatio;
431: else
432: xAxisToWidthRatio = graphToWidthRatio;
433:
434: yAxisToHeightRatio = height > 0 ? yAxis.getSize(MIN).height
435: / (float) height : 0f;
436: yAxisToHeightRatio = yAxisToHeightRatio < 1f ? yAxisToHeightRatio
437: : 1f;
438: xAxisToHeightRatio = height > 0 ? xAxis.getSize(MIN).height
439: / (float) height : 0f;
440: xAxisToHeightRatio = xAxisToHeightRatio < 1f ? xAxisToHeightRatio
441: : 1f;
442: graphToHeightRatio = height > 0 ? graphMinSizeHeight
443: / (float) height : 0f;
444: graphToHeightRatio = graphToHeightRatio < 1f ? graphToHeightRatio
445: : 1f;
446: if (yAxisToHeightRatio > graphToHeightRatio)
447: graphToHeightRatio = yAxisToHeightRatio;
448: else
449: yAxisToHeightRatio = graphToHeightRatio;
450:
451: if (yAxisToWidthRatio <= 0f || yAxisToHeightRatio <= 0f) {
452: yAxisToWidthRatio = yAxisToHeightRatio = 0f;
453: }
454: if (xAxisToWidthRatio <= 0f || xAxisToHeightRatio <= 0f) {
455: xAxisToWidthRatio = xAxisToHeightRatio = 0f;
456: }
457: if (graphToWidthRatio <= 0f || graphToHeightRatio <= 0f) {
458: graphToWidthRatio = graphToHeightRatio = 0f;
459: }
460: legendToWidthRatio = 1f - yAxisToWidthRatio
461: - graphToWidthRatio;
462: legendToHeightRatio = 1f;
463:
464: if (legendToWidthRatio <= 0f || legendToHeightRatio <= 0f) {
465: legendToWidthRatio = legendToHeightRatio = 0f;
466: }
467:
468: setYAxisToWidthRatio(yAxisToWidthRatio);
469: setXAxisToWidthRatio(xAxisToWidthRatio);
470: setGraphToWidthRatio(graphToWidthRatio);
471: setLegendToWidthRatio(legendToWidthRatio);
472:
473: setYAxisToHeightRatio(yAxisToHeightRatio);
474: setXAxisToHeightRatio(xAxisToHeightRatio);
475: setGraphToHeightRatio(graphToHeightRatio);
476: setLegendToHeightRatio(legendToHeightRatio);
477:
478: setAutoSetLayoutRatios(false);
479: }
480:
481: Dimension titleSize = getTitleSize(MIN, g2D);
482: int widthForDeficient = width;
483: width = titleSize.width > width ? titleSize.width : width;
484: int prefWidth = width
485: + (getSize(MIN).width - getSpaceSize(MIN).width);
486: int prefHeight = height
487: + (getSize(MIN).height - getSpaceSize(MIN).height)
488: + titleSize.height
489: + getBetweenTitleAndSpaceGapThickness(g2D);
490: prefSize = new Dimension((int) (1.4f * prefWidth),
491: (int) (1.3f * prefHeight));
492:
493: int deficientWidth = 0;
494: int deficientHeight = 0;
495: if (getAutoSize(MIN)) {
496:
497: deficientHeight = maxBounds.height - heightForDeficient;
498: deficientWidth = maxBounds.width - widthForDeficient;
499: } else {
500: deficientWidth = width - widthForDeficient;
501: deficientHeight = height - heightForDeficient;
502: }
503:
504: graphPrefHeight = minSpaceHeight + deficientHeight;
505: yTextList.setCustomSpaceMinHeight(true, graphPrefHeight);
506: yAxis.updateYAxisArea(g2D);
507: minSpaceHeight = yAxis.getSize(MIN).height;
508:
509: deficientWidth += (deficientWidth / getNumPlotAxisLabels());
510: int xAxisPrefWidth = xAxis.getSize(MIN).width + deficientWidth;
511: xTextList.setCustomSpaceMinWidth(true, xAxisPrefWidth);
512:
513: xAxis.updateXAxisArea(g2D);
514: minSpaceWidth = 0;
515: xAxisTicks = xAxis.getTicks(g2D);
516: if (xAxisTicks.length > 0) {
517: minSpaceWidth = xAxisTicks[xAxisTicks.length - 1].x
518: - xAxisTicks[0].x + xAxisTicks[0].width;
519: }
520:
521: minGraphSpaceSize = new Dimension(minSpaceWidth, minSpaceHeight);
522: for (int i = 0; i < graphVector.size(); ++i) {
523: ((LLGraphArea) graphVector.get(i)).setSpaceSize(MIN,
524: minGraphSpaceSize);
525: }
526:
527: graphMinSizeWidth = 0;
528: graphMinSizeHeight = 0;
529: if (graphVector.size() > 0) {
530: graphMinSizeWidth = graphFirst.getSize(MIN).width;
531: graphMinSizeHeight = graphFirst.getSize(MIN).height;
532: }
533:
534: legend.updateLegendArea(g2D);
535:
536: leftTickX = xAxis.getTicks(g2D)[0].x;
537: titleLeftX = xAxis.getSizeLocation(MIN).x
538: + (int) ((xAxis.getSize(MIN).width - xAxis.getTitle()
539: .getSize(MIN).width) / 2f);
540: labelLeftX = xTextList.getLabels(g2D)[0].getSizeLocation(MIN).x;
541: yAxisLeftX = leftTickX - graphFirst.getBorderThickness(LEFT)
542: - yAxis.getSize(MIN).width;
543: leftX = titleLeftX < labelLeftX ? titleLeftX : labelLeftX;
544: leftX = leftX < yAxisLeftX ? leftX : yAxisLeftX;
545:
546: rightTickX = xAxis.getTicks(g2D)[xAxis.getTicks(g2D).length - 1].x;
547: tickWidth = xAxis.getTicks(g2D)[0].width;
548: graphRightX = rightTickX + tickWidth
549: + graphFirst.getBorderThickness(RIGHT);
550: titleRightX = titleLeftX + xAxis.getTitle().getSize(MIN).width;
551: xAxisLabelRight = xTextList.getLabels(g2D)[xTextList
552: .getLabels(g2D).length - 1];
553: labelRightX = xAxisLabelRight.getSizeLocation(MIN).x
554: + xAxisLabelRight.getSize(MIN).width;
555: legendRightX = graphRightX + betweenChartAndLegendGapThickness
556: + legend.getSize(MIN).width;
557: rightX = titleRightX > labelRightX ? titleRightX : labelRightX;
558: rightX = rightX > legendRightX ? rightX : legendRightX;
559:
560: width = (rightX - leftX);
561: width = titleSize.width > width ? titleSize.width : width;
562:
563: height1 = xAxis.getSize(MIN).height + graphMinSizeHeight;
564: height2 = xAxis.getSize(MIN).height + yAxis.getSize(MIN).height;
565: height = height1 > height2 ? height1 : height2;
566:
567: float widthMultiplier = maxValue != 0 ? (float) (minSpaceWidth)
568: / maxValue : 0;
569: int graphLinesFillInteriorBaseValue = 0;
570: if (greatestValue > 0 & leastValue < 0)
571: graphLinesFillInteriorBaseValue = (int) Math.ceil(maxValue
572: / 2f * widthMultiplier);
573: else if (greatestValue > 0)
574: graphLinesFillInteriorBaseValue = 0;
575: else
576: graphLinesFillInteriorBaseValue = (int) Math.ceil(maxValue
577: * widthMultiplier);
578: for (int k = 0; k < graphVector.size(); ++k) {
579: float[][] this DataSet = ((Dataset) datasetVector.get(k))
580: .getOldGraphStruct();
581: int numSets = this DataSet.length;
582: int numWidths = numSets > 0 ? this DataSet[0].length : 0;
583: int[][] widths = new int[numSets][numWidths];
584: int[][] barLowWidths = new int[numSets][numWidths];
585: for (int i = 0; i < numWidths; ++i) {
586: for (int j = 0; j < numSets; ++j) {
587: if (greatestValue > 0 & leastValue < 0) {
588: widths[j][i] = (int) ((this DataSet[j][i] + maxValue / 2f) * widthMultiplier);
589: barLowWidths[j][i] = (int) Math.ceil(maxValue
590: / 2f * widthMultiplier);
591: } else if (greatestValue > 0) {
592: widths[j][i] = (int) ((this DataSet[j][i] - leastValue) * widthMultiplier);
593: barLowWidths[j][i] = 0;
594: } else {
595: widths[j][i] = (int) ((this DataSet[j][i]
596: + maxValue - greatestValue) * widthMultiplier);
597: barLowWidths[j][i] = (int) Math.ceil(maxValue
598: * widthMultiplier);
599: }
600: }
601: }
602: ((LLGraphArea) graphVector.get(k)).setGraphValues(widths);
603: ((LLGraphArea) graphVector.get(k))
604: .setBarLowValues(barLowWidths);
605: ((LLGraphArea) graphVector.get(k))
606: .setLinesFillInteriorBaseValue(graphLinesFillInteriorBaseValue);
607: ((LLGraphArea) graphVector.get(k)).setXTicks(xAxis
608: .getTicks(g2D));
609: ((LLGraphArea) graphVector.get(k)).setYTicks(yAxis
610: .getTicks(g2D));
611: ((LLGraphArea) graphVector.get(k)).updateLLGraphArea();
612: }
613:
614: Vector warningRegions = getWarningRegions();
615: for (int i = 0; i < warningRegions.size(); ++i) {
616: WarningRegion warningRegion = (WarningRegion) warningRegions
617: .get(i);
618: if (greatestValue > 0 & leastValue < 0) {
619: warningRegion
620: .setHighGraph(warningRegion.getHigh() == Float.POSITIVE_INFINITY ? minSpaceWidth
621: : (int) ((warningRegion.getHigh() + maxValue / 2f) * widthMultiplier));
622: warningRegion
623: .setLowGraph(warningRegion.getLow() == Float.NEGATIVE_INFINITY ? 0f
624: : (int) ((warningRegion.getLow() + maxValue / 2f) * widthMultiplier));
625: } else if (greatestValue >= 0) {
626: warningRegion
627: .setHighGraph(warningRegion.getHigh() == Float.POSITIVE_INFINITY ? minSpaceWidth
628: : (int) ((warningRegion.getHigh() - leastValue) * widthMultiplier));
629: warningRegion
630: .setLowGraph(warningRegion.getLow() == Float.NEGATIVE_INFINITY ? 0f
631: : (int) ((warningRegion.getLow() - leastValue) * widthMultiplier));
632: } else {
633: warningRegion
634: .setHighGraph(warningRegion.getHigh() == Float.POSITIVE_INFINITY ? minSpaceWidth
635: : (int) ((warningRegion.getHigh()
636: + maxValue - greatestValue) * widthMultiplier));
637: warningRegion
638: .setLowGraph(warningRegion.getLow() == Float.NEGATIVE_INFINITY ? 0f
639: : (int) ((warningRegion.getLow()
640: + maxValue - greatestValue) * widthMultiplier));
641: }
642: if (warningRegion.getHighGraph() > minSpaceWidth)
643: warningRegion.setHighGraph(minSpaceWidth);
644: if (warningRegion.getLowGraph() < 0)
645: warningRegion.setLowGraph(0);
646: if (warningRegion.getHighGraph() < warningRegion
647: .getLowGraph())
648: warningRegion.setHighGraph(warningRegion.getLowGraph());
649: if (warningRegion.getLowGraph() > warningRegion
650: .getHighGraph())
651: warningRegion.setLowGraph(warningRegion.getHighGraph());
652: if (widthMultiplier <= 0f) {
653: warningRegion.setHighGraph(0);
654: warningRegion.setLowGraph(0);
655: }
656: }
657: //no need to set warning regions for graph areas because this has already been done
658:
659: minBounds.setSize(width, height);
660: if (!getAutoSize(MIN)) {
661: int minWidth = titleSize.width > minBounds.width ? titleSize.width
662: : minBounds.width;
663: int minHeight;
664: if (titleSize.height > 0 && minBounds.height > 0) {
665: minHeight = titleSize.height
666: + getBetweenTitleAndSpaceGapThickness(g2D)
667: + minBounds.height;
668: } else
669: minHeight = titleSize.height + minBounds.height;
670: setSpaceSize(MIN, new Dimension(minWidth, minHeight));
671: }
672:
673: int x = maxBounds.x + (maxBounds.width - minBounds.width) / 2;
674: int y = maxBounds.y + (maxBounds.height - minBounds.height) / 2;
675: minBounds.setLocation(x, y);
676:
677: int graphBetweenWidth = graphFirst.getSpaceSizeLocation(MIN).x
678: - graphFirst.getSizeLocation(MIN).x;
679: int graphBetweenHeight = graphFirst.getSpaceSizeLocation(MIN).y
680: - graphFirst.getSizeLocation(MIN).y;
681: int legendBetweenWidth = legend.getSpaceSizeLocation(MIN).x
682: - legend.getSizeLocation(MIN).x;
683:
684: int yAxisX, yAxisY, xAxisX, xAxisY, graphX, graphY, legendX, legendY;
685:
686: int yAxisOffsetX = yAxisLeftX - leftX;
687: yAxisX = minBounds.x + yAxisOffsetX;
688: int xAxisLeftX = titleLeftX < labelLeftX ? titleLeftX
689: : labelLeftX;
690: int xAxisOffsetX = xAxisLeftX - leftX;
691: xAxisX = minBounds.x + xAxisOffsetX
692: - (xAxisLeftX - xAxis.getSpaceSizeLocation(MIN).x);
693: graphX = yAxisX + yAxis.getSize(MIN).width + graphBetweenWidth;
694: legendX = minBounds.x + minBounds.width
695: - legend.getSize(MIN).width + legendBetweenWidth;
696:
697: graphY = minBounds.y + graphBetweenHeight;
698: yAxisY = graphY;
699: xAxisY = minBounds.y + graphFirst.getSize(MIN).height;
700: legendY = graphY
701: + (graphFirst.getSpaceSize(MIN).height - legend
702: .getSpaceSize(MIN).height) / 2;
703:
704: yAxis.setSpaceSizeLocation(MIN, new Point(yAxisX, yAxisY));
705: yAxis.updateYAxisArea(g2D);
706: xAxis.setSpaceSizeLocation(MIN, new Point(xAxisX, xAxisY));
707: xAxis.updateXAxisArea(g2D);
708: legend.setSpaceSizeLocation(MIN, new Point(legendX, legendY));
709: legend.updateLegendArea(g2D);
710:
711: for (int i = 0; i < graphVector.size(); ++i) {
712: ((LLGraphArea) graphVector.get(i)).setSpaceSizeLocation(
713: MIN, new Point(graphX, graphY));
714: ((LLGraphArea) graphVector.get(i)).setXTicks(xAxis
715: .getTicks(g2D));
716: ((LLGraphArea) graphVector.get(i)).setYTicks(yAxis
717: .getTicks(g2D));
718: ((LLGraphArea) graphVector.get(i)).updateLLGraphArea();
719: }
720:
721: for (int i = 0; i < warningRegions.size(); ++i) {
722: WarningRegion warningRegion = (WarningRegion) warningRegions
723: .get(i);
724: warningRegion.setGraphSpaceX(graphFirst
725: .getSpaceSizeLocation(MIN).x);
726: warningRegion.setGraphSpaceY(graphFirst
727: .getSpaceSizeLocation(MIN).y);
728: warningRegion.setGraphSpaceWidth(graphFirst
729: .getSpaceSize(MIN).width);
730: warningRegion.setGraphSpaceHeight(graphFirst
731: .getSpaceSize(MIN).height);
732: }
733:
734: if (getTitleSqueeze()) {
735: int titleX = minBounds.x
736: + (minBounds.width - titleSize.width) / 2;
737: int titleY = minBounds.y
738: - getBetweenTitleAndSpaceGapThickness(g2D)
739: - getTitle().getSize(MIN).height;
740: setTitleLocation(new Point(titleX, titleY));
741: }
742: }
743: }
|