00001
00002
00003
00004
00005
00006
00007 package org.swtchart.internal.axis;
00008
00009 import java.math.BigDecimal;
00010 import java.text.DecimalFormat;
00011 import java.text.Format;
00012 import java.text.SimpleDateFormat;
00013 import java.util.ArrayList;
00014 import java.util.Calendar;
00015 import java.util.Date;
00016 import java.util.HashMap;
00017 import java.util.Map;
00018
00019 import org.eclipse.swt.SWT;
00020 import org.eclipse.swt.events.PaintEvent;
00021 import org.eclipse.swt.events.PaintListener;
00022 import org.eclipse.swt.graphics.Color;
00023 import org.eclipse.swt.graphics.Font;
00024 import org.eclipse.swt.graphics.GC;
00025 import org.eclipse.swt.graphics.Point;
00026 import org.eclipse.swt.graphics.Rectangle;
00027 import org.eclipse.swt.graphics.Transform;
00028 import org.eclipse.swt.widgets.Display;
00029 import org.swtchart.Chart;
00030 import org.swtchart.IAxis.Position;
00031 import org.swtchart.internal.ChartLayoutData;
00032 import org.swtchart.internal.Util;
00033
00037 public class AxisTickLabels implements PaintListener {
00038
00040 private final Chart chart;
00041
00043 private final Axis axis;
00044
00046 private Color foreground;
00047
00049 private int widthHint;
00050
00052 private int heightHint;
00053
00055 private Rectangle bounds;
00056
00058 private final ArrayList<Double> tickLabelValues;
00059
00061 private final ArrayList<String> tickLabels;
00062
00064 private final ArrayList<Integer> tickLabelPositions;
00065
00067 private final ArrayList<Boolean> tickVisibilities;
00068
00070 private Format format;
00071
00073 private static final int DEFAULT_FOREGROUND = SWT.COLOR_BLUE;
00074
00076 private static final Font DEFAULT_FONT = Display.getDefault()
00077 .getSystemFont();
00078
00080 private static final String DEFAULT_DECIMAL_FORMAT = "#.###########";
00081
00083 private Map<Integer, Integer[]> possibleTickSteps;
00084
00086 private int timeUnit;
00087
00089 private Font font;
00090
00099 protected AxisTickLabels(Chart chart, Axis axis) {
00100 this.chart = chart;
00101 this.axis = axis;
00102
00103 tickLabelValues = new ArrayList<Double>();
00104 tickLabels = new ArrayList<String>();
00105 tickLabelPositions = new ArrayList<Integer>();
00106 tickVisibilities = new ArrayList<Boolean>();
00107
00108 initializePossibleTickSteps();
00109
00110 font = DEFAULT_FONT;
00111 foreground = Display.getDefault().getSystemColor(DEFAULT_FOREGROUND);
00112 chart.addPaintListener(this);
00113 }
00114
00118 private void initializePossibleTickSteps() {
00119 final Integer[] milliseconds = { 1, 2, 5, 10, 20, 50, 100, 200, 500,
00120 999 };
00121 final Integer[] seconds = { 1, 2, 5, 10, 15, 20, 30, 59 };
00122 final Integer[] minutes = { 1, 2, 3, 5, 10, 15, 20, 30, 59 };
00123 final Integer[] hours = { 1, 2, 3, 4, 6, 12, 22 };
00124 final Integer[] dates = { 1, 7, 14, 28 };
00125 final Integer[] months = { 1, 2, 3, 4, 6, 11 };
00126 final Integer[] years = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 };
00127
00128 possibleTickSteps = new HashMap<Integer, Integer[]>();
00129 possibleTickSteps.put(Calendar.MILLISECOND, milliseconds);
00130 possibleTickSteps.put(Calendar.SECOND, seconds);
00131 possibleTickSteps.put(Calendar.MINUTE, minutes);
00132 possibleTickSteps.put(Calendar.HOUR_OF_DAY, hours);
00133 possibleTickSteps.put(Calendar.DATE, dates);
00134 possibleTickSteps.put(Calendar.MONTH, months);
00135 possibleTickSteps.put(Calendar.YEAR, years);
00136 }
00137
00144 public void setForeground(Color color) {
00145 if (color == null) {
00146 foreground = Display.getDefault()
00147 .getSystemColor(DEFAULT_FOREGROUND);
00148 } else {
00149 foreground = color;
00150 }
00151 }
00152
00158 protected Color getForeground() {
00159 if (foreground.isDisposed()) {
00160 foreground = Display.getDefault()
00161 .getSystemColor(DEFAULT_FOREGROUND);
00162 }
00163 return foreground;
00164 }
00165
00172 protected void update(int length) {
00173 tickLabelValues.clear();
00174 tickLabels.clear();
00175 tickLabelPositions.clear();
00176
00177 if (axis.isValidCategoryAxis()) {
00178 updateTickLabelForCategoryAxis(length);
00179 } else if (axis.isLogScaleEnabled()) {
00180 updateTickLabelForLogScale(length);
00181 } else if (axis.isDateEnabled()) {
00182 updateTickLabelForDateAxis(length);
00183 } else {
00184 updateTickLabelForLinearScale(length);
00185 }
00186
00187 updateTickVisibility();
00188 }
00189
00196 private void updateTickLabelForDateAxis(int length) {
00197 double min = axis.getRange().lower;
00198 double max = axis.getRange().upper;
00199
00200 double gridStepHint = Math.abs(max - min) / length
00201 * axis.getTick().getTickMarkStepHint();
00202
00203 timeUnit = getTimeUnit(gridStepHint);
00204
00205 if (timeUnit == Calendar.MILLISECOND || timeUnit == Calendar.SECOND
00206 || timeUnit == Calendar.MINUTE
00207 || timeUnit == Calendar.HOUR_OF_DAY
00208 || timeUnit == Calendar.DATE) {
00209
00210 Integer[] steps = possibleTickSteps.get(timeUnit);
00211 for (int i = 0; i < steps.length - 1; i++) {
00212 if (gridStepHint < (getPeriodInMillis(timeUnit, steps[i]) + getPeriodInMillis(
00213 timeUnit, steps[i + 1])) / 2d) {
00214 BigDecimal gridStep = BigDecimal.valueOf(getPeriodInMillis(
00215 timeUnit, steps[i]));
00216 updateTickLabelForLinearScale(length, gridStep);
00217 break;
00218 }
00219 }
00220 } else if (timeUnit == Calendar.MONTH || timeUnit == Calendar.YEAR) {
00221
00222 updateTickLabelForMonthOrYear(length, gridStepHint, timeUnit);
00223 }
00224 }
00225
00238 private void updateTickLabelForMonthOrYear(int length, double gridStepHint,
00239 int tickStepUnit) {
00240 double min = axis.getRange().lower;
00241 double max = axis.getRange().upper;
00242
00243
00244 Calendar cal = Calendar.getInstance();
00245 cal.setTime(new Date((long) min));
00246 int month = cal.get(Calendar.MONTH);
00247 int year = cal.get(Calendar.YEAR);
00248 if (tickStepUnit == Calendar.MONTH) {
00249 if (month == Calendar.DECEMBER) {
00250 year++;
00251 month = Calendar.JANUARY;
00252 } else {
00253 month++;
00254 }
00255 } else if (tickStepUnit == Calendar.YEAR) {
00256 month = Calendar.JANUARY;
00257 year++;
00258 }
00259
00260
00261 Integer[] steps = possibleTickSteps.get(tickStepUnit);
00262 int step = steps[steps.length - 1];
00263 for (int i = 0; i < steps.length - 1; i++) {
00264 if (gridStepHint < (getPeriodInMillis(tickStepUnit, steps[i]) + getPeriodInMillis(
00265 tickStepUnit, steps[i + 1])) / 2d) {
00266 step = steps[i];
00267 break;
00268 }
00269 }
00270
00271
00272 cal.clear();
00273 cal.set(year, month, 1);
00274 while (cal.getTimeInMillis() < max) {
00275 tickLabelValues.add(Double.valueOf(cal.getTimeInMillis()));
00276 tickLabels.add(format(cal.getTimeInMillis()));
00277 int tickLabelPosition = (int) ((cal.getTimeInMillis() - min)
00278 / (max - min) * length);
00279 tickLabelPositions.add(tickLabelPosition);
00280 if (tickStepUnit == Calendar.MONTH) {
00281 month += step;
00282 if (month + step > Calendar.DECEMBER) {
00283 year++;
00284 month -= Calendar.DECEMBER + 1;
00285 }
00286 } else if (tickStepUnit == Calendar.YEAR) {
00287 year += step;
00288 }
00289 cal.clear();
00290 cal.set(year, month, 1);
00291 }
00292 }
00293
00300 private void updateTickLabelForCategoryAxis(int length) {
00301 String[] series = axis.getCategorySeries();
00302 if (series == null) {
00303 return;
00304 }
00305
00306 int min = (int) axis.getRange().lower;
00307 int max = (int) axis.getRange().upper;
00308
00309 int sizeOfTickLabels = (series.length < max - min + 1) ? series.length
00310 : max - min + 1;
00311 int initialIndex = (min < 0) ? 0 : min;
00312
00313 for (int i = 0; i < sizeOfTickLabels; i++) {
00314 tickLabels.add(series[i + initialIndex]);
00315
00316 int tickLabelPosition = (int) (length * (i + 0.5) / sizeOfTickLabels);
00317 tickLabelPositions.add(tickLabelPosition);
00318 }
00319 }
00320
00327 private void updateTickLabelForLogScale(int length) {
00328 double min = axis.getRange().lower;
00329 double max = axis.getRange().upper;
00330
00331 int digitMin = (int) Math.ceil(Math.log10(min));
00332 int digitMax = (int) Math.ceil(Math.log10(max));
00333
00334 final BigDecimal MIN = BigDecimal.valueOf(min);
00335 BigDecimal tickStep = pow(10, digitMin - 1);
00336 BigDecimal firstPosition;
00337
00338 if (MIN.remainder(tickStep).doubleValue() <= 0) {
00339 firstPosition = MIN.subtract(MIN.remainder(tickStep));
00340 } else {
00341 firstPosition = MIN.subtract(MIN.remainder(tickStep)).add(tickStep);
00342 }
00343
00344 for (int i = digitMin; i <= digitMax; i++) {
00345 for (BigDecimal j = firstPosition; j.doubleValue() <= pow(10, i)
00346 .doubleValue(); j = j.add(tickStep)) {
00347 if (j.doubleValue() > max) {
00348 break;
00349 }
00350
00351 if (axis.isDateEnabled()) {
00352 Date date = new Date((long) j.doubleValue());
00353 tickLabels.add(format(date));
00354 } else {
00355 tickLabels.add(format(j.doubleValue()));
00356 }
00357 tickLabelValues.add(j.doubleValue());
00358
00359 int tickLabelPosition = (int) ((Math.log10(j.doubleValue()) - Math
00360 .log10(min)) / (Math.log10(max) - Math.log10(min)) * length);
00361 tickLabelPositions.add(tickLabelPosition);
00362 }
00363 tickStep = tickStep.multiply(pow(10, 1));
00364 firstPosition = tickStep.add(pow(10, i));
00365 }
00366 }
00367
00374 private void updateTickLabelForLinearScale(int length) {
00375 double min = axis.getRange().lower;
00376 double max = axis.getRange().upper;
00377 updateTickLabelForLinearScale(length, getGridStep(length, min, max));
00378 }
00379
00388 private void updateTickLabelForLinearScale(int length, BigDecimal tickStep) {
00389 double min = axis.getRange().lower;
00390 double max = axis.getRange().upper;
00391
00392 final BigDecimal MIN = BigDecimal.valueOf(min);
00393 BigDecimal firstPosition;
00394
00395
00396 if (MIN.remainder(tickStep).doubleValue() <= 0) {
00397
00398 firstPosition = MIN.subtract(MIN.remainder(tickStep));
00399 } else {
00400
00401 firstPosition = MIN.subtract(MIN.remainder(tickStep)).add(tickStep);
00402 }
00403
00404
00405 if (axis.isDateEnabled()) {
00406 BigDecimal zeroOclock = firstPosition.subtract(BigDecimal
00407 .valueOf(3600000));
00408 if (MIN.compareTo(zeroOclock) == -1) {
00409 firstPosition = zeroOclock;
00410 }
00411 }
00412
00413 for (BigDecimal b = firstPosition; b.doubleValue() <= max; b = b
00414 .add(tickStep)) {
00415 if (axis.isDateEnabled()) {
00416 Date date = new Date((long) b.doubleValue());
00417 tickLabels.add(format(date));
00418 } else {
00419 tickLabels.add(format(b.doubleValue()));
00420 }
00421 tickLabelValues.add(b.doubleValue());
00422
00423 int tickLabelPosition = (int) ((b.doubleValue() - min)
00424 / (max - min) * length);
00425 tickLabelPositions.add(tickLabelPosition);
00426 }
00427 }
00428
00432 private void updateTickVisibility() {
00433
00434
00435 tickVisibilities.clear();
00436 for (int i = 0; i < tickLabelPositions.size(); i++) {
00437 tickVisibilities.add(Boolean.TRUE);
00438 }
00439
00440 if (tickLabelPositions.size() == 0
00441 || axis.getTick().getTickLabelAngle() != 0) {
00442 return;
00443 }
00444
00445
00446 int previousPosition = 0;
00447 for (int i = 0; i < tickLabelPositions.size(); i++) {
00448
00449
00450 boolean hasSpaceToDraw = true;
00451 if (i != 0) {
00452 hasSpaceToDraw = hasSpaceToDraw(previousPosition,
00453 tickLabelPositions.get(i), tickLabels.get(i));
00454 }
00455
00456
00457 boolean isMajorTick = true;
00458 if (!axis.isValidCategoryAxis()) {
00459 if (axis.isLogScaleEnabled()) {
00460 isMajorTick = isMajorTick(tickLabelValues.get(i));
00461 }
00462
00463
00464 String currentLabel = tickLabels.get(i);
00465 try {
00466 double value = Double.parseDouble(currentLabel);
00467 if (value != tickLabelValues.get(i)) {
00468 isMajorTick = false;
00469 }
00470 } catch (NumberFormatException e) {
00471
00472 }
00473 }
00474
00475 if (hasSpaceToDraw && isMajorTick) {
00476 previousPosition = tickLabelPositions.get(i);
00477 } else {
00478 tickVisibilities.set(i, Boolean.FALSE);
00479 }
00480 }
00481 }
00482
00490 private int getTimeUnit(double gridStepHint) {
00491 final Integer[] units = { Calendar.MILLISECOND, Calendar.SECOND,
00492 Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DATE,
00493 Calendar.MONTH, Calendar.YEAR };
00494
00495 for (Integer unit : units) {
00496 Integer[] steps = possibleTickSteps.get(unit);
00497 if (gridStepHint < (getPeriodInMillis(unit, steps[steps.length - 2]) + getPeriodInMillis(
00498 unit, steps[steps.length - 1])) / 2d) {
00499 return unit;
00500 }
00501 }
00502 return Calendar.YEAR;
00503 }
00504
00515 private static long getPeriodInMillis(int unit, int amount) {
00516 Calendar cal = Calendar.getInstance();
00517 cal.setTimeInMillis(0);
00518 cal.roll(unit, amount);
00519 return cal.getTimeInMillis();
00520 }
00521
00529 private String format(Object obj) {
00530 if (format == null) {
00531 if (axis.isDateEnabled()) {
00532 String dateFormat = "yyyyy.MMMMM.dd";
00533 if (timeUnit == Calendar.MILLISECOND) {
00534 dateFormat = "HH:mm:ss.SSS";
00535 } else if (timeUnit == Calendar.SECOND) {
00536 dateFormat = "HH:mm:ss";
00537 } else if (timeUnit == Calendar.MINUTE) {
00538 dateFormat = "HH:mm";
00539 } else if (timeUnit == Calendar.HOUR_OF_DAY) {
00540 dateFormat = "dd HH:mm";
00541 } else if (timeUnit == Calendar.DATE) {
00542 dateFormat = "MMMMM d";
00543 } else if (timeUnit == Calendar.MONTH) {
00544 dateFormat = "yyyy MMMMM";
00545 } else if (timeUnit == Calendar.YEAR) {
00546 dateFormat = "yyyy";
00547 }
00548 return new SimpleDateFormat(dateFormat).format(obj);
00549 }
00550 return new DecimalFormat(DEFAULT_DECIMAL_FORMAT).format(obj);
00551 }
00552 return format.format(obj);
00553 }
00554
00562 private boolean isMajorTick(double tickValue) {
00563 if (!axis.isLogScaleEnabled()) {
00564 return true;
00565 }
00566
00567 if (Math.log10(tickValue) % 1 == 0) {
00568 return true;
00569 }
00570
00571 return false;
00572 }
00573
00585 private boolean hasSpaceToDraw(int previousPosition, int tickLabelPosition,
00586 String tickLabel) {
00587 Point p = Util.getExtentInGC(axis.getTick().getFont(), tickLabel);
00588 int interval = tickLabelPosition - previousPosition;
00589 int textLength = axis.isHorizontalAxis() ? p.x : p.y;
00590 int padding = 3;
00591
00592 return interval > textLength + padding;
00593 }
00594
00602 public int getRightMarginHint(int length) {
00603
00604
00605 int mostRightLabelIndex = -1;
00606 for (int i = tickLabels.size() - 1; i >= 0; i--) {
00607 if (tickVisibilities.size() > i && tickVisibilities.get(i)) {
00608 mostRightLabelIndex = i;
00609 break;
00610 }
00611 }
00612
00613
00614 int rightMarginHint = 0;
00615 if (mostRightLabelIndex != -1) {
00616 int position = tickLabelPositions.get(mostRightLabelIndex);
00617 double angle = axis.getTick().getTickLabelAngle();
00618 int textWidth = Util.getExtentInGC(axis.getTick().getFont(),
00619 tickLabels.get(mostRightLabelIndex)).x;
00620 if (angle == 0) {
00621 rightMarginHint = Math.max(0, position - length
00622 + (int) (textWidth / 2d));
00623 } else if (axis.getPosition() == Position.Secondary) {
00624 rightMarginHint = Math.max(0, position - length
00625 + (int) (textWidth * Math.cos(Math.toRadians(angle))));
00626 }
00627 }
00628
00629 return rightMarginHint;
00630 }
00631
00639 public int getLeftMarginHint(int length) {
00640
00641
00642 int mostLeftLabelIndex = -1;
00643 for (int i = 0; i < tickLabels.size(); i++) {
00644 if (tickVisibilities.size() > i && tickVisibilities.get(i)) {
00645 mostLeftLabelIndex = i;
00646 break;
00647 }
00648 }
00649
00650
00651 int leftMarginHint = 0;
00652 if (mostLeftLabelIndex != -1) {
00653 int position = tickLabelPositions.get(mostLeftLabelIndex);
00654 double angle = axis.getTick().getTickLabelAngle();
00655 int textWidth = Util.getExtentInGC(axis.getTick().getFont(),
00656 tickLabels.get(mostLeftLabelIndex)).x;
00657 if (angle == 0) {
00658 leftMarginHint = Math.max(0, (int) (textWidth / 2d) - position);
00659 } else if (axis.getPosition() == Position.Primary) {
00660 leftMarginHint = Math.max(0,
00661 (int) (textWidth * Math.cos(Math.toRadians(angle)))
00662 - position);
00663 }
00664 }
00665
00666 return leftMarginHint;
00667 }
00668
00674 public int getTickLabelMaxLength() {
00675 int maxLength = 0;
00676 for (int i = 0; i < tickLabels.size(); i++) {
00677 if (tickVisibilities.size() > i && tickVisibilities.get(i) == true) {
00678 Point p = Util.getExtentInGC(axis.getTick().getFont(),
00679 tickLabels.get(i));
00680 if (p.x > maxLength) {
00681 maxLength = p.x;
00682 }
00683 }
00684 }
00685
00686 return maxLength;
00687 }
00688
00699 private static BigDecimal pow(double base, int exponent) {
00700 BigDecimal value;
00701 if (exponent > 0) {
00702 value = BigDecimal.valueOf(base).pow(exponent);
00703 } else {
00704 value = BigDecimal.ONE.divide(BigDecimal.valueOf(base).pow(
00705 -exponent));
00706 }
00707 return value;
00708 }
00709
00721 private BigDecimal getGridStep(int lengthInPixels, double min, double max) {
00722 if (lengthInPixels <= 0) {
00723 throw new IllegalArgumentException(
00724 "lengthInPixels must be positive value.");
00725 }
00726 if (min >= max) {
00727 throw new IllegalArgumentException("min must be less than max.");
00728 }
00729
00730 double length = Math.abs(max - min);
00731 double gridStepHint = length / lengthInPixels
00732 * axis.getTick().getTickMarkStepHint();
00733
00734
00735
00736 double mantissa = gridStepHint;
00737 int exponent = 0;
00738 if (mantissa < 1) {
00739 while (mantissa < 1) {
00740 mantissa *= 10.0;
00741 exponent--;
00742 }
00743 } else {
00744 while (mantissa >= 10) {
00745 mantissa /= 10.0;
00746 exponent++;
00747 }
00748 }
00749
00750
00751 BigDecimal gridStep;
00752 if (mantissa > 7.5) {
00753
00754 gridStep = BigDecimal.TEN.multiply(pow(10, exponent));
00755 } else if (mantissa > 3.5) {
00756
00757 gridStep = BigDecimal.valueOf(5).multiply(pow(10, exponent));
00758 } else if (mantissa > 1.5) {
00759
00760 gridStep = BigDecimal.valueOf(2).multiply(pow(10, exponent));
00761 } else {
00762
00763 gridStep = pow(10, exponent);
00764 }
00765 return gridStep;
00766 }
00767
00773 public ArrayList<Integer> getTickLabelPositions() {
00774 return tickLabelPositions;
00775 }
00776
00782 protected ArrayList<Double> getTickLabelValues() {
00783 return tickLabelValues;
00784 }
00785
00792 protected void setFont(Font font) {
00793 if (font == null) {
00794 this.font = DEFAULT_FONT;
00795 } else {
00796 this.font = font;
00797 }
00798 }
00799
00805 public Font getFont() {
00806 if (font.isDisposed()) {
00807 font = DEFAULT_FONT;
00808 }
00809 return font;
00810 }
00811
00817 public ChartLayoutData getLayoutData() {
00818 return new ChartLayoutData(widthHint, heightHint);
00819 }
00820
00833 public void setBounds(int x, int y, int width, int height) {
00834 bounds = new Rectangle(x, y, width, height);
00835 }
00836
00842 protected Rectangle getBounds() {
00843 return bounds;
00844 }
00845
00849 protected void dispose() {
00850 if (!chart.isDisposed()) {
00851 chart.removePaintListener(this);
00852 }
00853 }
00854
00858 protected void updateLayoutData() {
00859 widthHint = SWT.DEFAULT;
00860 heightHint = SWT.DEFAULT;
00861 if (!axis.getTick().isVisible()) {
00862 widthHint = 0;
00863 heightHint = 0;
00864 } else {
00865 if (axis.isHorizontalAxis()) {
00866 heightHint = Axis.MARGIN
00867 + Util.getExtentInGC(getFont(), "dummy").y;
00868 } else {
00869 widthHint = Axis.MARGIN;
00870 }
00871 }
00872 }
00873
00874
00875
00876
00877 public void paintControl(PaintEvent e) {
00878 if (!axis.getTick().isVisible()) {
00879 return;
00880 }
00881
00882 Color oldBackground = e.gc.getBackground();
00883 e.gc.setBackground(chart.getBackground());
00884 Color oldForeground = e.gc.getForeground();
00885 e.gc.setForeground(getForeground());
00886 if (axis.isHorizontalAxis()) {
00887 drawXTick(e.gc);
00888 } else {
00889 drawYTick(e.gc);
00890 }
00891
00892 e.gc.setBackground(oldBackground);
00893 e.gc.setForeground(oldForeground);
00894 }
00895
00902 private void drawXTick(GC gc) {
00903 int offset = axis.getTick().getAxisTickMarks().getBounds().x;
00904
00905
00906 gc.setFont(axis.getTick().getFont());
00907 int angle = axis.getTick().getTickLabelAngle();
00908 for (int i = 0; i < tickLabelPositions.size(); i++) {
00909 if (axis.isValidCategoryAxis() || tickVisibilities.get(i) == true) {
00910 String text = tickLabels.get(i);
00911 int textWidth = gc.textExtent(text).x;
00912 int textHeight = gc.textExtent(text).y;
00913 if (angle == 0) {
00914 int x = (int) (tickLabelPositions.get(i) - textWidth / 2d + offset);
00915 gc.drawText(text, bounds.x + x, bounds.y);
00916 continue;
00917 }
00918
00919 float x, y;
00920 if (axis.getPosition() == Position.Primary) {
00921 x = (float) (offset + bounds.x + tickLabelPositions.get(i)
00922 - textWidth * Math.cos(Math.toRadians(angle)) - textHeight
00923 / 2d * Math.sin(Math.toRadians(angle)));
00924 y = (float) (bounds.y + textWidth
00925 * Math.sin(Math.toRadians(angle)));
00926 } else {
00927 x = (float) (offset + bounds.x + tickLabelPositions.get(i) - textHeight
00928 / 2d * Math.sin(Math.toRadians(angle)));
00929 y = (float) (bounds.y + bounds.height
00930 * Math.sin(Math.toRadians(angle)));
00931 }
00932 drawRotatedText(gc, text, x, y, angle);
00933 }
00934 }
00935 }
00936
00951 private static void drawRotatedText(GC gc, String text, float x, float y, int angle) {
00952
00953
00954 Transform transform = new Transform(gc.getDevice());
00955 transform.translate(x, y);
00956 transform.rotate(360 - angle);
00957 gc.setTransform(transform);
00958 gc.drawText(text, 0, 0);
00959
00960
00961 transform.dispose();
00962 gc.setTransform(null);
00963 }
00964
00971 private void drawYTick(GC gc) {
00972 int margin = Axis.MARGIN + AxisTickMarks.TICK_LENGTH;
00973
00974
00975 gc.setFont(axis.getTick().getFont());
00976 int figureHeight = gc.textExtent("dummy").y;
00977 for (int i = 0; i < tickLabelPositions.size(); i++) {
00978 if (tickVisibilities.size() == 0 || tickLabels.size() == 0) {
00979 break;
00980 }
00981
00982 if (tickVisibilities.get(i) == true) {
00983 String text = tickLabels.get(i);
00984 int x = Axis.MARGIN;
00985 if (tickLabels.get(0).startsWith("-") && !text.startsWith("-")) {
00986 x += gc.textExtent("-").x;
00987 }
00988 int y = (int) (bounds.height - 1 - tickLabelPositions.get(i)
00989 - figureHeight / 2.0 - margin);
00990 gc.drawText(text, bounds.x + x, bounds.y + y);
00991 }
00992 }
00993 }
00994
01005 protected void setFormat(Format format) {
01006 this.format = format;
01007 }
01008
01014 protected Format getFormat() {
01015 return format;
01016 }
01017 }