/** * Updates tick label for date axis. * * @param length the length of axis */ private void updateTickLabelForDateAxis(int length) { double min = axis.getRange().lower; double max = axis.getRange().upper; double gridStepHint = Math.abs(max - min) / length * axis.getTick().getTickMarkStepHint(); timeUnit = getTimeUnit(gridStepHint); if (timeUnit == Calendar.MILLISECOND || timeUnit == Calendar.SECOND || timeUnit == Calendar.MINUTE || timeUnit == Calendar.HOUR_OF_DAY || timeUnit == Calendar.DATE) { Integer[] steps = possibleTickSteps.get(timeUnit); for (int i = 0; i < steps.length - 1; i++) { if (gridStepHint < (getPeriodInMillis(timeUnit, steps[i]) + getPeriodInMillis(timeUnit, steps[i + 1])) / 2d) { BigDecimal gridStep = new BigDecimal(Long.valueOf(getPeriodInMillis(timeUnit, steps[i])).toString()); updateTickLabelForLinearScale(length, gridStep); break; } } } else if (timeUnit == Calendar.MONTH || timeUnit == Calendar.YEAR) { updateTickLabelForMonthOrYear(length, gridStepHint, timeUnit); } }
/** * Updates the tick label for month or year. The month and year are handled differently from other * units of time, since 1 month and 1 year can be different depending on which time to start * counting. * * @param length the length of axis * @param gridStepHint the grid step hint * @param tickStepUnit the tick step unit of time */ private void updateTickLabelForMonthOrYear(int length, double gridStepHint, int tickStepUnit) { double min = axis.getRange().lower; double max = axis.getRange().upper; // get initial position Calendar cal = Calendar.getInstance(); cal.setTime(new Date((long) min)); int month = cal.get(Calendar.MONTH); int year = cal.get(Calendar.YEAR); if (tickStepUnit == Calendar.MONTH) { if (month == Calendar.DECEMBER) { year++; month = Calendar.JANUARY; } else { month++; } } else if (tickStepUnit == Calendar.YEAR) { month = Calendar.JANUARY; year++; } // get tick step Integer[] steps = possibleTickSteps.get(tickStepUnit); int step = steps[steps.length - 1]; for (int i = 0; i < steps.length - 1; i++) { if (gridStepHint < (getPeriodInMillis(tickStepUnit, steps[i]) + getPeriodInMillis(tickStepUnit, steps[i + 1])) / 2d) { step = steps[i]; break; } } // set tick labels cal.clear(); cal.set(year, month, 1); while (cal.getTimeInMillis() < max) { tickLabelValues.add(Double.valueOf(cal.getTimeInMillis())); tickLabels.add(format(cal.getTimeInMillis())); int tickLabelPosition = (int) ((cal.getTimeInMillis() - min) / (max - min) * length); tickLabelPositions.add(tickLabelPosition); if (tickStepUnit == Calendar.MONTH) { month += step; if (month + step > Calendar.DECEMBER) { year++; month -= Calendar.DECEMBER + 1; } } else if (tickStepUnit == Calendar.YEAR) { year += step; } cal.clear(); cal.set(year, month, 1); } }
/** * Updates tick label for log scale. * * @param length the length of axis */ private void updateTickLabelForLogScale(int length) { double min = axis.getRange().lower; double max = axis.getRange().upper; int digitMin = (int) Math.ceil(Math.log10(min)); int digitMax = (int) Math.ceil(Math.log10(max)); final BigDecimal MIN = new BigDecimal(new Double(min).toString()); BigDecimal tickStep = pow(10, digitMin - 1); BigDecimal firstPosition; if (MIN.remainder(tickStep).doubleValue() <= 0) { firstPosition = MIN.subtract(MIN.remainder(tickStep)); } else { firstPosition = MIN.subtract(MIN.remainder(tickStep)).add(tickStep); } for (int i = digitMin; i <= digitMax; i++) { for (BigDecimal j = firstPosition; j.doubleValue() <= pow(10, i).doubleValue(); j = j.add(tickStep)) { if (j.doubleValue() > max) { break; } if (axis.isDateEnabled()) { Date date = new Date((long) j.doubleValue()); tickLabels.add(format(date)); } else { tickLabels.add(format(j.doubleValue())); } tickLabelValues.add(j.doubleValue()); int tickLabelPosition = (int) ((Math.log10(j.doubleValue()) - Math.log10(min)) / (Math.log10(max) - Math.log10(min)) * length); tickLabelPositions.add(tickLabelPosition); } tickStep = tickStep.multiply(pow(10, 1)); firstPosition = tickStep.add(pow(10, i)); } }
/** * Updates tick label for category axis. * * @param length the length of axis */ private void updateTickLabelForCategoryAxis(int length) { String[] series = axis.getCategorySeries(); if (series == null) { return; } int min = (int) axis.getRange().lower; int max = (int) axis.getRange().upper; int sizeOfTickLabels = (series.length < max - min + 1) ? series.length : max - min + 1; int initialIndex = (min < 0) ? 0 : min; for (int i = 0; i < sizeOfTickLabels; i++) { tickLabels.add(series[i + initialIndex]); int tickLabelPosition = (int) (length * (i + 0.5) / sizeOfTickLabels); tickLabelPositions.add(tickLabelPosition); } }
/** * Updates tick label for normal scale. * * @param length axis length (>0) * @param tickStep the tick step */ private void updateTickLabelForLinearScale(int length, BigDecimal tickStep) { double min = axis.getRange().lower; double max = axis.getRange().upper; final BigDecimal MIN = new BigDecimal(new Double(min).toString()); BigDecimal firstPosition; /* if (min % tickStep <= 0) */ if (MIN.remainder(tickStep).doubleValue() <= 0) { /* firstPosition = min - min % tickStep */ firstPosition = MIN.subtract(MIN.remainder(tickStep)); } else { /* firstPosition = min - min % tickStep + tickStep */ firstPosition = MIN.subtract(MIN.remainder(tickStep)).add(tickStep); } // the unit time starts from 1:00 if (axis.isDateEnabled()) { BigDecimal zeroOclock = firstPosition.subtract(new BigDecimal(new Double(3600000).toString())); if (MIN.compareTo(zeroOclock) == -1) { firstPosition = zeroOclock; } } for (BigDecimal b = firstPosition; b.doubleValue() <= max; b = b.add(tickStep)) { if (axis.isDateEnabled()) { Date date = new Date((long) b.doubleValue()); tickLabels.add(format(date)); } else { tickLabels.add(format(b.doubleValue())); } tickLabelValues.add(b.doubleValue()); int tickLabelPosition = (int) ((b.doubleValue() - min) / (max - min) * length); tickLabelPositions.add(tickLabelPosition); } }
/** * Updates tick label for normal scale. * * @param length axis length (>0) */ private void updateTickLabelForLinearScale(int length) { double min = axis.getRange().lower; double max = axis.getRange().upper; updateTickLabelForLinearScale(length, getGridStep(length, min, max)); }