diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart04.java b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart04.java
index 5e15c2e07a46d2075ce7b9c46648c98920acc60a..fa9546424783d3542aeca5633df227da72ff8d29 100644
--- a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart04.java
+++ b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart04.java
@@ -72,7 +72,7 @@ public class LineChart04 implements ExampleChart {
     chart.setChartTitle("LineChart04");
     chart.setXAxisTitle("time of day");
     chart.setYAxisTitle("gigawatts");
-    chart.getValueFormatter().setTimezone(TimeZone.getTimeZone("UTC"));
+    chart.getStyleManager().getDateFormatter().setTimezone(TimeZone.getTimeZone("UTC"));
     chart.getStyleManager().setLegendPosition(LegendPosition.InsideNW);
 
     Series series = chart.addDateSeries("value", xData, yData);
diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart09.java b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart09.java
index d6d73cd61e8a2b67eaf78c783b84446bc60af1b3..39348ac9c3b4ad6e245276743c5348c98ef092b7 100644
--- a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart09.java
+++ b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/line/LineChart09.java
@@ -81,9 +81,9 @@ public class LineChart09 implements ExampleChart {
     chart.getStyleManager().setLegendFont(new Font(Font.SERIF, Font.PLAIN, 18));
     chart.getStyleManager().setAxisTitleFont(new Font(Font.SANS_SERIF, Font.ITALIC, 18));
     chart.getStyleManager().setAxisTickLabelsFont(new Font(Font.SERIF, Font.PLAIN, 11));
-    chart.getValueFormatter().setDatePattern("dd-MMM");
-    chart.getValueFormatter().setNormalDecimalPattern("#.000");
-    chart.getValueFormatter().setLocale(Locale.GERMAN);
+    chart.getStyleManager().getDateFormatter().setDatePattern("dd-MMM");
+    chart.getStyleManager().getDecimalFormatter().setNormalDecimalPattern("#.000");
+    chart.getStyleManager().getDateFormatter().setLocale(Locale.GERMAN);
 
     Series series = chart.addDateSeries("Fake Data", xData, yData);
     series.setLineColor(SeriesColor.BLUE);
diff --git a/xchart/src/main/java/com/xeiam/xchart/Chart.java b/xchart/src/main/java/com/xeiam/xchart/Chart.java
index 2fb48add0cd16472fa27874e7de80b09c0aef933..17e51c2934f518b4fa89cb38a6a4ecf7d244eab1 100644
--- a/xchart/src/main/java/com/xeiam/xchart/Chart.java
+++ b/xchart/src/main/java/com/xeiam/xchart/Chart.java
@@ -27,7 +27,6 @@ import com.xeiam.xchart.internal.chartpart.Legend;
 import com.xeiam.xchart.internal.chartpart.Plot;
 import com.xeiam.xchart.style.Series;
 import com.xeiam.xchart.style.StyleManager;
-import com.xeiam.xchart.style.ValueFormatter;
 import com.xeiam.xchart.style.theme.Theme;
 
 /**
@@ -41,7 +40,6 @@ public class Chart {
   private int height;
 
   private StyleManager styleManager = new StyleManager();
-  private ValueFormatter valueFormatter = new ValueFormatter();
 
   // Chart Parts
   private Legend chartLegend = new Legend(this);
@@ -275,16 +273,6 @@ public class Chart {
 
   }
 
-  /**
-   * Gets the Chart's value formatter, which can be used to customize the formatting of numbers and dates
-   * 
-   * @return
-   */
-  public ValueFormatter getValueFormatter() {
-
-    return valueFormatter;
-  }
-
   /**
    * Set the min and max value of the X axis
    * 
diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java
index d6cc1a8cec2dc8184a694b9cc6032189914dd5db..668b6559542d05955f1c228bc733df1df472bace 100644
--- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java
+++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java
@@ -164,7 +164,7 @@ public class AxisPair implements ChartPart {
    * @param workingSpace
    * @return
    */
-  protected static int getTickSpace(int workingSpace) {
+  public static int getTickSpace(int workingSpace) {
 
     return (int) (workingSpace * 0.95);
   }
@@ -176,7 +176,7 @@ public class AxisPair implements ChartPart {
    * @param tickSpace
    * @return
    */
-  protected static int getTickStartOffset(int workingSpace, int tickSpace) {
+  public static int getTickStartOffset(int workingSpace, int tickSpace) {
 
     int marginSpace = workingSpace - tickSpace;
     return (int) (marginSpace / 2.0);
diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java
index 1f1b99c8090f5923afd0304a077e868c53f27e89..8e83c3c5b2409d4d7936c024012a172301580b39 100644
--- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java
+++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTick.java
@@ -20,6 +20,10 @@ import java.awt.Rectangle;
 import java.util.List;
 
 import com.xeiam.xchart.Chart;
+import com.xeiam.xchart.internal.chartpart.Axis.AxisType;
+import com.xeiam.xchart.internal.chartpart.gridstep.DateGridStep;
+import com.xeiam.xchart.internal.chartpart.gridstep.DecimalGridStep;
+import com.xeiam.xchart.internal.chartpart.gridstep.GridStep;
 
 /**
  * An axis tick
@@ -41,7 +45,7 @@ public class AxisTick implements ChartPart {
   /** the visibility state of axistick */
   private boolean isVisible = true; // default to true
 
-  AxisTickComputer axisTickComputer;
+  GridStep gridStep = null;
 
   /**
    * Constructor
@@ -77,7 +81,21 @@ public class AxisTick implements ChartPart {
       // System.out.println("workingspace= " + workingSpace);
     }
 
-    axisTickComputer = new AxisTickComputer(axis.getDirection(), workingSpace, axis.getMin(), axis.getMax(), getChart().getValueFormatter(), axis.getAxisType());
+    // ////////////////////////
+
+    if (axis.getAxisType() == AxisType.Number) {
+
+      gridStep = new DecimalGridStep(axis.getDirection(), workingSpace, axis.getMin(), axis.getMax(), getChart().getStyleManager());
+
+    } else if (axis.getAxisType() == AxisType.Date) {
+
+      gridStep = new DateGridStep(axis.getDirection(), workingSpace, axis.getMin(), axis.getMax(), getChart().getStyleManager());
+
+    } else if (axis.getAxisType() == AxisType.Logarithmic) {
+
+    }
+
+    // /////////////////////////
 
     if (isVisible) {
 
@@ -120,11 +138,11 @@ public class AxisTick implements ChartPart {
 
   public List<Integer> getTickLocations() {
 
-    return axisTickComputer.getTickLocations();
+    return gridStep.getTickLocations();
   }
 
   public List<String> getTickLabels() {
 
-    return axisTickComputer.getTickLabels();
+    return gridStep.getTickLabels();
   }
 }
diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickComputer.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickComputer.java
deleted file mode 100644
index 07e8a090ba99f15f48b9108100211bd4c8ef1934..0000000000000000000000000000000000000000
--- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickComputer.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * Copyright (C) 2013 Xeiam LLC http://xeiam.com
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package com.xeiam.xchart.internal.chartpart;
-
-import java.math.BigDecimal;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.xeiam.xchart.internal.chartpart.Axis.AxisType;
-import com.xeiam.xchart.internal.chartpart.Axis.Direction;
-import com.xeiam.xchart.internal.chartpart.gridstep.DecimalGridStep;
-import com.xeiam.xchart.style.ValueFormatter;
-
-/**
- * This class encapsulates the logic to generate the axis tick mark and axis tick label data for rendering the axis ticks
- * 
- * @author timmolter
- */
-public class AxisTickComputer {
-
-  /** the List of tick label position in pixels */
-  private List<Integer> tickLocations = new LinkedList<Integer>();;
-
-  /** the List of tick label values */
-  private List<String> tickLabels = new LinkedList<String>();
-
-  private final Direction axisDirection;
-
-  private final int workingSpace;
-
-  private final BigDecimal minValue;
-
-  private final BigDecimal maxValue;
-
-  private final ValueFormatter valueFormatter;
-
-  private final AxisType axisType;
-
-  /**
-   * Constructor
-   * 
-   * @param axisDirection
-   * @param workingSpace
-   * @param minValue
-   * @param maxValue
-   * @param valueFormatter
-   * @param axisType
-   */
-  public AxisTickComputer(Direction axisDirection, int workingSpace, BigDecimal minValue, BigDecimal maxValue, ValueFormatter valueFormatter, AxisType axisType) {
-
-    this.axisDirection = axisDirection;
-    this.workingSpace = workingSpace;
-    this.minValue = minValue;
-    this.maxValue = maxValue;
-    this.valueFormatter = valueFormatter;
-    this.axisType = axisType;
-
-    computeAxisTick();
-  }
-
-  private void computeAxisTick() {
-
-    System.out.println("workingSpace= " + workingSpace);
-
-    // a check if all axis data are the exact same values
-    if (maxValue == minValue) {
-      tickLabels.add(format(maxValue));
-      tickLocations.add((int) (workingSpace / 2.0));
-      return;
-    }
-
-    // tick space - a percentage of the working space available for ticks, i.e. 95%
-    int tickSpace = AxisPair.getTickSpace(workingSpace); // in plot space
-    System.out.println("tickSpace= " + tickSpace);
-
-    // where the tick should begin in the working space in pixels
-    int margin = AxisPair.getTickStartOffset(workingSpace, tickSpace); // in plot space
-
-    // the span of the data
-    double span = Math.abs(maxValue.subtract(minValue).doubleValue()); // in data space
-
-    BigDecimal gridStep = null;
-    BigDecimal firstPosition = null;
-    if (axisType == AxisType.Number) {
-
-      DecimalGridStep decimalGridStepHelper = new DecimalGridStep();
-      gridStep = decimalGridStepHelper.getGridStepForDecimal(axisDirection, span, tickSpace);
-      firstPosition = decimalGridStepHelper.getFirstPosition(minValue, gridStep);
-
-    } else if (axisType == AxisType.Date) {
-
-    } else if (axisType == AxisType.Logarithmic) {
-
-    }
-
-    // generate all tickLabels and tickLocations from the first to last position
-    for (BigDecimal tickPosition = firstPosition; tickPosition.compareTo(maxValue) <= 0; tickPosition = tickPosition.add(gridStep)) {
-
-      tickLabels.add(format(tickPosition));
-      // here we convert tickPosition finally to plot space, i.e. pixels
-      int tickLabelPosition = (int) (margin + ((tickPosition.subtract(minValue)).doubleValue() / (maxValue.subtract(minValue)).doubleValue() * tickSpace));
-      tickLocations.add(tickLabelPosition);
-    }
-
-  }
-
-  /**
-   * Format the number
-   * 
-   * @param value The number to be formatted
-   * @return The formatted number in String form
-   */
-  private String format(BigDecimal value) {
-
-    if (axisType == AxisType.Number) {
-
-      return valueFormatter.formatNumber(value);
-    } else {
-
-      return valueFormatter.formatDateValue(value, minValue, maxValue);
-    }
-  }
-
-  public List<Integer> getTickLocations() {
-
-    return tickLocations;
-  }
-
-  public List<String> getTickLabels() {
-
-    return tickLabels;
-  }
-
-}
diff --git a/xchart/src/main/java/com/xeiam/xchart/style/ValueFormatter.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DateFormatter.java
similarity index 68%
rename from xchart/src/main/java/com/xeiam/xchart/style/ValueFormatter.java
rename to xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DateFormatter.java
index 19b15d428754e720e12c4e24dd059c3968ea84fd..21fae0c6bce48bd3545f852930c9868721577c4e 100644
--- a/xchart/src/main/java/com/xeiam/xchart/style/ValueFormatter.java
+++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DateFormatter.java
@@ -19,11 +19,9 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-package com.xeiam.xchart.style;
+package com.xeiam.xchart.internal.chartpart.gridstep;
 
 import java.math.BigDecimal;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
 import java.text.SimpleDateFormat;
 import java.util.Locale;
 import java.util.TimeZone;
@@ -32,10 +30,8 @@ import java.util.concurrent.TimeUnit;
 /**
  * @author timmolter
  */
-public class ValueFormatter {
+public class DateFormatter {
 
-  private String normalDecimalPattern;
-  private String scientificDecimalPattern;
   private String datePattern;
   private Locale locale;
   private TimeZone timezone;
@@ -51,43 +47,13 @@ public class ValueFormatter {
   /**
    * Constructor
    */
-  public ValueFormatter() {
+  public DateFormatter() {
 
-    normalDecimalPattern = "#.####";
-    scientificDecimalPattern = "0.##E0";
     datePattern = "HHmmss";
     locale = Locale.getDefault();
     timezone = TimeZone.getDefault();
   }
 
-  /**
-   * Format a number value, if the override patterns are null, it uses defaults
-   * 
-   * @param value
-   * @return
-   */
-  public String formatNumber(BigDecimal value) {
-
-    NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
-
-    BigDecimal absoluteValue = value.abs();
-
-    if (absoluteValue.compareTo(new BigDecimal("10000.000001")) == -1 && absoluteValue.compareTo(new BigDecimal(".0009999999")) == 1 || BigDecimal.ZERO.compareTo(value) == 0) {
-
-      DecimalFormat normalFormat = (DecimalFormat) numberFormat;
-      normalFormat.applyPattern(normalDecimalPattern);
-      return normalFormat.format(value);
-
-    } else {
-
-      DecimalFormat scientificFormat = (DecimalFormat) numberFormat;
-      scientificFormat.applyPattern(scientificDecimalPattern);
-      return scientificFormat.format(value);
-
-    }
-
-  }
-
   /**
    * Format a date value
    * 
@@ -98,6 +64,8 @@ public class ValueFormatter {
    */
   public String formatDateValue(BigDecimal value, BigDecimal min, BigDecimal max) {
 
+    // TODO check if min and max are the same, then calculate this differently
+
     // intelligently set date pattern if none is given
     long diff = max.subtract(min).longValue();
 
@@ -126,26 +94,6 @@ public class ValueFormatter {
 
   }
 
-  /**
-   * Set the decimal formatter for all tick labels
-   * 
-   * @param pattern - the pattern describing the decimal format
-   */
-  public void setNormalDecimalPattern(String normalDecimalPattern) {
-
-    this.normalDecimalPattern = normalDecimalPattern;
-  }
-
-  /**
-   * Set the scientific notation formatter for all tick labels
-   * 
-   * @param pattern - the pattern describing the scientific notation format
-   */
-  public void setScientificDecimalPattern(String scientificDecimalPattern) {
-
-    this.scientificDecimalPattern = scientificDecimalPattern;
-  }
-
   /**
    * Set the String formatter for Data x-axis
    * 
diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DateGridStep.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DateGridStep.java
new file mode 100644
index 0000000000000000000000000000000000000000..d27af6ebff922b3d851dbe38399e19ef00853024
--- /dev/null
+++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DateGridStep.java
@@ -0,0 +1,205 @@
+/**
+ * Copyright (C) 2013 Xeiam LLC http://xeiam.com
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.xeiam.xchart.internal.chartpart.gridstep;
+
+import java.math.BigDecimal;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.xeiam.xchart.internal.chartpart.Axis.Direction;
+import com.xeiam.xchart.internal.chartpart.AxisPair;
+import com.xeiam.xchart.style.StyleManager;
+
+/**
+ * @author timmolter
+ */
+public class DateGridStep implements GridStep {
+
+  /** the default tick mark step hint for x axis */
+  private static final int DEFAULT_TICK_MARK_STEP_HINT_X = 74;
+
+  /** the default tick mark step hint for y axis */
+  private static final int DEFAULT_TICK_MARK_STEP_HINT_Y = 44;
+
+  /** the List of tick label position in pixels */
+  private List<Integer> tickLocations = new LinkedList<Integer>();;
+
+  /** the List of tick label values */
+  private List<String> tickLabels = new LinkedList<String>();
+
+  private final Direction axisDirection;
+
+  private final int workingSpace;
+
+  private final BigDecimal minValue;
+
+  private final BigDecimal maxValue;
+
+  private final StyleManager styleManager;
+
+  /**
+   * Constructor
+   * 
+   * @param axisDirection
+   * @param workingSpace
+   * @param minValue
+   * @param maxValue
+   */
+  public DateGridStep(Direction axisDirection, int workingSpace, BigDecimal minValue, BigDecimal maxValue, StyleManager styleManager) {
+
+    this.axisDirection = axisDirection;
+    this.workingSpace = workingSpace;
+    this.minValue = minValue;
+    this.maxValue = maxValue;
+    this.styleManager = styleManager;
+
+    go();
+  }
+
+  private void go() {
+
+    // a check if all axis data are the exact same values
+    if (minValue == maxValue) {
+      tickLabels.add(styleManager.getDateFormatter().formatDateValue(maxValue, maxValue, maxValue));
+      tickLocations.add((int) (workingSpace / 2.0));
+      return;
+    }
+
+    // tick space - a percentage of the working space available for ticks, i.e. 95%
+    int tickSpace = AxisPair.getTickSpace(workingSpace); // in plot space
+    System.out.println("tickSpace= " + tickSpace);
+
+    // where the tick should begin in the working space in pixels
+    int margin = AxisPair.getTickStartOffset(workingSpace, tickSpace); // in plot space BigDecimal gridStep = getGridStepForDecimal(tickSpace);
+
+    BigDecimal gridStep = getGridStepForDecimal(tickSpace);
+
+    BigDecimal firstPosition = getFirstPosition(minValue, gridStep);
+
+    // generate all tickLabels and tickLocations from the first to last position
+    for (BigDecimal tickPosition = firstPosition; tickPosition.compareTo(maxValue) <= 0; tickPosition = tickPosition.add(gridStep)) {
+
+      tickLabels.add(styleManager.getDateFormatter().formatDateValue(tickPosition, minValue, maxValue));
+      // here we convert tickPosition finally to plot space, i.e. pixels
+      int tickLabelPosition = (int) (margin + ((tickPosition.subtract(minValue)).doubleValue() / (maxValue.subtract(minValue)).doubleValue() * tickSpace));
+      tickLocations.add(tickLabelPosition);
+    }
+  }
+
+  /**
+   * Determine the grid step for the data set given the space in pixels allocated for the axis
+   * 
+   * @param tickSpace in plot space
+   * @return
+   */
+  private BigDecimal getGridStepForDecimal(int tickSpace) {
+
+    // the span of the data
+    double span = Math.abs(maxValue.subtract(minValue).doubleValue()); // in data space
+
+    int tickMarkSpaceHint = (axisDirection == Direction.X ? DEFAULT_TICK_MARK_STEP_HINT_X : DEFAULT_TICK_MARK_STEP_HINT_Y);
+
+    // for very short plots, squeeze some more ticks in than normal
+    if (axisDirection == Direction.Y && tickSpace < 160) {
+      tickMarkSpaceHint = 25;
+    }
+
+    double gridStepHint = span / tickSpace * tickMarkSpaceHint;
+
+    // gridStepHint --> significand * 10 ** exponent
+    // e.g. 724.1 --> 7.241 * 10 ** 2
+    double significand = gridStepHint;
+    int exponent = 0;
+    if (significand == 0) {
+      exponent = 1;
+    } else if (significand < 1) {
+      while (significand < 1) {
+        significand *= 10.0;
+        exponent--;
+      }
+    } else {
+      while (significand >= 10) {
+        significand /= 10.0;
+        exponent++;
+      }
+    }
+
+    // calculate the grid step with hint.
+    BigDecimal gridStep;
+    if (significand > 7.5) {
+      // gridStep = 10.0 * 10 ** exponent
+      gridStep = BigDecimal.TEN.multiply(pow(10, exponent));
+    } else if (significand > 3.5) {
+      // gridStep = 5.0 * 10 ** exponent
+      gridStep = new BigDecimal(new Double(5).toString()).multiply(pow(10, exponent));
+    } else if (significand > 1.5) {
+      // gridStep = 2.0 * 10 ** exponent
+      gridStep = new BigDecimal(new Double(2).toString()).multiply(pow(10, exponent));
+    } else {
+      // gridStep = 1.0 * 10 ** exponent
+      gridStep = pow(10, exponent);
+    }
+    return gridStep;
+  }
+
+  /**
+   * Calculates the value of the first argument raised to the power of the second argument.
+   * 
+   * @param base the base
+   * @param exponent the exponent
+   * @return the value <tt>a<sup>b</sup></tt> in <tt>BigDecimal</tt>
+   */
+  private BigDecimal pow(double base, int exponent) {
+
+    BigDecimal value;
+    if (exponent > 0) {
+      value = new BigDecimal(new Double(base).toString()).pow(exponent);
+    } else {
+      value = BigDecimal.ONE.divide(new BigDecimal(new Double(base).toString()).pow(-exponent));
+    }
+    return value;
+  }
+
+  private BigDecimal getFirstPosition(final BigDecimal min, BigDecimal gridStep) {
+
+    BigDecimal firstPosition;
+    if (min.remainder(gridStep).doubleValue() <= 0.0) {
+      firstPosition = min.subtract(min.remainder(gridStep));
+    } else {
+      firstPosition = min.subtract(min.remainder(gridStep)).add(gridStep);
+    }
+    return firstPosition;
+  }
+
+  @Override
+  public List<Integer> getTickLocations() {
+
+    return tickLocations;
+  }
+
+  @Override
+  public List<String> getTickLabels() {
+
+    return tickLabels;
+  }
+
+}
diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DecimalFormatter.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DecimalFormatter.java
new file mode 100644
index 0000000000000000000000000000000000000000..abf2d54d1cf25f0051f8605ea7618c8166841493
--- /dev/null
+++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DecimalFormatter.java
@@ -0,0 +1,108 @@
+/**
+ * Copyright (C) 2013 Xeiam LLC http://xeiam.com
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.xeiam.xchart.internal.chartpart.gridstep;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+/**
+ * @author timmolter
+ */
+public class DecimalFormatter {
+
+  private String normalDecimalPattern;
+  private String scientificDecimalPattern;
+  // TODO move to parent class??
+  private Locale locale;
+
+  /**
+   * Constructor
+   */
+  public DecimalFormatter() {
+
+    normalDecimalPattern = "#.####";
+    scientificDecimalPattern = "0.##E0";
+    locale = Locale.getDefault();
+
+  }
+
+  /**
+   * Format a number value, if the override patterns are null, it uses defaults
+   * 
+   * @param value
+   * @return
+   */
+  public String formatNumber(BigDecimal value) {
+
+    NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
+
+    BigDecimal absoluteValue = value.abs();
+
+    if (absoluteValue.compareTo(new BigDecimal("10000.000001")) == -1 && absoluteValue.compareTo(new BigDecimal(".0009999999")) == 1 || BigDecimal.ZERO.compareTo(value) == 0) {
+
+      DecimalFormat normalFormat = (DecimalFormat) numberFormat;
+      normalFormat.applyPattern(normalDecimalPattern);
+      return normalFormat.format(value);
+
+    } else {
+
+      DecimalFormat scientificFormat = (DecimalFormat) numberFormat;
+      scientificFormat.applyPattern(scientificDecimalPattern);
+      return scientificFormat.format(value);
+
+    }
+
+  }
+
+  /**
+   * Set the decimal formatter for all tick labels
+   * 
+   * @param pattern - the pattern describing the decimal format
+   */
+  public void setNormalDecimalPattern(String normalDecimalPattern) {
+
+    this.normalDecimalPattern = normalDecimalPattern;
+  }
+
+  /**
+   * Set the scientific notation formatter for all tick labels
+   * 
+   * @param pattern - the pattern describing the scientific notation format
+   */
+  public void setScientificDecimalPattern(String scientificDecimalPattern) {
+
+    this.scientificDecimalPattern = scientificDecimalPattern;
+  }
+
+  /**
+   * Set the locale to use for rendering the chart
+   * 
+   * @param locale - the locale to use when formatting Strings and dates for the axis tick labels
+   */
+  public void setLocale(Locale locale) {
+
+    this.locale = locale;
+  }
+
+}
diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DecimalGridStep.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DecimalGridStep.java
index 6748e34687284a1cf9fbbdc7f466bffc786cd62d..b1426418da6de94d78e43bc732a97b5adcbb2690 100644
--- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DecimalGridStep.java
+++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/DecimalGridStep.java
@@ -22,13 +22,19 @@
 package com.xeiam.xchart.internal.chartpart.gridstep;
 
 import java.math.BigDecimal;
+import java.util.LinkedList;
+import java.util.List;
 
 import com.xeiam.xchart.internal.chartpart.Axis.Direction;
+import com.xeiam.xchart.internal.chartpart.AxisPair;
+import com.xeiam.xchart.style.StyleManager;
 
 /**
+ * This class encapsulates the logic to generate the axis tick mark and axis tick label data for rendering the axis ticks for decimla axes
+ * 
  * @author timmolter
  */
-public class DecimalGridStep {
+public class DecimalGridStep implements GridStep {
 
   /** the default tick mark step hint for x axis */
   private static final int DEFAULT_TICK_MARK_STEP_HINT_X = 74;
@@ -36,13 +42,81 @@ public class DecimalGridStep {
   /** the default tick mark step hint for y axis */
   private static final int DEFAULT_TICK_MARK_STEP_HINT_Y = 44;
 
+  /** the List of tick label position in pixels */
+  private List<Integer> tickLocations = new LinkedList<Integer>();;
+
+  /** the List of tick label values */
+  private List<String> tickLabels = new LinkedList<String>();
+
+  private final Direction axisDirection;
+
+  private final int workingSpace;
+
+  private final BigDecimal minValue;
+
+  private final BigDecimal maxValue;
+
+  private final StyleManager styleManager;
+
+  /**
+   * Constructor
+   * 
+   * @param axisDirection
+   * @param workingSpace
+   * @param minValue
+   * @param maxValue
+   */
+  public DecimalGridStep(Direction axisDirection, int workingSpace, BigDecimal minValue, BigDecimal maxValue, StyleManager styleManager) {
+
+    this.axisDirection = axisDirection;
+    this.workingSpace = workingSpace;
+    this.minValue = minValue;
+    this.maxValue = maxValue;
+    this.styleManager = styleManager;
+
+    go();
+  }
+
+  private void go() {
+
+    // a check if all axis data are the exact same values
+    if (minValue == maxValue) {
+      tickLabels.add(styleManager.getDecimalFormatter().formatNumber(maxValue));
+      tickLocations.add((int) (workingSpace / 2.0));
+      return;
+    }
+
+    // tick space - a percentage of the working space available for ticks, i.e. 95%
+    int tickSpace = AxisPair.getTickSpace(workingSpace); // in plot space
+    System.out.println("tickSpace= " + tickSpace);
+
+    // where the tick should begin in the working space in pixels
+    int margin = AxisPair.getTickStartOffset(workingSpace, tickSpace); // in plot space BigDecimal gridStep = getGridStepForDecimal(tickSpace);
+
+    BigDecimal gridStep = getGridStepForDecimal(tickSpace);
+
+    BigDecimal firstPosition = getFirstPosition(minValue, gridStep);
+
+    // generate all tickLabels and tickLocations from the first to last position
+    for (BigDecimal tickPosition = firstPosition; tickPosition.compareTo(maxValue) <= 0; tickPosition = tickPosition.add(gridStep)) {
+
+      tickLabels.add(styleManager.getDecimalFormatter().formatNumber(tickPosition));
+      // here we convert tickPosition finally to plot space, i.e. pixels
+      int tickLabelPosition = (int) (margin + ((tickPosition.subtract(minValue)).doubleValue() / (maxValue.subtract(minValue)).doubleValue() * tickSpace));
+      tickLocations.add(tickLabelPosition);
+    }
+  }
+
   /**
    * Determine the grid step for the data set given the space in pixels allocated for the axis
    * 
    * @param tickSpace in plot space
    * @return
    */
-  public BigDecimal getGridStepForDecimal(Direction axisDirection, double span, int tickSpace) {
+  private BigDecimal getGridStepForDecimal(int tickSpace) {
+
+    // the span of the data
+    double span = Math.abs(maxValue.subtract(minValue).doubleValue()); // in data space
 
     int tickMarkSpaceHint = (axisDirection == Direction.X ? DEFAULT_TICK_MARK_STEP_HINT_X : DEFAULT_TICK_MARK_STEP_HINT_Y);
 
@@ -107,7 +181,7 @@ public class DecimalGridStep {
     return value;
   }
 
-  public BigDecimal getFirstPosition(final BigDecimal min, BigDecimal gridStep) {
+  private BigDecimal getFirstPosition(final BigDecimal min, BigDecimal gridStep) {
 
     BigDecimal firstPosition;
     if (min.remainder(gridStep).doubleValue() <= 0.0) {
@@ -118,4 +192,16 @@ public class DecimalGridStep {
     return firstPosition;
   }
 
+  @Override
+  public List<Integer> getTickLocations() {
+
+    return tickLocations;
+  }
+
+  @Override
+  public List<String> getTickLabels() {
+
+    return tickLabels;
+  }
+
 }
diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/GridStep.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/GridStep.java
new file mode 100644
index 0000000000000000000000000000000000000000..f10ec2bfdf1da6c8a3044a85eb9a5314553d57cd
--- /dev/null
+++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/gridstep/GridStep.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2013 Xeiam LLC http://xeiam.com
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package com.xeiam.xchart.internal.chartpart.gridstep;
+
+import java.util.List;
+
+/**
+ * @author timmolter
+ */
+public interface GridStep {
+
+  public List<Integer> getTickLocations();
+
+  public List<String> getTickLabels();
+
+}
diff --git a/xchart/src/main/java/com/xeiam/xchart/style/StyleManager.java b/xchart/src/main/java/com/xeiam/xchart/style/StyleManager.java
index ce15199f3cd94a4d6b2306c1bd0c56f259e0a093..32b9701b6d7652037cd9513b4d57763002c958d7 100644
--- a/xchart/src/main/java/com/xeiam/xchart/style/StyleManager.java
+++ b/xchart/src/main/java/com/xeiam/xchart/style/StyleManager.java
@@ -25,6 +25,8 @@ import java.awt.Color;
 import java.awt.Font;
 import java.awt.Stroke;
 
+import com.xeiam.xchart.internal.chartpart.gridstep.DateFormatter;
+import com.xeiam.xchart.internal.chartpart.gridstep.DecimalFormatter;
 import com.xeiam.xchart.style.theme.Theme;
 import com.xeiam.xchart.style.theme.XChartTheme;
 
@@ -94,6 +96,11 @@ public class StyleManager {
   // Error Bars ///////////////////////////////
   private Color errorBarsColor;
 
+  // Formatting ////////////////////////////////
+
+  private DecimalFormatter decimalFormatter;
+  private DateFormatter dateFormatter;
+
   /**
    * Constructor
    */
@@ -151,6 +158,10 @@ public class StyleManager {
 
     // Error Bars ///////////////////////////////
     errorBarsColor = theme.getErrorBarsColor();
+
+    // Formatting ////////////////////////////////
+    decimalFormatter = new DecimalFormatter();
+    dateFormatter = new DateFormatter();
   }
 
   /**
@@ -741,4 +752,17 @@ public class StyleManager {
 
     return errorBarsColor;
   }
+
+  // Formatting ////////////////////////////////
+
+  public DecimalFormatter getDecimalFormatter() {
+
+    return decimalFormatter;
+  }
+
+  public DateFormatter getDateFormatter() {
+
+    return dateFormatter;
+  }
+
 }
diff --git a/xchart/src/test/java/com/xeiam/xchart/unit/DecimalGridStepTest.java b/xchart/src/test/java/com/xeiam/xchart/unit/DecimalGridStepTest.java
index 265fbf938c27778cf20a8a586dcc6e17e84c7538..c85b834bb1dcc76c63773c64002be53872b07e92 100644
--- a/xchart/src/test/java/com/xeiam/xchart/unit/DecimalGridStepTest.java
+++ b/xchart/src/test/java/com/xeiam/xchart/unit/DecimalGridStepTest.java
@@ -21,13 +21,8 @@
  */
 package com.xeiam.xchart.unit;
 
-import java.math.BigDecimal;
-
 import org.junit.Test;
 
-import com.xeiam.xchart.internal.chartpart.Axis.Direction;
-import com.xeiam.xchart.internal.chartpart.gridstep.DecimalGridStep;
-
 /**
  * @author timmolter
  */
@@ -36,11 +31,11 @@ public class DecimalGridStepTest {
   @Test
   public void testDateOneMinuteTimespan() {
 
-    DecimalGridStep decimalGridStep = new DecimalGridStep();
-    BigDecimal gridStep = decimalGridStep.getGridStepForDecimal(Direction.X, 30, 600);
-    System.out.println("gridStep= " + gridStep);
-    BigDecimal first = decimalGridStep.getFirstPosition(new BigDecimal(-15), gridStep);
-    System.out.println("first= " + first);
+    // DecimalGridStep decimalGridStep = new DecimalGridStep();
+    // BigDecimal gridStep = decimalGridStep.getGridStepForDecimal(Direction.X, 30, 600);
+    // System.out.println("gridStep= " + gridStep);
+    // BigDecimal first = decimalGridStep.getFirstPosition(new BigDecimal(-15), gridStep);
+    // System.out.println("first= " + first);
 
   }
 
diff --git a/xchart/src/test/java/com/xeiam/xchart/unit/ValueFormatterTest.java b/xchart/src/test/java/com/xeiam/xchart/unit/ValueFormatterTest.java
index 3c501749fe4e0d6c2eaa4b05b0ff5230380944b8..4edb9ce5481b646becde8565df6c259149fb501b 100644
--- a/xchart/src/test/java/com/xeiam/xchart/unit/ValueFormatterTest.java
+++ b/xchart/src/test/java/com/xeiam/xchart/unit/ValueFormatterTest.java
@@ -30,7 +30,8 @@ import java.util.TimeZone;
 
 import org.junit.Test;
 
-import com.xeiam.xchart.style.ValueFormatter;
+import com.xeiam.xchart.internal.chartpart.gridstep.DateFormatter;
+import com.xeiam.xchart.internal.chartpart.gridstep.DecimalFormatter;
 
 /**
  * @author timmolter
@@ -42,7 +43,7 @@ public class ValueFormatterTest {
   @Test
   public void testNumberFormatting() {
 
-    ValueFormatter axisTickLabelFormatter = new ValueFormatter();
+    DecimalFormatter axisTickLabelFormatter = new DecimalFormatter();
 
     // big
     axisTickLabelFormatter.setLocale(locale);
@@ -135,7 +136,7 @@ public class ValueFormatterTest {
   @Test
   public void testDateFormatting() {
 
-    ValueFormatter axisTickLabelFormatter = new ValueFormatter();
+    DateFormatter axisTickLabelFormatter = new DateFormatter();
 
     TimeZone timeZone = TimeZone.getTimeZone("UTC");
 
diff --git a/xchart/src/test/java/com/xeiam/xchart/unit/XAxisTest.java b/xchart/src/test/java/com/xeiam/xchart/unit/XAxisTest.java
deleted file mode 100644
index 4084df72324ee49d716fbb66bfe0619f7e3db01b..0000000000000000000000000000000000000000
--- a/xchart/src/test/java/com/xeiam/xchart/unit/XAxisTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Copyright (C) 2013 Xeiam LLC http://xeiam.com
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package com.xeiam.xchart.unit;
-
-import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.List;
-
-import org.junit.Test;
-
-import com.xeiam.xchart.internal.chartpart.Axis.AxisType;
-import com.xeiam.xchart.internal.chartpart.Axis.Direction;
-import com.xeiam.xchart.internal.chartpart.AxisTickComputer;
-import com.xeiam.xchart.style.ValueFormatter;
-
-/**
- * @author timmolter
- */
-public class XAxisTest {
-
-  // @Test
-  public void testNumber() {
-
-    AxisTickComputer axisTickComputer = new AxisTickComputer(Direction.X, 1000, new BigDecimal(0), new BigDecimal(10), new ValueFormatter(), AxisType.Number);
-    // Labels
-    List<String> tickLabels = axisTickComputer.getTickLabels();
-    System.out.println(Arrays.toString(tickLabels.toArray()));
-    // Locations
-    List<Integer> tickLocations = axisTickComputer.getTickLocations();
-    System.out.println(Arrays.toString(tickLocations.toArray()));
-  }
-
-  @Test
-  public void testDateOneMinuteTimespan() {
-
-    AxisTickComputer axisTickComputer = new AxisTickComputer(Direction.X, 1000, new BigDecimal(1361031254000L), new BigDecimal(1361031314000L), new ValueFormatter(), AxisType.Date);
-    // Labels
-    List<String> tickLabels = axisTickComputer.getTickLabels();
-    System.out.println(Arrays.toString(tickLabels.toArray()));
-    // Locations
-    List<Integer> tickLocations = axisTickComputer.getTickLocations();
-    System.out.println(Arrays.toString(tickLocations.toArray()));
-  }
-
-}