0001: /**
0002: * Chart2D, a java library for drawing two dimensional charts.
0003: * Copyright (C) 2001 Jason J. Simas
0004: *
0005: * This library is free software; you can redistribute it and/or
0006: * modify it under the terms of the GNU Lesser General Public
0007: * License as published by the Free Software Foundation; either
0008: * version 2.1 of the License, or (at your option) any later version.
0009: *
0010: * This library is distributed in the hope that it will be useful,
0011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0013: * Lesser General Public License for more details.
0014: * You should have received a copy of the GNU Lesser General Public
0015: * License along with this library; if not, write to the Free Software
0016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0017: *
0018: * The author of this library may be contacted at:
0019: * E-mail: jjsimas@users.sourceforge.net
0020: * Street Address: J J Simas, 887 Tico Road, Ojai, CA 93023-3555 USA
0021: */package net.sourceforge.chart2d;
0022:
0023: import java.awt.*;
0024: import java.awt.geom.*;
0025: import java.util.*;
0026:
0027: /**
0028: * The area that the x axis and y axis attach to, and in which bars, lines, or
0029: * dots are painted to represent the data set. The "LB" in the name of this
0030: * class stands for Labels Bottom. This graph should always be used when the
0031: * data descriptors for the the graph are located on the bottom. Data
0032: * descriptors have values such as September and November, and not like 0 or 50.
0033: * <b>Features:</b><br>
0034: * Provides bordering functionality. Allows lines to be painted that match
0035: * up with y axis and x axis tick marks in order to know where the bars, dots,
0036: * or plot lines are in relation to the y axis values. Supports vertical
0037: * bar graphs, line charts, and scatter charts (dots), and any combintation
0038: * thereof. If a bars are present in any graph, then it is highly recommended
0039: * that the GraphArea method, allowComponentAlignment be passed the value of
0040: * false. This will ensure that all the bars are visible on the graph. For
0041: * graphs that do not have bars present, the opposite is advised. The GraphArea
0042: * method should be passed the value of true. This provides a more intuitive
0043: * representation of the data.
0044: */
0045: final class LBGraphArea extends GraphArea {
0046:
0047: private FancyBar[][] bars;
0048: private FancyDot[][] dots;
0049: private FancyLine[] lines;
0050: private boolean needsUpdate;
0051:
0052: /**
0053: * Creates a graph area with GraphArea's default values. Default values:
0054: * resetLBGraphAreaModel (true);
0055: */
0056: LBGraphArea() {
0057:
0058: bars = new FancyBar[0][0];
0059: dots = new FancyDot[0][0];
0060: lines = new FancyLine[0];
0061:
0062: setBarRoundingRatio(.25f);
0063:
0064: resetLBGraphAreaModel(true);
0065: needsUpdate = true;
0066: }
0067:
0068: /**
0069: * Does a quick calculation of the preferred width of the graph.
0070: * @param numSets The number of data series.
0071: * @param numComps The number of data categories per series.
0072: * @param numCompsPerCat The number of data per series, per category.
0073: * @return The preferred width.
0074: */
0075: final int getPrefSpaceWidth(int numSets, int numCats,
0076: int numCompsPerCat) {
0077:
0078: float ratio = getRatio(WIDTH);
0079: int barsWidth = 0, dotsWidth = 0, linesWidth = 0, prefWidth = 0;
0080: if (getAllowComponentAlignment()) {
0081: barsWidth = getBarsExistence() ? (int) (numCats
0082: * (1 + (1 - getBarsWithinCategoryOverlapRatio())
0083: * (numCompsPerCat - 1)) * applyRatio(
0084: getBarsThicknessModel(), ratio)) : 0;
0085: dotsWidth = getDotsExistence() ? (int) (numCats
0086: * (1 + (1 - getDotsWithinCategoryOverlapRatio())
0087: * (numCompsPerCat - 1)) * applyRatio(
0088: getDotsThicknessModel(), ratio)) : 0;
0089: linesWidth = getLinesExistence() ? (int) (numCats
0090: * (1 + (1 - getLinesWithinCategoryOverlapRatio())
0091: * (numCompsPerCat - 1)) * applyRatio(
0092: getLinesThicknessModel(), ratio)) : 0;
0093: } else {
0094: barsWidth = getBarsExistence() ? (int) (numSets
0095: * numCats
0096: * (1 + (1 - getBarsWithinCategoryOverlapRatio())
0097: * (numCompsPerCat - 1)) * applyRatio(
0098: getBarsThicknessModel(), ratio)) : 0;
0099: dotsWidth = getDotsExistence() ? (int) (numSets
0100: * numCats
0101: * (1 + (1 - getDotsWithinCategoryOverlapRatio())
0102: * (numCompsPerCat - 1)) * applyRatio(
0103: getDotsThicknessModel(), ratio)) : 0;
0104: linesWidth = getLinesExistence() ? (int) (numSets
0105: * numCats
0106: * (1 + (1 - getLinesWithinCategoryOverlapRatio())
0107: * (numCompsPerCat - 1)) * applyRatio(
0108: getLinesThicknessModel(), ratio)) : 0;
0109:
0110: }
0111: prefWidth = barsWidth > dotsWidth ? barsWidth : dotsWidth;
0112: prefWidth = prefWidth > linesWidth ? prefWidth : linesWidth;
0113: int gapsWidth = getBetweenComponentsGapExistence() ? numCats
0114: * applyRatio(getBetweenComponentsGapThicknessModel(),
0115: ratio) : 0;
0116: prefWidth = prefWidth + gapsWidth;
0117: prefWidth = prefWidth < getSpaceSize(MAX).width ? prefWidth
0118: : getSpaceSize(MAX).width;
0119: return (prefWidth);
0120: }
0121:
0122: /**
0123: * Indicates whether some property of this class has changed.
0124: * @return True if some property has changed.
0125: */
0126: final boolean getLBGraphAreaNeedsUpdate() {
0127:
0128: return (needsUpdate || getGraphAreaNeedsUpdate());
0129: }
0130:
0131: /**
0132: * Resets the model for this class. The model is used for shrinking and
0133: * growing of its components based on the maximum size of this class. If this
0134: * method is called, then the next time the maximum size is set, this classes
0135: * model maximum size will be made equal to the new maximum size. Effectively
0136: * what this does is ensure that whenever this objects maximum size is equal
0137: * to the one given, then all of the components will take on their default
0138: * model sizes. Note: This is only useful when auto model max sizing is
0139: * disabled.
0140: * @param reset True causes the max model size to be set upon the next max
0141: * sizing.
0142: */
0143: final void resetLBGraphAreaModel(boolean reset) {
0144:
0145: needsUpdate = true;
0146: resetGraphAreaModel(reset);
0147: }
0148:
0149: /**
0150: * Updates this parent's variables, and this' variables.
0151: */
0152: final void updateLBGraphArea() {
0153:
0154: if (getLBGraphAreaNeedsUpdate()) {
0155: updateGraphArea();
0156: update();
0157: }
0158: needsUpdate = false;
0159: }
0160:
0161: /**
0162: * Paints all the components of this class. First all variables are updated.
0163: * @param g2D The graphics context for calculations and painting.
0164: */
0165: final void paintComponent(Graphics2D g2D) {
0166:
0167: updateLBGraphArea();
0168: super .paintComponent(g2D);
0169:
0170: Shape oldClip = g2D.getClip();
0171: if (getClip())
0172: g2D.setClip(new Rectangle(getSpaceSizeLocation(MIN),
0173: getSpaceSize(MIN)));
0174:
0175: Composite oldComposite = g2D.getComposite();
0176: g2D.setComposite(getComponentsAlphaComposite());
0177:
0178: int numBars = bars.length > 0 ? bars[0].length : 0;
0179: int numDots = dots.length > 0 ? dots[0].length : 0;
0180: int numLines = lines.length;
0181: int numSets = getGraphValues().length;
0182: if (!getAllowComponentAlignment() && numBars > 0) {
0183: for (int i = 0; i < numSets; ++i) {
0184: for (int j = 0; j < numBars; ++j) {
0185: bars[i][j].paint(g2D);
0186: }
0187: }
0188: } else if (numBars > 0) {
0189: int[][] graphValues = getGraphValues();
0190: graphValues = stackedBarConvert(graphValues,
0191: getBarLowValues());
0192: for (int j = 0; j < numBars; ++j) {
0193: int[] sorted = stackedBarSort(graphValues, j);
0194: for (int i = 0; i < numSets; ++i) {
0195: bars[sorted[i]][j].paint(g2D);
0196: }
0197: }
0198: }
0199:
0200: for (int i = numLines - 1; i >= 0; --i)
0201: lines[i].paint(g2D);
0202:
0203: for (int i = numSets - 1; i >= 0; --i) {
0204: for (int j = numDots - 1; j >= 0; --j) {
0205: dots[i][j].paint(g2D);
0206: }
0207: }
0208:
0209: g2D.setClip(oldClip);
0210: g2D.setComposite(oldComposite);
0211: }
0212:
0213: private void update() {
0214:
0215: if (getAllowComponentAlignment())
0216: updateAllowAlignment();
0217: else
0218: updateDisallowAlignment();
0219: }
0220:
0221: private void updateDisallowAlignment() {
0222:
0223: int[][] graphLengths = getGraphValues();
0224: int numBars = 0, numDots = 0, numLinePoints = 0, numGaps = 0;
0225: int numSets = graphLengths.length;
0226: Rectangle[] xTicks = getXTicks();
0227: int numCompsPerCat = 0;
0228: int numCats = 0;
0229: if (numSets > 0) {
0230: numCats = getLabelsAxisTicksAlignment() == BETWEEN ? xTicks.length + 1
0231: : xTicks.length;
0232: numBars = getBarsExistence() ? numCats : 0;
0233: numDots = getDotsExistence() ? numCats : 0;
0234: numLinePoints = getLinesExistence() ? numCats : 0;
0235: numGaps = getBetweenComponentsGapExistence() ? numCats : 0;
0236: numCompsPerCat = numCats > 0 ? (int) (graphLengths[0].length / numCats)
0237: : 0;
0238: }
0239: if (numSets > 0 && numCats > 0 && numCompsPerCat > 0) {
0240:
0241: float ratio = getRatio(WIDTH);
0242: int availableThickness = getSpaceSize(MIN).width;
0243:
0244: int betweenComponentsGapThickness = 0;
0245: if (numGaps > 0) {
0246: betweenComponentsGapThickness = applyRatio(
0247: getBetweenComponentsGapThicknessModel(), ratio);
0248: betweenComponentsGapThickness = numGaps
0249: * betweenComponentsGapThickness <= availableThickness ? betweenComponentsGapThickness
0250: : availableThickness / numGaps;
0251: availableThickness -= numGaps
0252: * betweenComponentsGapThickness;
0253: }
0254:
0255: int barsThickness = 0;
0256: if (numBars > 0) {
0257: barsThickness = applyRatio(getBarsThicknessModel(),
0258: ratio);
0259: if ((numSets * numBars * numCompsPerCat)
0260: * barsThickness <= availableThickness) {
0261: float leftover = (availableThickness - barsThickness
0262: * (numSets * numBars * numCompsPerCat))
0263: / (numSets * numBars * numCompsPerCat);
0264: barsThickness = barsThickness
0265: + (int) (getBarsExcessSpaceFeedbackRatio() * leftover);
0266: } else {
0267: float numOverlapBarsPerCat = (1 + (1 - getBarsWithinCategoryOverlapRatio())
0268: * (numCompsPerCat - 1));
0269: if (numSets * numBars * numOverlapBarsPerCat
0270: * barsThickness > availableThickness) {
0271: barsThickness = (int) (availableThickness / (numSets
0272: * numBars * numOverlapBarsPerCat));
0273: }
0274: }
0275: }
0276: int dotsThickness = 0;
0277: if (numDots > 0) {
0278: dotsThickness = applyRatio(getDotsThicknessModel(),
0279: getRatio(LESSER));
0280: if ((numSets * numDots * numCompsPerCat)
0281: * dotsThickness <= availableThickness) {
0282: float leftover = (availableThickness - dotsThickness
0283: * (numSets * numDots * numCompsPerCat))
0284: / (numSets * numDots * numCompsPerCat);
0285: dotsThickness = dotsThickness
0286: + (int) (getDotsExcessSpaceFeedbackRatio() * leftover);
0287: } else {
0288: float numOverlapDotsPerCat = (1 + (1 - getDotsWithinCategoryOverlapRatio())
0289: * (numCompsPerCat - 1));
0290: if (numSets * numDots * numOverlapDotsPerCat
0291: * dotsThickness > availableThickness) {
0292: dotsThickness = (int) (availableThickness / (numSets
0293: * numDots * numOverlapDotsPerCat));
0294: }
0295: }
0296: }
0297: int linesThickness = 0;
0298: if (numLinePoints > 0) {
0299: linesThickness = applyRatio(getLinesThicknessModel(),
0300: getRatio(LESSER));
0301: if ((numSets * numLinePoints * numCompsPerCat)
0302: * linesThickness <= availableThickness) {
0303: float leftover = (availableThickness - linesThickness
0304: * (numSets * numLinePoints * numCompsPerCat))
0305: / (numSets * numLinePoints * numCompsPerCat);
0306: linesThickness = linesThickness
0307: + (int) (getLinesExcessSpaceFeedbackRatio() * leftover);
0308: } else {
0309: float numOverlapLinesPerCat = (1 + (1 - getLinesWithinCategoryOverlapRatio())
0310: * (numCompsPerCat - 1));
0311: if (numSets * numLinePoints * numOverlapLinesPerCat
0312: * linesThickness > availableThickness) {
0313: linesThickness = (int) (availableThickness / (numSets
0314: * numLinePoints * numOverlapLinesPerCat));
0315: }
0316: }
0317: }
0318:
0319: int componentsThickness = barsThickness;
0320: componentsThickness = dotsThickness > componentsThickness ? dotsThickness
0321: : componentsThickness;
0322: componentsThickness = linesThickness > componentsThickness ? linesThickness
0323: : componentsThickness;
0324: int setsThickness = componentsThickness * numSets;
0325: setsThickness = setsThickness > availableThickness
0326: / (numCats * numCompsPerCat) ? availableThickness
0327: / (numCats * numCompsPerCat) : setsThickness;
0328: componentsThickness = setsThickness / numSets;
0329:
0330: Rectangle2D.Float boundsGraph = new Rectangle2D.Float(
0331: getSpaceSizeLocation(MIN).x,
0332: getSpaceSizeLocation(MIN).y,
0333: getSpaceSize(MIN).width, getSpaceSize(MIN).height);
0334:
0335: bars = new FancyBar[numSets][numBars * numCompsPerCat];
0336: int[][] barLowValues = getBarLowValues();
0337: if (numBars > 0) {
0338: int y = getSpaceSizeLocation(MIN).y
0339: + getSpaceSize(MIN).height, x = 0;
0340: float catDelta = getSpaceSize(MIN).width
0341: / (float) (numBars * numCompsPerCat);
0342: if (numBars == 1) {
0343: x = getSpaceSizeLocation(MIN).x
0344: + (getSpaceSize(MIN).width - setsThickness)
0345: / 2;
0346: x = (int) (x - ((numCompsPerCat - 1) / 2f)
0347: * catDelta);
0348: for (int k = 0; k < numCompsPerCat; ++k) {
0349: for (int j = 0; j < numSets; ++j) {
0350: int compX = x
0351: + j
0352: * componentsThickness
0353: + (componentsThickness - barsThickness)
0354: / 2;
0355: bars[j][k] = new FancyBar();
0356: bars[j][k].setDataSign(getDataSign());
0357: bars[j][k].setBaseValue(y
0358: - getLinesFillInteriorBaseValue());
0359: if (graphLengths[j][k] > barLowValues[j][k]) {
0360: bars[j][k]
0361: .setBounds(new Rectangle2D.Float(
0362: compX + k * catDelta,
0363: y - graphLengths[j][k],
0364: barsThickness,
0365: graphLengths[j][k]
0366: - barLowValues[j][k]));
0367: } else {
0368: bars[j][k]
0369: .setBounds(new Rectangle2D.Float(
0370: compX + k * catDelta,
0371: y - barLowValues[j][k],
0372: barsThickness,
0373: barLowValues[j][k]
0374: - graphLengths[j][k]));
0375: }
0376: Rectangle2D.Float clipBounds = new Rectangle2D.Float(
0377: boundsGraph.x, bars[j][k]
0378: .getBounds().y,
0379: boundsGraph.width, bars[j][k]
0380: .getBounds().height);
0381: bars[j][k].setClipBounds(clipBounds);
0382: bars[j][k]
0383: .setLightBounds(getComponentsLightType() == COMPONENT ? bars[j][k]
0384: .getBounds()
0385: : boundsGraph);
0386: bars[j][k]
0387: .setLightSource(getComponentsLightSource());
0388: bars[j][k]
0389: .setColor(!getComponentsColoringByCat() ? getBarColors()[j]
0390: : getComponentsColorsByCat()[0]);
0391: bars[j][k]
0392: .setOutlineExistence(getOutlineComponents());
0393: bars[j][k]
0394: .setOutlineColor(getOutlineComponentsColor());
0395: bars[j][k].setArcw(getBarRoundingRatio()
0396: * barsThickness);
0397: bars[j][k].setArch(getBarRoundingRatio()
0398: * barsThickness);
0399: bars[j][k]
0400: .setWarningRegions(getWarningRegions());
0401: bars[j][k].setType(FancyShape.LABELSBOTTOM);
0402: bars[j][k].setGraphBounds(boundsGraph);
0403: }
0404: }
0405: } else {
0406: float minX, maxX, tickHalfWidth;
0407: minX = getSpaceSizeLocation(MIN).x;
0408: tickHalfWidth = xTicks[0].width / 2f;
0409: maxX = xTicks[0].x + tickHalfWidth;
0410: int i = 0;
0411: do {
0412: if (getLabelsAxisTicksAlignment() == this .BETWEEN) {
0413: x = (int) (minX + Math
0414: .floor((maxX - minX - setsThickness) / 2f));
0415: } else
0416: x = (int) Math.floor(maxX - setsThickness
0417: / 2f);
0418: x = (int) (x - ((numCompsPerCat - 1) / 2f)
0419: * catDelta);
0420: for (int k = 0; k < numCompsPerCat; ++k) {
0421: for (int j = 0; j < numSets; ++j) {
0422: int compX = x
0423: + j
0424: * componentsThickness
0425: + (componentsThickness - barsThickness)
0426: / 2;
0427: bars[j][i * numCompsPerCat + k] = new FancyBar();
0428: bars[j][i * numCompsPerCat + k]
0429: .setDataSign(getDataSign());
0430: bars[j][i * numCompsPerCat + k]
0431: .setBaseValue(y
0432: - getLinesFillInteriorBaseValue());
0433: if (graphLengths[j][i * numCompsPerCat
0434: + k] > barLowValues[j][i
0435: * numCompsPerCat + k]) {
0436: bars[j][i * numCompsPerCat + k]
0437: .setBounds(new Rectangle2D.Float(
0438: compX + k
0439: * catDelta,
0440: y
0441: - graphLengths[j][i
0442: * numCompsPerCat
0443: + k],
0444: barsThickness,
0445: graphLengths[j][i
0446: * numCompsPerCat
0447: + k]
0448: - barLowValues[j][i
0449: * numCompsPerCat
0450: + k]));
0451: } else {
0452: bars[j][i * numCompsPerCat + k]
0453: .setBounds(new Rectangle2D.Float(
0454: compX + k
0455: * catDelta,
0456: y
0457: - barLowValues[j][i
0458: * numCompsPerCat
0459: + k],
0460: barsThickness,
0461: barLowValues[j][i
0462: * numCompsPerCat
0463: + k]
0464: - graphLengths[j][i
0465: * numCompsPerCat
0466: + k]));
0467: }
0468: Rectangle2D.Float clipBounds = new Rectangle2D.Float(
0469: boundsGraph.x, bars[j][i
0470: * numCompsPerCat + k]
0471: .getBounds().y,
0472: boundsGraph.width, bars[j][i
0473: * numCompsPerCat + k]
0474: .getBounds().height);
0475: bars[j][i * numCompsPerCat + k]
0476: .setClipBounds(clipBounds);
0477: bars[j][i * numCompsPerCat + k]
0478: .setLightBounds(getComponentsLightType() == COMPONENT ? bars[j][i
0479: * numCompsPerCat + k]
0480: .getBounds()
0481: : boundsGraph);
0482: bars[j][i * numCompsPerCat + k]
0483: .setLightSource(getComponentsLightSource());
0484: bars[j][i * numCompsPerCat + k]
0485: .setColor(!getComponentsColoringByCat() ? getBarColors()[j]
0486: : getComponentsColorsByCat()[i]);
0487: bars[j][i * numCompsPerCat + k]
0488: .setOutlineExistence(getOutlineComponents());
0489: bars[j][i * numCompsPerCat + k]
0490: .setOutlineColor(getOutlineComponentsColor());
0491: bars[j][i * numCompsPerCat + k]
0492: .setArcw(getBarRoundingRatio()
0493: * barsThickness);
0494: bars[j][i * numCompsPerCat + k]
0495: .setArch(getBarRoundingRatio()
0496: * barsThickness);
0497: bars[j][i * numCompsPerCat + k]
0498: .setWarningRegions(getWarningRegions());
0499: bars[j][i * numCompsPerCat + k]
0500: .setType(FancyShape.LABELSBOTTOM);
0501: bars[j][i * numCompsPerCat + k]
0502: .setGraphBounds(boundsGraph);
0503: }
0504: }
0505: if (i + 1 == numBars)
0506: break;
0507: minX = maxX;
0508: if (i + 2 == numBars
0509: && getLabelsAxisTicksAlignment() == this .BETWEEN) {
0510: maxX = getSpaceSizeLocation(MIN).x
0511: + getSpaceSize(MIN).width;
0512: } else
0513: maxX = xTicks[i + 1].x + tickHalfWidth;
0514: ++i;
0515: } while (true);
0516: }
0517: }
0518:
0519: dots = new FancyDot[numSets][numDots * numCompsPerCat];
0520: if (numDots > 0) {
0521: int y = getSpaceSizeLocation(MIN).y
0522: + getSpaceSize(MIN).height - dotsThickness / 2, x;
0523: float catDelta = getSpaceSize(MIN).width
0524: / (float) (numDots * numCompsPerCat);
0525: if (numDots == 1) {
0526: x = getSpaceSizeLocation(MIN).x
0527: + (getSpaceSize(MIN).width - setsThickness)
0528: / 2;
0529: x = (int) (x - ((numCompsPerCat - 1) / 2f)
0530: * catDelta);
0531: for (int k = 0; k < numCompsPerCat; ++k) {
0532: for (int j = 0; j < numSets; ++j) {
0533: int compX = x
0534: + j
0535: * componentsThickness
0536: + (componentsThickness - dotsThickness)
0537: / 2;
0538: dots[j][k] = new FancyDot();
0539: dots[j][k].setBounds(new Rectangle2D.Float(
0540: compX + k * catDelta, y
0541: - graphLengths[j][k],
0542: dotsThickness, dotsThickness));
0543: dots[j][k].setClipBounds(dots[j][k]
0544: .getBounds());
0545: dots[j][k]
0546: .setColor(!getComponentsColoringByCat() ? getDotColors()[j]
0547: : getComponentsColorsByCat()[0]);
0548: dots[j][k]
0549: .setOutlineExistence(getOutlineComponents());
0550: dots[j][k]
0551: .setOutlineColor(getOutlineComponentsColor());
0552: dots[j][k]
0553: .setLightBounds(getComponentsLightType() == COMPONENT ? dots[j][k]
0554: .getBounds()
0555: : boundsGraph);
0556: dots[j][k]
0557: .setLightSource(getComponentsLightSource());
0558: dots[j][k]
0559: .setWarningRegions(getWarningRegions());
0560: dots[j][k].setType(FancyShape.LABELSBOTTOM);
0561: }
0562: }
0563: } else {
0564: float minX, maxX, tickHalfWidth;
0565: minX = getSpaceSizeLocation(MIN).x;
0566: tickHalfWidth = xTicks[0].width / 2f;
0567: maxX = xTicks[0].x + tickHalfWidth;
0568: int i = 0;
0569: do {
0570: if (getLabelsAxisTicksAlignment() == this .BETWEEN) {
0571: x = (int) (minX + Math
0572: .floor((maxX - minX - setsThickness) / 2f));
0573: } else
0574: x = (int) Math.floor(maxX - setsThickness
0575: / 2f);
0576: x = (int) (x - ((numCompsPerCat - 1) / 2f)
0577: * catDelta);
0578: for (int k = 0; k < numCompsPerCat; ++k) {
0579: for (int j = 0; j < numSets; ++j) {
0580: int compX = x
0581: + j
0582: * componentsThickness
0583: + (componentsThickness - dotsThickness)
0584: / 2;
0585: dots[j][i * numCompsPerCat + k] = new FancyDot();
0586: dots[j][i * numCompsPerCat + k]
0587: .setBounds(new Rectangle2D.Float(
0588: compX + k * catDelta,
0589: y
0590: - graphLengths[j][i
0591: * numCompsPerCat
0592: + k],
0593: dotsThickness,
0594: dotsThickness));
0595: dots[j][i * numCompsPerCat + k]
0596: .setClipBounds(dots[j][i
0597: * numCompsPerCat + k]
0598: .getBounds());
0599: dots[j][i * numCompsPerCat + k]
0600: .setColor(!getComponentsColoringByCat() ? getDotColors()[j]
0601: : getComponentsColorsByCat()[i]);
0602: dots[j][i * numCompsPerCat + k]
0603: .setOutlineExistence(getOutlineComponents());
0604: dots[j][i * numCompsPerCat + k]
0605: .setOutlineColor(getOutlineComponentsColor());
0606: dots[j][i * numCompsPerCat + k]
0607: .setLightBounds(getComponentsLightType() == COMPONENT ? dots[j][i
0608: * numCompsPerCat + k]
0609: .getBounds()
0610: : boundsGraph);
0611: dots[j][i * numCompsPerCat + k]
0612: .setLightSource(getComponentsLightSource());
0613: dots[j][i * numCompsPerCat + k]
0614: .setWarningRegions(getWarningRegions());
0615: dots[j][i * numCompsPerCat + k]
0616: .setType(FancyShape.LABELSBOTTOM);
0617: }
0618: }
0619: if (i + 1 == numDots)
0620: break;
0621: minX = maxX;
0622: if (i + 2 == numDots
0623: && getLabelsAxisTicksAlignment() == this .BETWEEN) {
0624: maxX = getSpaceSizeLocation(MIN).x
0625: + getSpaceSize(MIN).width;
0626: } else
0627: maxX = xTicks[i + 1].x + tickHalfWidth;
0628: ++i;
0629: } while (true);
0630: }
0631: }
0632:
0633: if ((numCats * numCompsPerCat) < 2 || linesThickness < 1)
0634: lines = new FancyLine[0];
0635: else {
0636: lines = new FancyLine[numSets];
0637: int y = getSpaceSizeLocation(MIN).y
0638: + getSpaceSize(MIN).height, x;
0639: for (int i = 0; i < numSets; ++i) {
0640: lines[i] = new FancyLine();
0641: lines[i].setThickness(linesThickness);
0642: lines[i].setFillArea(getLinesFillInterior());
0643: lines[i].setColor(getLineColors()[i]);
0644: lines[i]
0645: .setOutlineExistence(getOutlineComponents());
0646: lines[i]
0647: .setOutlineColor(getOutlineComponentsColor());
0648: lines[i].setLightSource(getComponentsLightSource());
0649: lines[i].setWarningRegions(getWarningRegions());
0650: lines[i].setType(FancyShape.LABELSBOTTOM);
0651: }
0652: Point firstPoints[] = new Point[numSets];
0653: float minX, maxX, tickHalfWidth;
0654: minX = getSpaceSizeLocation(MIN).x;
0655: tickHalfWidth = xTicks[0].width / 2f;
0656: maxX = xTicks[0].x + tickHalfWidth;
0657: float catDelta = getSpaceSize(MIN).width
0658: / (float) (numLinePoints * numCompsPerCat);
0659: int i = 0;
0660: do {
0661: if (getLabelsAxisTicksAlignment() == BETWEEN) {
0662: x = (int) (minX + Math
0663: .floor((maxX - minX - setsThickness) / 2f));
0664: } else
0665: x = (int) Math.floor(maxX - setsThickness / 2f);
0666: x = (int) (x - ((numCompsPerCat - 1) / 2f)
0667: * catDelta);
0668: for (int k = 0; k < numCompsPerCat; ++k) {
0669: for (int j = 0; j < numSets; ++j) {
0670: int compX = x + j * componentsThickness
0671: + componentsThickness / 2;
0672: Point this Point = new Point(
0673: (int) (compX + k * catDelta),
0674: (int) (y - graphLengths[j][i
0675: * numCompsPerCat + k]));
0676: if (k == 0 && i == 0) {
0677: if (getLinesFillInterior()) {
0678: firstPoints[j] = new Point(
0679: (int) (compX + k * catDelta),
0680: y
0681: - getLinesFillInteriorBaseValue());
0682: lines[j].getLine().moveTo(
0683: firstPoints[j].x,
0684: firstPoints[j].y);
0685: lines[j].getLine().lineTo(
0686: this Point.x, this Point.y);
0687: } else {
0688: lines[j].getLine().moveTo(
0689: this Point.x, this Point.y);
0690: }
0691: } else {
0692: lines[j].getLine().lineTo(this Point.x,
0693: this Point.y);
0694: if (getLinesFillInterior()
0695: && k == numCompsPerCat - 1
0696: && i == numLinePoints - 1) {
0697: lines[j].getLine().lineTo(
0698: this Point.x,
0699: firstPoints[j].y);
0700: lines[j].getLine().lineTo(
0701: firstPoints[j].x,
0702: firstPoints[j].y);
0703: }
0704: }
0705: }
0706: }
0707: if (i + 1 == numLinePoints)
0708: break;
0709: minX = maxX;
0710: if (i + 2 == numLinePoints
0711: && getLabelsAxisTicksAlignment() == this .BETWEEN) {
0712: maxX = getSpaceSizeLocation(MIN).x
0713: + getSpaceSize(MIN).width;
0714: } else
0715: maxX = xTicks[i + 1].x + tickHalfWidth;
0716: ++i;
0717: } while (true);
0718: for (int g = 0; g < numSets; ++g) {
0719: lines[g].setClipBounds(boundsGraph);
0720: Rectangle2D.Float bounds = (Rectangle2D.Float) lines[g]
0721: .getLine().getBounds2D();
0722: lines[g]
0723: .setLightBounds(getComponentsLightType() == COMPONENT ? bounds
0724: : boundsGraph);
0725: }
0726: }
0727: } else {
0728: bars = new FancyBar[0][0];
0729: dots = new FancyDot[0][0];
0730: lines = new FancyLine[0];
0731: }
0732: }
0733:
0734: private void updateAllowAlignment() {
0735:
0736: int[][] graphLengths = getGraphValues();
0737: int numBars = 0, numDots = 0, numLinePoints = 0, numGaps = 0;
0738: int numSets = graphLengths.length;
0739: Rectangle[] xTicks = getXTicks();
0740: int numCompsPerCat = 0;
0741: int numCats = 0;
0742: if (numSets > 0) {
0743: numCats = getLabelsAxisTicksAlignment() == BETWEEN ? xTicks.length + 1
0744: : xTicks.length;
0745: numBars = getBarsExistence() ? numCats : 0;
0746: numDots = getDotsExistence() ? numCats : 0;
0747: numLinePoints = getLinesExistence() ? numCats : 0;
0748: numGaps = getBetweenComponentsGapExistence() ? numCats : 0;
0749: numCompsPerCat = numCats > 0 ? (int) (graphLengths[0].length / numCats)
0750: : 0;
0751: }
0752:
0753: if (numSets > 0 && numCats > 0 && numCompsPerCat > 0) {
0754: float ratio = getRatio(WIDTH);
0755: int availableThickness = getSpaceSize(MIN).width;
0756:
0757: int betweenComponentsGapThickness = 0;
0758: if (numGaps > 0) {
0759: betweenComponentsGapThickness = applyRatio(
0760: getBetweenComponentsGapThicknessModel(), ratio);
0761: betweenComponentsGapThickness = numGaps
0762: * betweenComponentsGapThickness <= availableThickness ? betweenComponentsGapThickness
0763: : availableThickness / numGaps;
0764: availableThickness -= numGaps
0765: * betweenComponentsGapThickness;
0766: }
0767:
0768: int barsThickness = 0;
0769: if (numBars > 0) {
0770: barsThickness = applyRatio(getBarsThicknessModel(),
0771: ratio);
0772: if (numBars * numCompsPerCat * barsThickness <= availableThickness) {
0773: float leftover = (availableThickness - barsThickness
0774: * (numBars * numCompsPerCat))
0775: / (numBars * numCompsPerCat);
0776: barsThickness = barsThickness
0777: + (int) (getBarsExcessSpaceFeedbackRatio() * leftover);
0778: } else {
0779: float numOverlapBarsPerCat = (1 + (1 - getBarsWithinCategoryOverlapRatio())
0780: * (numCompsPerCat - 1));
0781: if (numBars * numOverlapBarsPerCat * barsThickness > availableThickness) {
0782: barsThickness = (int) (availableThickness / (numBars * numOverlapBarsPerCat));
0783: }
0784: }
0785: }
0786: int dotsThickness = 0;
0787: if (numDots > 0) {
0788: dotsThickness = applyRatio(getDotsThicknessModel(),
0789: getRatio(LESSER));
0790: if (numDots * numCompsPerCat * dotsThickness <= availableThickness) {
0791: float leftover = (availableThickness - dotsThickness
0792: * (numDots * numCompsPerCat))
0793: / (numDots * numCompsPerCat);
0794: dotsThickness = dotsThickness
0795: + (int) (getDotsExcessSpaceFeedbackRatio() * leftover);
0796: } else {
0797: float numOverlapDotsPerCat = (1 + (1 - getDotsWithinCategoryOverlapRatio())
0798: * (numCompsPerCat - 1));
0799: if (numDots * numOverlapDotsPerCat * dotsThickness > availableThickness) {
0800: dotsThickness = (int) (availableThickness / (numDots * numOverlapDotsPerCat));
0801: }
0802: }
0803: }
0804: int linesThickness = 0;
0805: if (numLinePoints > 0) {
0806: linesThickness = applyRatio(getLinesThicknessModel(),
0807: getRatio(LESSER));
0808: if (numLinePoints * numCompsPerCat * linesThickness <= availableThickness) {
0809: float leftover = (availableThickness - linesThickness
0810: * (numLinePoints * numCompsPerCat))
0811: / (numLinePoints * numCompsPerCat);
0812: linesThickness = linesThickness
0813: + (int) (getLinesExcessSpaceFeedbackRatio() * leftover);
0814: } else {
0815: float numOverlapLinesPerCat = (1 + (1 - getLinesWithinCategoryOverlapRatio())
0816: * (numCompsPerCat - 1));
0817: if (numLinePoints * numOverlapLinesPerCat
0818: * linesThickness > availableThickness) {
0819: linesThickness = (int) (availableThickness / (numLinePoints * numOverlapLinesPerCat));
0820: }
0821: }
0822: }
0823:
0824: Rectangle2D.Float boundsGraph = new Rectangle2D.Float(
0825: getSpaceSizeLocation(MIN).x,
0826: getSpaceSizeLocation(MIN).y,
0827: getSpaceSize(MIN).width, getSpaceSize(MIN).height);
0828:
0829: bars = new FancyBar[numSets][numBars * numCompsPerCat];
0830: int[][] barLowValues = getBarLowValues();
0831: if (numBars > 0) {
0832: int y = getSpaceSizeLocation(MIN).y
0833: + getSpaceSize(MIN).height, x;
0834: float catDelta = getSpaceSize(MIN).width
0835: / (float) (numBars * numCompsPerCat);
0836: if (numBars == 1) {
0837: x = getSpaceSizeLocation(MIN).x
0838: + (getSpaceSize(MIN).width - barsThickness)
0839: / 2;
0840: x = (int) (x - ((numCompsPerCat - 1) / 2f)
0841: * catDelta);
0842: for (int k = 0; k < numCompsPerCat; ++k) {
0843: for (int j = 0; j < numSets; ++j) {
0844: bars[j][k] = new FancyBar();
0845: bars[j][k].setDataSign(getDataSign());
0846: bars[j][k].setBaseValue(y
0847: - getLinesFillInteriorBaseValue());
0848: if (graphLengths[j][k] > barLowValues[j][k]) {
0849: bars[j][k]
0850: .setBounds(new Rectangle2D.Float(
0851: x + k * catDelta,
0852: y - graphLengths[j][k],
0853: barsThickness,
0854: graphLengths[j][k]
0855: - barLowValues[j][k]));
0856: } else {
0857: bars[j][k]
0858: .setBounds(new Rectangle2D.Float(
0859: x + k * catDelta,
0860: y - barLowValues[j][k],
0861: barsThickness,
0862: barLowValues[j][k]
0863: - graphLengths[j][k]));
0864: }
0865: Rectangle2D.Float clipBounds = new Rectangle2D.Float(
0866: boundsGraph.x, bars[j][k]
0867: .getBounds().y,
0868: boundsGraph.width, bars[j][k]
0869: .getBounds().height);
0870: bars[j][k].setClipBounds(clipBounds);
0871: bars[j][k]
0872: .setLightBounds(getComponentsLightType() == COMPONENT ? bars[j][k]
0873: .getBounds()
0874: : boundsGraph);
0875: bars[j][k]
0876: .setLightSource(getComponentsLightSource());
0877: bars[j][k]
0878: .setColor(!getComponentsColoringByCat() ? getBarColors()[j]
0879: : getComponentsColorsByCat()[0]);
0880: bars[j][k]
0881: .setOutlineExistence(getOutlineComponents());
0882: bars[j][k]
0883: .setOutlineColor(getOutlineComponentsColor());
0884: bars[j][k].setArcw(getBarRoundingRatio()
0885: * barsThickness);
0886: bars[j][k].setArch(getBarRoundingRatio()
0887: * barsThickness);
0888: bars[j][k]
0889: .setWarningRegions(getWarningRegions());
0890: bars[j][k].setType(FancyShape.LABELSBOTTOM);
0891: bars[j][k].setGraphBounds(boundsGraph);
0892: }
0893: }
0894: } else {
0895: float minX, maxX, tickHalfWidth;
0896: minX = getSpaceSizeLocation(MIN).x;
0897: tickHalfWidth = xTicks[0].width / 2f;
0898: maxX = xTicks[0].x + tickHalfWidth;
0899: int i = 0;
0900: do {
0901: if (getLabelsAxisTicksAlignment() == BETWEEN) {
0902: x = (int) (minX + Math
0903: .floor((maxX - minX - barsThickness) / 2f));
0904: } else
0905: x = (int) Math.floor(maxX - barsThickness
0906: / 2f);
0907: x = (int) (x - ((numCompsPerCat - 1) / 2f)
0908: * catDelta);
0909: for (int k = 0; k < numCompsPerCat; ++k) {
0910: for (int j = 0; j < numSets; ++j) {
0911: bars[j][i * numCompsPerCat + k] = new FancyBar();
0912: bars[j][i * numCompsPerCat + k]
0913: .setDataSign(getDataSign());
0914: bars[j][i * numCompsPerCat + k]
0915: .setBaseValue(y
0916: - getLinesFillInteriorBaseValue());
0917: if (graphLengths[j][i * numCompsPerCat
0918: + k] > barLowValues[j][i
0919: * numCompsPerCat + k]) {
0920: bars[j][i * numCompsPerCat + k]
0921: .setBounds(new Rectangle2D.Float(
0922: x + k * catDelta,
0923: y
0924: - graphLengths[j][i
0925: * numCompsPerCat
0926: + k],
0927: barsThickness,
0928: graphLengths[j][i
0929: * numCompsPerCat
0930: + k]
0931: - barLowValues[j][i
0932: * numCompsPerCat
0933: + k]));
0934: } else {
0935: bars[j][i * numCompsPerCat + k]
0936: .setBounds(new Rectangle2D.Float(
0937: (int) (x + k
0938: * catDelta),
0939: y
0940: - barLowValues[j][i
0941: * numCompsPerCat
0942: + k],
0943: barsThickness,
0944: barLowValues[j][i
0945: * numCompsPerCat
0946: + k]
0947: - graphLengths[j][i
0948: * numCompsPerCat
0949: + k]));
0950: }
0951: Rectangle2D.Float clipBounds = new Rectangle2D.Float(
0952: boundsGraph.x, bars[j][i
0953: * numCompsPerCat + k]
0954: .getBounds().y,
0955: boundsGraph.width, bars[j][i
0956: * numCompsPerCat + k]
0957: .getBounds().height);
0958: bars[j][i * numCompsPerCat + k]
0959: .setClipBounds(clipBounds);
0960: bars[j][i * numCompsPerCat + k]
0961: .setLightBounds(getComponentsLightType() == COMPONENT ? bars[j][i
0962: * numCompsPerCat + k]
0963: .getBounds()
0964: : boundsGraph);
0965: bars[j][i * numCompsPerCat + k]
0966: .setLightSource(getComponentsLightSource());
0967: bars[j][i * numCompsPerCat + k]
0968: .setColor(!getComponentsColoringByCat() ? getBarColors()[j]
0969: : getComponentsColorsByCat()[i]);
0970: bars[j][i * numCompsPerCat + k]
0971: .setOutlineExistence(getOutlineComponents());
0972: bars[j][i * numCompsPerCat + k]
0973: .setOutlineColor(getOutlineComponentsColor());
0974: bars[j][i * numCompsPerCat + k]
0975: .setArcw(getBarRoundingRatio()
0976: * barsThickness);
0977: bars[j][i * numCompsPerCat + k]
0978: .setArch(getBarRoundingRatio()
0979: * barsThickness);
0980: bars[j][i * numCompsPerCat + k]
0981: .setWarningRegions(getWarningRegions());
0982: bars[j][i * numCompsPerCat + k]
0983: .setType(FancyShape.LABELSBOTTOM);
0984: bars[j][i * numCompsPerCat + k]
0985: .setGraphBounds(boundsGraph);
0986: }
0987: }
0988: if (i + 1 == numBars)
0989: break;
0990: minX = maxX;
0991: if (i + 2 == numBars
0992: && getLabelsAxisTicksAlignment() == BETWEEN) {
0993: maxX = getSpaceSizeLocation(MIN).x
0994: + getSpaceSize(MIN).width;
0995: } else
0996: maxX = xTicks[i + 1].x + tickHalfWidth;
0997: ++i;
0998: } while (true);
0999: }
1000: }
1001:
1002: dots = new FancyDot[numSets][numDots * numCompsPerCat];
1003: if (numDots > 0) {
1004: int y = getSpaceSizeLocation(MIN).y
1005: + getSpaceSize(MIN).height - dotsThickness / 2, x;
1006: float catDelta = getSpaceSize(MIN).width
1007: / (float) (numDots * numCompsPerCat);
1008: if (numDots == 1) {
1009: x = getSpaceSizeLocation(MIN).x
1010: + (getSpaceSize(MIN).width - dotsThickness)
1011: / 2;
1012: x = (int) (x - ((numCompsPerCat - 1) / 2f)
1013: * catDelta);
1014: for (int k = 0; k < numCompsPerCat; ++k) {
1015: for (int j = 0; j < numSets; ++j) {
1016: dots[j][k] = new FancyDot();
1017: dots[j][k].setBounds(new Rectangle2D.Float(
1018: x + k * catDelta, y
1019: - graphLengths[j][k],
1020: dotsThickness, dotsThickness));
1021: dots[j][k].setClipBounds(dots[j][k]
1022: .getBounds());
1023: dots[j][k]
1024: .setColor(!getComponentsColoringByCat() ? getDotColors()[j]
1025: : getComponentsColorsByCat()[0]);
1026: dots[j][k]
1027: .setOutlineExistence(getOutlineComponents());
1028: dots[j][k]
1029: .setOutlineColor(getOutlineComponentsColor());
1030: dots[j][k]
1031: .setLightBounds(getComponentsLightType() == COMPONENT ? dots[j][k]
1032: .getBounds()
1033: : boundsGraph);
1034: dots[j][k]
1035: .setLightSource(getComponentsLightSource());
1036: dots[j][k]
1037: .setWarningRegions(getWarningRegions());
1038: dots[j][k].setType(FancyShape.LABELSBOTTOM);
1039: }
1040: }
1041: } else {
1042: float minX, maxX, tickHalfWidth;
1043: minX = getSpaceSizeLocation(MIN).x;
1044: tickHalfWidth = xTicks[0].width / 2f;
1045: maxX = xTicks[0].x + tickHalfWidth;
1046: int i = 0;
1047: do {
1048: if (getLabelsAxisTicksAlignment() == this .BETWEEN) {
1049: x = (int) (minX + Math
1050: .floor((maxX - minX - dotsThickness) / 2f));
1051: } else
1052: x = (int) Math.floor(maxX - dotsThickness
1053: / 2f);
1054: x = (int) (x - ((numCompsPerCat - 1) / 2f)
1055: * catDelta);
1056: for (int k = 0; k < numCompsPerCat; ++k) {
1057: for (int j = 0; j < numSets; ++j) {
1058: dots[j][i * numCompsPerCat + k] = new FancyDot();
1059: dots[j][i * numCompsPerCat + k]
1060: .setBounds(new Rectangle2D.Float(
1061: x + k * catDelta,
1062: y
1063: - graphLengths[j][i
1064: * numCompsPerCat
1065: + k],
1066: dotsThickness,
1067: dotsThickness));
1068: dots[j][i * numCompsPerCat + k]
1069: .setClipBounds(dots[j][i
1070: * numCompsPerCat + k]
1071: .getBounds());
1072: dots[j][i * numCompsPerCat + k]
1073: .setColor(!getComponentsColoringByCat() ? getDotColors()[j]
1074: : getComponentsColorsByCat()[i]);
1075: dots[j][i * numCompsPerCat + k]
1076: .setOutlineExistence(getOutlineComponents());
1077: dots[j][i * numCompsPerCat + k]
1078: .setOutlineColor(getOutlineComponentsColor());
1079: dots[j][i * numCompsPerCat + k]
1080: .setLightBounds(getComponentsLightType() == COMPONENT ? dots[j][i
1081: * numCompsPerCat + k]
1082: .getBounds()
1083: : boundsGraph);
1084: dots[j][i * numCompsPerCat + k]
1085: .setLightSource(getComponentsLightSource());
1086: dots[j][i * numCompsPerCat + k]
1087: .setWarningRegions(getWarningRegions());
1088: dots[j][i * numCompsPerCat + k]
1089: .setType(FancyShape.LABELSBOTTOM);
1090: }
1091: }
1092: if (i + 1 == numDots)
1093: break;
1094: minX = maxX;
1095: if (i + 2 == numDots
1096: && getLabelsAxisTicksAlignment() == this .BETWEEN) {
1097: maxX = getSpaceSizeLocation(MIN).x
1098: + getSpaceSize(MIN).width;
1099: } else
1100: maxX = xTicks[i + 1].x + tickHalfWidth;
1101: ++i;
1102: } while (true);
1103: }
1104: }
1105:
1106: if ((numCats * numCompsPerCat) < 2 || linesThickness < 1)
1107: lines = new FancyLine[0];
1108: else {
1109: lines = new FancyLine[numSets];
1110: int y = getSpaceSizeLocation(MIN).y
1111: + getSpaceSize(MIN).height, x;
1112: for (int i = 0; i < numSets; ++i) {
1113: lines[i] = new FancyLine();
1114: lines[i].setThickness(linesThickness);
1115: lines[i].setFillArea(getLinesFillInterior());
1116: lines[i].setColor(getLineColors()[i]);
1117: lines[i]
1118: .setOutlineExistence(getOutlineComponents());
1119: lines[i]
1120: .setOutlineColor(getOutlineComponentsColor());
1121: lines[i].setLightSource(getComponentsLightSource());
1122: lines[i].setWarningRegions(getWarningRegions());
1123: lines[i].setType(FancyShape.LABELSBOTTOM);
1124: }
1125: Point firstPoints[] = new Point[numSets];
1126: float minX, maxX, tickHalfWidth;
1127: minX = getSpaceSizeLocation(MIN).x;
1128: tickHalfWidth = xTicks[0].width / 2f;
1129: maxX = xTicks[0].x + tickHalfWidth;
1130: float catDelta = getSpaceSize(MIN).width
1131: / (float) (numLinePoints * numCompsPerCat);
1132: int i = 0;
1133: do {
1134: if (getLabelsAxisTicksAlignment() == Area.BETWEEN) {
1135: x = (int) (minX + Math
1136: .floor((maxX - minX) / 2f));
1137: } else {
1138: x = (int) maxX;
1139: }
1140: x = (int) (x - ((numCompsPerCat - 1) / 2f)
1141: * catDelta);
1142: for (int k = 0; k < numCompsPerCat; ++k) {
1143: for (int j = 0; j < numSets; ++j) {
1144: Point this Point = new Point((int) (x + k
1145: * catDelta),
1146: (int) (y - graphLengths[j][i
1147: * numCompsPerCat + k]));
1148: if (k == 0 && i == 0) {
1149: if (getLinesFillInterior()) {
1150: firstPoints[j] = new Point(
1151: (int) (x + k * catDelta),
1152: y
1153: - getLinesFillInteriorBaseValue());
1154: lines[j].getLine().moveTo(
1155: firstPoints[j].x,
1156: firstPoints[j].y);
1157: lines[j].getLine().lineTo(
1158: this Point.x, this Point.y);
1159: } else {
1160: lines[j].getLine().moveTo(
1161: this Point.x, this Point.y);
1162: }
1163: } else {
1164: lines[j].getLine().lineTo(this Point.x,
1165: this Point.y);
1166: if (getLinesFillInterior()
1167: && k == numCompsPerCat - 1
1168: && i == numLinePoints - 1) {
1169: lines[j].getLine().lineTo(
1170: this Point.x,
1171: firstPoints[j].y);
1172: lines[j].getLine().lineTo(
1173: firstPoints[j].x,
1174: firstPoints[j].y);
1175: }
1176: }
1177: }
1178: }
1179: if (i + 1 == numLinePoints)
1180: break;
1181: minX = maxX;
1182: if (i + 2 == numLinePoints
1183: && getLabelsAxisTicksAlignment() == this .BETWEEN) {
1184: maxX = getSpaceSizeLocation(MIN).x
1185: + getSpaceSize(MIN).width;
1186: } else
1187: maxX = xTicks[i + 1].x + tickHalfWidth;
1188: ++i;
1189: } while (true);
1190: for (int g = 0; g < numSets; ++g) {
1191: lines[g].setClipBounds(boundsGraph);
1192: Rectangle2D.Float bounds = (Rectangle2D.Float) lines[g]
1193: .getLine().getBounds2D();
1194: lines[g]
1195: .setLightBounds(getComponentsLightType() == COMPONENT ? bounds
1196: : boundsGraph);
1197: }
1198: }
1199: } else {
1200: bars = new FancyBar[0][0];
1201: dots = new FancyDot[0][0];
1202: lines = new FancyLine[0];
1203: }
1204: }
1205: }
|