diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java index 9d4918b5c6e6650f0cbdeec0dc926f9be00bd6fa..a4fed5f8ce713840e5c2d090f71451fb59d85cfd 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java @@ -94,7 +94,7 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Date) { long span = (long) Math.abs(maxValue - minValue); // in data space long gridStepHint = (long) (span / (double) tickSpace * styleManager.getXAxisTickMarkSpacingHint()); - long timeUnit = dateFormatter.getTimeUnit(gridStepHint); + long timeUnit = dateFormatter.getTimeSpan(gridStepHint); tickLabels.add(dateFormatter.formatDate(((Number) ((Date) category).getTime()).doubleValue(), timeUnit)); } double tickLabelPosition = (int) (margin + firstPosition + gridStep * counter++); diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickCalculator.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickCalculator.java index 10d7685fa8efbc16ccbb84afadb35db10aa72bd3..8a52fb79691931774c1822d15d4e709dcf86d5ea 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickCalculator.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickCalculator.java @@ -152,7 +152,11 @@ public abstract class AxisTickCalculator { // System.out.println("largestLabelWidth: " + largestLabelWidth); // System.out.println("tickSpacingHint: " + tickSpacingHint); - return (largestLabelWidth * 1.6 < tickSpacingHint); + // if (largestLabelWidth * 1.1 >= tickSpacingHint) { + // System.out.println("WILL NOT FIT!!!"); + // } + + return (largestLabelWidth * 1.1 < tickSpacingHint); } } diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickDateCalculator.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickDateCalculator.java index 5e2ebb73914069eec30286a6f577c10e52b51925..bd2be16157aeb5a0cc48bf234c57f22a8d981643 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickDateCalculator.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickDateCalculator.java @@ -15,6 +15,11 @@ */ package com.xeiam.xchart.internal.chartpart; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + import com.xeiam.xchart.StyleManager; import com.xeiam.xchart.internal.Utils; import com.xeiam.xchart.internal.chartpart.Axis.Direction; @@ -26,7 +31,72 @@ import com.xeiam.xchart.internal.chartpart.Axis.Direction; */ public class AxisTickDateCalculator extends AxisTickCalculator { - DateFormatter dateFormatter; + private static final long MILLIS_SCALE = TimeUnit.MILLISECONDS.toMillis(1L); + private static final long SEC_SCALE = TimeUnit.SECONDS.toMillis(1L); + private static final long MIN_SCALE = TimeUnit.MINUTES.toMillis(1L); + private static final long HOUR_SCALE = TimeUnit.HOURS.toMillis(1L); + private static final long DAY_SCALE = TimeUnit.DAYS.toMillis(1L); + private static final long MONTH_SCALE = TimeUnit.DAYS.toMillis(1L) * 30; + // private static final long QUARTER_SCALE = TimeUnit.DAYS.toMillis(1L) * 120; + private static final long YEAR_SCALE = TimeUnit.DAYS.toMillis(1L) * 365; + + private static List<TimeSpan> timeSpans = new ArrayList<TimeSpan>(); + + static { + timeSpans.add(new TimeSpan(MILLIS_SCALE, 1, "ss.SSS")); + timeSpans.add(new TimeSpan(MILLIS_SCALE, 2, "ss.SSS")); + timeSpans.add(new TimeSpan(MILLIS_SCALE, 5, "ss.SSS")); + timeSpans.add(new TimeSpan(MILLIS_SCALE, 10, "ss.SSS")); + timeSpans.add(new TimeSpan(MILLIS_SCALE, 50, "ss.SS")); + timeSpans.add(new TimeSpan(MILLIS_SCALE, 100, "ss.SS")); + timeSpans.add(new TimeSpan(MILLIS_SCALE, 200, "ss.SS")); + timeSpans.add(new TimeSpan(MILLIS_SCALE, 500, "ss.SS")); + + timeSpans.add(new TimeSpan(SEC_SCALE, 1, "ss.SS")); + timeSpans.add(new TimeSpan(SEC_SCALE, 2, "ss.S")); + timeSpans.add(new TimeSpan(SEC_SCALE, 5, "ss.S")); + timeSpans.add(new TimeSpan(SEC_SCALE, 10, "HH:mm:ss")); + timeSpans.add(new TimeSpan(SEC_SCALE, 15, "HH:mm:ss")); + timeSpans.add(new TimeSpan(SEC_SCALE, 20, "HH:mm:ss")); + timeSpans.add(new TimeSpan(SEC_SCALE, 30, "HH:mm:ss")); + + timeSpans.add(new TimeSpan(MIN_SCALE, 1, "HH:mm:ss")); + timeSpans.add(new TimeSpan(MIN_SCALE, 2, "HH:mm:ss")); + timeSpans.add(new TimeSpan(MIN_SCALE, 5, "HH:mm:ss")); + timeSpans.add(new TimeSpan(MIN_SCALE, 10, "HH:mm")); + timeSpans.add(new TimeSpan(MIN_SCALE, 15, "HH:mm")); + timeSpans.add(new TimeSpan(MIN_SCALE, 20, "HH:mm")); + timeSpans.add(new TimeSpan(MIN_SCALE, 30, "HH:mm")); + + timeSpans.add(new TimeSpan(HOUR_SCALE, 1, "HH:mm")); + timeSpans.add(new TimeSpan(HOUR_SCALE, 2, "HH:mm")); + timeSpans.add(new TimeSpan(HOUR_SCALE, 4, "HH:mm")); + timeSpans.add(new TimeSpan(HOUR_SCALE, 8, "HH:mm")); + timeSpans.add(new TimeSpan(HOUR_SCALE, 12, "HH:mm")); + + timeSpans.add(new TimeSpan(DAY_SCALE, 1, "EEE HH:mm")); + timeSpans.add(new TimeSpan(DAY_SCALE, 2, "EEE HH:mm")); + timeSpans.add(new TimeSpan(DAY_SCALE, 3, "EEE HH:mm")); + timeSpans.add(new TimeSpan(DAY_SCALE, 5, "MM-dd")); + timeSpans.add(new TimeSpan(DAY_SCALE, 10, "MM-dd")); + timeSpans.add(new TimeSpan(DAY_SCALE, 15, "MM-dd")); + + timeSpans.add(new TimeSpan(MONTH_SCALE, 1, "MM-dd")); + timeSpans.add(new TimeSpan(MONTH_SCALE, 2, "MM-dd")); + timeSpans.add(new TimeSpan(MONTH_SCALE, 3, "MM-dd")); + timeSpans.add(new TimeSpan(MONTH_SCALE, 4, "MM-dd")); + timeSpans.add(new TimeSpan(MONTH_SCALE, 6, "yyyy-MM")); + + timeSpans.add(new TimeSpan(YEAR_SCALE, 1, "yyyy-MM")); + timeSpans.add(new TimeSpan(YEAR_SCALE, 2, "yyyy-MM")); + timeSpans.add(new TimeSpan(YEAR_SCALE, 5, "yyyy")); + timeSpans.add(new TimeSpan(YEAR_SCALE, 10, "yyyy")); + timeSpans.add(new TimeSpan(YEAR_SCALE, 20, "yyyy")); + timeSpans.add(new TimeSpan(YEAR_SCALE, 100, "yyyy")); + timeSpans.add(new TimeSpan(YEAR_SCALE, 500, "yyyy")); + timeSpans.add(new TimeSpan(YEAR_SCALE, 1000, "yyyy")); + + } /** * Constructor @@ -40,7 +110,6 @@ public class AxisTickDateCalculator extends AxisTickCalculator { public AxisTickDateCalculator(Direction axisDirection, double workingSpace, double minValue, double maxValue, StyleManager styleManager) { super(axisDirection, workingSpace, minValue, maxValue, styleManager); - dateFormatter = new DateFormatter(styleManager); calculate(); } @@ -50,7 +119,8 @@ public class AxisTickDateCalculator extends AxisTickCalculator { double tickSpace = styleManager.getAxisTickSpacePercentage() * workingSpace; // in plot space // this prevents an infinite loop when the plot gets sized really small. - if (tickSpace < 10) { + if (tickSpace < styleManager.getXAxisTickMarkSpacingHint()) { + // System.out.println("Returning!"); return; } @@ -59,43 +129,130 @@ public class AxisTickDateCalculator extends AxisTickCalculator { // the span of the data long span = (long) Math.abs(maxValue - minValue); // in data space + // System.out.println("span: " + span); // Generate the labels first, see if they "look" OK and reiterate with an increased tickSpacingHint - int tickSpacingHint = styleManager.getXAxisTickMarkSpacingHint() - 5; + int tickSpacingHint = styleManager.getXAxisTickMarkSpacingHint(); + int gridStepInChartSpace = 0; + + // System.out.println("calculating ticks..."); + long gridStepHint = (long) (span / tickSpace * tickSpacingHint); // in time units (ms) + // System.out.println("gridStepHint: " + gridStepHint); + + ////////////////////////////////////////////// + + // iterate forward until the matching timespan is found + int index = 0; + for (int i = 0; i < timeSpans.size() - 1; i++) { + + if (span < ((timeSpans.get(i).getUnitAmount() * timeSpans.get(i).getMagnitude() + timeSpans.get(i + 1).getUnitAmount() * timeSpans.get(i + 1).getMagnitude()) / 2.0)) { + index = i; + break; + } + } + + // use the pattern from the first timeSpan + String datePattern = timeSpans.get(index).getDatePattern(); + // System.out.println("index: " + index); + + // iterate BACWARDS from previous point until the appropriate timespan is found for the gridStepHint + for (int i = index - 1; i > 0; i--) { + + if (gridStepHint > timeSpans.get(i).getUnitAmount() * timeSpans.get(i).getMagnitude()) { + index = i; + break; + } + } + + ////////////////////////////////////////////// + + // now increase the timespan until one is found where all the labels fit nicely. It will often be the first one. + index--; do { - // System.out.println("calculating ticks..."); tickLabels.clear(); tickLocations.clear(); - tickSpacingHint += 5; - long gridStepHint = (long) (span / tickSpace * tickSpacingHint); - - long timeUnit = dateFormatter.getTimeUnit(gridStepHint); - double gridStep = 0.0; - int[] steps = dateFormatter.getValidTickStepsMap().get(timeUnit); - for (int i = 0; i < steps.length - 1; i++) { - if (gridStepHint < (timeUnit * steps[i] + timeUnit * steps[i + 1]) / 2.0) { - gridStep = timeUnit * steps[i]; - break; - } - } + double gridStep = timeSpans.get(++index).getUnitAmount() * timeSpans.get(index).getMagnitude(); // in time units (ms) // System.out.println("gridStep: " + gridStep); + gridStepInChartSpace = (int) (gridStep / span * tickSpace); + // System.out.println("gridStepInChartSpace: " + gridStepInChartSpace); + double firstPosition = getFirstPosition(gridStep); + // Define Date Pattern + // override pattern if one was explicitly given + if (styleManager.getDatePattern() != null) { + datePattern = styleManager.getDatePattern(); + } + // System.out.println("datePattern: " + datePattern); + + SimpleDateFormat simpleDateformat = new SimpleDateFormat(datePattern, styleManager.getLocale()); + simpleDateformat.setTimeZone(styleManager.getTimezone()); + simpleDateformat.applyPattern(datePattern); + + // return simpleDateformat.format(value); + + ////////////////////////////// + // generate all tickLabels and tickLocations from the first to last position for (double value = firstPosition; value <= maxValue + 2 * gridStep; value = value + gridStep) { // if (value <= maxValue && value >= minValue) { - tickLabels.add(dateFormatter.formatDate(value, timeUnit)); + /////////////////////////////// + + tickLabels.add(simpleDateformat.format(value)); // here we convert tickPosition finally to plot space, i.e. pixels double tickLabelPosition = margin + ((value - minValue) / (maxValue - minValue) * tickSpace); + // System.out.println("tickLabelPosition: " + tickLabelPosition); tickLocations.add(tickLabelPosition); // } } - } while (!willLabelsFitInTickSpaceHint(tickLabels, tickSpacingHint)); + } while (!willLabelsFitInTickSpaceHint(tickLabels, gridStepInChartSpace)); + } + + static class TimeSpan { + + private final long unitAmount; + private final int magnitude; + private final String datePattern; + + /** + * Constructor + * + * @param unitAmount + * @param magnitude + * @param datePattern + */ + public TimeSpan(long unitAmount, int magnitude, String datePattern) { + this.unitAmount = unitAmount; + this.magnitude = magnitude; + this.datePattern = datePattern; + } + + public long getUnitAmount() { + + return unitAmount; + } + + public int getMagnitude() { + + return magnitude; + } + + public String getDatePattern() { + + return datePattern; + } + + @Override + public String toString() { + + return "TimeSpan [unitAmount=" + unitAmount + ", magnitude=" + magnitude + ", datePattern=" + datePattern + "]"; + } + } } diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickNumericalCalculator.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickNumericalCalculator.java index d0ec0bea3abf8632b66b059ba457db90c064f43d..e18322a3f7ca48a615e8dc5a8fd201abcdbdedfb 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickNumericalCalculator.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickNumericalCalculator.java @@ -60,7 +60,7 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator { double tickSpace = styleManager.getAxisTickSpacePercentage() * workingSpace; // in plot space // this prevents an infinite loop when the plot gets sized really small. - if (tickSpace < 10) { + if (tickSpace < styleManager.getXAxisTickMarkSpacingHint()) { return; } @@ -77,12 +77,17 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator { if (axisDirection == Direction.Y && tickSpace < 160) { tickSpacingHint = 25 - 5; } + + int gridStepInChartSpace = 0; + do { // System.out.println("calculating ticks..."); tickLabels.clear(); tickLocations.clear(); tickSpacingHint += 5; + // System.out.println("tickSpacingHint: " + tickSpacingHint); + double gridStepHint = span / tickSpace * tickSpacingHint; // gridStepHint --> significand * 10 ** exponent @@ -105,7 +110,7 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator { } } - // calculate the grid step with hint. + // calculate the grid step width hint. double gridStep; if (significand > 7.5) { // gridStep = 10.0 * 10 ** exponent @@ -124,11 +129,23 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator { gridStep = Utils.pow(10, exponent); } ////////////////////////// + // System.out.println("gridStep: " + gridStep); + // System.out.println("***gridStepInChartSpace: " + gridStep / span * tickSpace); + gridStepInChartSpace = (int) (gridStep / span * tickSpace); + // System.out.println("gridStepInChartSpace: " + gridStepInChartSpace); + BigDecimal gridStepBigDecimal = BigDecimal.valueOf(gridStep); - // System.out.println("***gridStep: " + gridStep); BigDecimal cleanedGridStep = gridStepBigDecimal.setScale(10, RoundingMode.HALF_UP).stripTrailingZeros(); // chop off any double imprecision // System.out.println("cleanedGridStep: " + cleanedGridStep); - BigDecimal firstPosition = BigDecimal.valueOf(getFirstPosition(cleanedGridStep.doubleValue())); + // TODO figure this out. It happens once in a blue moon. + BigDecimal firstPosition = null; + try { + firstPosition = BigDecimal.valueOf(getFirstPosition(cleanedGridStep.doubleValue())); + } catch (java.lang.NumberFormatException e) { + System.out.println("cleanedGridStep: " + cleanedGridStep); + System.out.println("cleanedGridStep.doubleValue(): " + cleanedGridStep.doubleValue()); + System.out.println("NumberFormatException caused by this number: " + getFirstPosition(cleanedGridStep.doubleValue())); + } // System.out.println("firstPosition: " + firstPosition); // chop off any double imprecision BigDecimal cleanedFirstPosition = firstPosition.setScale(10, RoundingMode.HALF_UP).stripTrailingZeros(); // chop off any double imprecision // System.out.println("cleanedFirstPosition: " + cleanedFirstPosition); @@ -147,7 +164,7 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator { tickLocations.add(tickLabelPosition); // } } - } while (!willLabelsFitInTickSpaceHint(tickLabels, tickSpacingHint)); + } while (!willLabelsFitInTickSpaceHint(tickLabels, gridStepInChartSpace)); } diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/DateFormatter.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/DateFormatter.java deleted file mode 100644 index df757ef3029b619488cf2e4d43a69d102d8ec69e..0000000000000000000000000000000000000000 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/DateFormatter.java +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Copyright 2011 - 2015 Xeiam LLC. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.xeiam.xchart.internal.chartpart; - -import java.text.SimpleDateFormat; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - -import com.xeiam.xchart.StyleManager; - -/** - * @author timmolter - */ -public class DateFormatter { - - public static final long MILLIS_SCALE = TimeUnit.MILLISECONDS.toMillis(1L); - public static final long SEC_SCALE = TimeUnit.SECONDS.toMillis(1L); - public static final long MIN_SCALE = TimeUnit.MINUTES.toMillis(1L); - public static final long HOUR_SCALE = TimeUnit.HOURS.toMillis(1L); - public static final long DAY_SCALE = TimeUnit.DAYS.toMillis(1L); - public static final long MONTH_SCALE = TimeUnit.DAYS.toMillis(1L) * 31; - public static final long YEAR_SCALE = TimeUnit.DAYS.toMillis(1L) * 365; - - private Map<Long, int[]> validTickStepsMap; - - private final StyleManager styleManager; - - /** - * Constructor - */ - public DateFormatter(StyleManager styleManager) { - - this.styleManager = styleManager; - - validTickStepsMap = new TreeMap<Long, int[]>(); - validTickStepsMap.put(MILLIS_SCALE, new int[] { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 }); - validTickStepsMap.put(SEC_SCALE, new int[] { 1, 2, 5, 10, 15, 20, 30, 60 }); - validTickStepsMap.put(MIN_SCALE, new int[] { 1, 2, 3, 5, 10, 15, 20, 30, 60 }); - validTickStepsMap.put(HOUR_SCALE, new int[] { 1, 2, 4, 6, 12, 24 }); - validTickStepsMap.put(DAY_SCALE, new int[] { 1, 2, 3, 5, 10, 15, 31 }); - validTickStepsMap.put(MONTH_SCALE, new int[] { 1, 2, 3, 4, 6, 12 }); - validTickStepsMap.put(YEAR_SCALE, new int[] { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 }); - } - - /** - * @param gridStepHint - * @return - */ - public long getTimeUnit(long gridStepHint) { - - for (Entry<Long, int[]> entry : validTickStepsMap.entrySet()) { - - long groupMagnitude = entry.getKey(); - int[] steps = entry.getValue(); - long validTickStepMagnitude = (long) ((groupMagnitude * steps[steps.length - 2] + groupMagnitude * steps[steps.length - 1]) / 2.0); - if (gridStepHint < validTickStepMagnitude) { - return groupMagnitude; - } - } - return YEAR_SCALE; - } - - /** - * Format a date value - * - * @param value - * @param timeUnit - * @return - */ - public String formatDate(double value, long timeUnit) { - - String datePattern; - - if (styleManager.getDatePattern() == null) { - - // intelligently set date pattern if none is given - if (timeUnit == MILLIS_SCALE) { - datePattern = "ss.SSS"; - } - else if (timeUnit == SEC_SCALE) { - datePattern = "mm:ss"; - } - else if (timeUnit == MIN_SCALE) { - datePattern = "HH:mm"; - } - else if (timeUnit == HOUR_SCALE) { - datePattern = "HH:mm"; - } - else if (timeUnit == DAY_SCALE) { - datePattern = "MM-dd"; - } - else if (timeUnit == MONTH_SCALE) { - datePattern = "yyyy-MM"; - } - else { - datePattern = "yyyy"; - } - } - else { - datePattern = styleManager.getDatePattern(); - } - - SimpleDateFormat simpleDateformat = new SimpleDateFormat(datePattern, styleManager.getLocale()); - simpleDateformat.setTimeZone(styleManager.getTimezone()); - simpleDateformat.applyPattern(datePattern); - - return simpleDateformat.format(value); - } - - Map<Long, int[]> getValidTickStepsMap() { - - return validTickStepsMap; - } -} diff --git a/xchart/src/test/java/com/xeiam/xchart/DateFormatterTest.java b/xchart/src/test/java/com/xeiam/xchart/DateFormatterTest.java deleted file mode 100644 index 5e9e63e2e2d8a4819db749ea00423add6231cdb9..0000000000000000000000000000000000000000 --- a/xchart/src/test/java/com/xeiam/xchart/DateFormatterTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright 2011 - 2015 Xeiam LLC. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.xeiam.xchart; - -import static org.fest.assertions.api.Assertions.assertThat; - -import java.util.Locale; -import java.util.TimeZone; - -import org.junit.Test; - -import com.xeiam.xchart.internal.chartpart.DateFormatter; - -/** - * @author timmolter - */ -public class DateFormatterTest { - - private final Locale locale = Locale.US; - - @Test - public void testDateFormatting() { - - StyleManager styleManager = new StyleManager(); - DateFormatter dateFormatter = new DateFormatter(styleManager); - - TimeZone timeZone = TimeZone.getTimeZone("UTC"); - - styleManager.setLocale(locale); - styleManager.setTimezone(timeZone); - - // ms - double value = 1358108105531L; - double min = 1358108105100L; - double max = 1358108105900L; - double span = Math.abs(max - min); // in data space - long gridStepHint = (long) (span / 1000 * 74); - long timeUnit = dateFormatter.getTimeUnit(gridStepHint); - String stringValue = dateFormatter.formatDate(value, timeUnit); - assertThat(stringValue).isEqualTo("05.531"); - - // sec - value = 1358108105000L; - min = 1358108101000L; - max = 1358108109000L; - span = Math.abs(max - min); // in data space - gridStepHint = (long) (span / 1000 * 74); - timeUnit = dateFormatter.getTimeUnit(gridStepHint); - stringValue = dateFormatter.formatDate(value, timeUnit); - assertThat(stringValue).isEqualTo("05.000"); - - // min - value = 1358111750000L; - min = 1358111690000L; - max = 1358111870000L; - span = Math.abs(max - min); // in data space - gridStepHint = (long) (span / 1000 * 74); - timeUnit = dateFormatter.getTimeUnit(gridStepHint); - stringValue = dateFormatter.formatDate(value, timeUnit); - assertThat(stringValue).isEqualTo("15:50"); - - // hour - value = 1358111870000L; - min = 1358101070000L; - max = 1358115470000L; - span = Math.abs(max - min); // in data space - gridStepHint = (long) (span / 1000 * 74); - timeUnit = dateFormatter.getTimeUnit(gridStepHint); - stringValue = dateFormatter.formatDate(value, timeUnit); - assertThat(stringValue).isEqualTo("21:17"); - - // day - value = 1358112317000L; - min = 1357939517000L; - max = 1358285117000L; - span = Math.abs(max - min); // in data space - gridStepHint = (long) (span / 1000 * 74); - timeUnit = dateFormatter.getTimeUnit(gridStepHint); - stringValue = dateFormatter.formatDate(value, timeUnit); - assertThat(stringValue).isEqualTo("21:25"); - - // week - value = 1358112317000L; - min = 1357075517000L; - max = 1359149117000L; - span = Math.abs(max - min); // in data space - gridStepHint = (long) (span / 1000 * 74); - timeUnit = dateFormatter.getTimeUnit(gridStepHint); - stringValue = dateFormatter.formatDate(value, timeUnit); - assertThat(stringValue).isEqualTo("01-13"); - - // month - value = 1358112838000L; - min = 1354397638000L; - max = 1361223238000L; - span = Math.abs(max - min); // in data space - gridStepHint = (long) (span / 1000 * 74); - timeUnit = dateFormatter.getTimeUnit(gridStepHint); - stringValue = dateFormatter.formatDate(value, timeUnit); - assertThat(stringValue).isEqualTo("01-13"); - - // year - value = 1358113402000L; - min = 1263419002000L; - max = 1421185402000L; - span = Math.abs(max - min); // in data space - gridStepHint = (long) (span / 1000 * 74); - timeUnit = dateFormatter.getTimeUnit(gridStepHint); - stringValue = dateFormatter.formatDate(value, timeUnit); - assertThat(stringValue).isEqualTo("2013-01"); - - } - -}