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