changeset 188:44059a9aa639

Bug 3194: Time-Awareness XAxis in FXAnalyzer Reviewed-by: ykubota https://github.com/HeapStats/heapstats/pull/40
author Yasumasa Suenaga <yasuenag@gmail.com>
date Wed, 09 Nov 2016 22:31:27 +0900
parents 14ea8c5a07c9
children 8f717a109972
files ChangeLog analyzer/fx/heapstats.properties analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/log/tabs/LogResourcesController.java analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/SnapShotController.java analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/HistogramController.java analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/SummaryController.java analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/utils/EpochTimeConverter.java analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/utils/HeapStatsUtils.java analyzer/fx/src/main/resources/jp/co/ntt/oss/heapstats/plugin/builtin/log/tabs/resources.fxml analyzer/fx/src/main/resources/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/histogram.fxml analyzer/fx/src/main/resources/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/summary.fxml
diffstat 11 files changed, 245 insertions(+), 126 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Nov 09 21:15:19 2016 +0900
+++ b/ChangeLog	Wed Nov 09 22:31:27 2016 +0900
@@ -1,6 +1,7 @@
 2016-11-09  Yasumasa Suenaga <yasuenag@gmail.com>
 
 	* Bug 3225: JVM may hang when deadlock detector and safepoint are conflicted
+	* Bug 3194: Time-Awareness XAxis in FXAnalyzer
 
 2016-11-08  Yasumasa Suenaga <yasuenag@gmail.com>
 
--- a/analyzer/fx/heapstats.properties	Wed Nov 09 21:15:19 2016 +0900
+++ b/analyzer/fx/heapstats.properties	Wed Nov 09 22:31:27 2016 +0900
@@ -14,3 +14,4 @@
 #plugins=
 reftree_fontsize=11
 tickmarker=false
+x_tickunit=20
--- a/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/log/tabs/LogResourcesController.java	Wed Nov 09 21:15:19 2016 +0900
+++ b/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/log/tabs/LogResourcesController.java	Wed Nov 09 22:31:27 2016 +0900
@@ -19,6 +19,7 @@
 
 import java.net.URL;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.List;
 import java.util.Optional;
 import java.util.ResourceBundle;
@@ -35,8 +36,8 @@
 import javafx.fxml.Initializable;
 import javafx.scene.Node;
 import javafx.scene.chart.Axis;
-import javafx.scene.chart.CategoryAxis;
 import javafx.scene.chart.LineChart;
+import javafx.scene.chart.NumberAxis;
 import javafx.scene.chart.StackedAreaChart;
 import javafx.scene.chart.XYChart;
 import javafx.scene.control.Label;
@@ -53,6 +54,7 @@
 import jp.co.ntt.oss.heapstats.container.log.DiffData;
 import jp.co.ntt.oss.heapstats.container.log.LogData;
 import jp.co.ntt.oss.heapstats.container.log.SummaryData;
+import jp.co.ntt.oss.heapstats.utils.EpochTimeConverter;
 import jp.co.ntt.oss.heapstats.utils.HeapStatsUtils;
 
 /**
@@ -64,59 +66,59 @@
     private GridPane chartGrid;
 
     @FXML
-    private StackedAreaChart<String, Double> javaCPUChart;
+    private StackedAreaChart<Number, Double> javaCPUChart;
 
-    private XYChart.Series<String, Double> javaUserUsage;
+    private XYChart.Series<Number, Double> javaUserUsage;
 
-    private XYChart.Series<String, Double> javaSysUsage;
+    private XYChart.Series<Number, Double> javaSysUsage;
 
     @FXML
-    private StackedAreaChart<String, Double> systemCPUChart;
+    private StackedAreaChart<Number, Double> systemCPUChart;
 
-    private XYChart.Series<String, Double> systemUserUsage;
+    private XYChart.Series<Number, Double> systemUserUsage;
 
-    private XYChart.Series<String, Double> systemNiceUsage;
+    private XYChart.Series<Number, Double> systemNiceUsage;
 
-    private XYChart.Series<String, Double> systemSysUsage;
+    private XYChart.Series<Number, Double> systemSysUsage;
 
-    private XYChart.Series<String, Double> systemIdleUsage;
+    private XYChart.Series<Number, Double> systemIdleUsage;
 
-    private XYChart.Series<String, Double> systemIOWaitUsage;
+    private XYChart.Series<Number, Double> systemIOWaitUsage;
 
-    private XYChart.Series<String, Double> systemIRQUsage;
+    private XYChart.Series<Number, Double> systemIRQUsage;
 
-    private XYChart.Series<String, Double> systemSoftIRQUsage;
+    private XYChart.Series<Number, Double> systemSoftIRQUsage;
 
-    private XYChart.Series<String, Double> systemStealUsage;
+    private XYChart.Series<Number, Double> systemStealUsage;
 
-    private XYChart.Series<String, Double> systemGuestUsage;
+    private XYChart.Series<Number, Double> systemGuestUsage;
 
     @FXML
-    private LineChart<String, Long> javaMemoryChart;
+    private LineChart<Number, Long> javaMemoryChart;
 
-    private XYChart.Series<String, Long> javaVSZUsage;
+    private XYChart.Series<Number, Long> javaVSZUsage;
 
-    private XYChart.Series<String, Long> javaRSSUsage;
+    private XYChart.Series<Number, Long> javaRSSUsage;
 
     @FXML
-    private LineChart<String, Long> safepointChart;
+    private LineChart<Number, Long> safepointChart;
 
-    private XYChart.Series<String, Long> safepoints;
+    private XYChart.Series<Number, Long> safepoints;
 
     @FXML
-    private LineChart<String, Long> safepointTimeChart;
+    private LineChart<Number, Long> safepointTimeChart;
 
-    private XYChart.Series<String, Long> safepointTime;
+    private XYChart.Series<Number, Long> safepointTime;
 
     @FXML
-    private LineChart<String, Long> threadChart;
+    private LineChart<Number, Long> threadChart;
 
-    private XYChart.Series<String, Long> threads;
+    private XYChart.Series<Number, Long> threads;
 
     @FXML
-    private LineChart<String, Long> monitorChart;
+    private LineChart<Number, Long> monitorChart;
 
-    private XYChart.Series<String, Long> monitors;
+    private XYChart.Series<Number, Long> monitors;
 
     @FXML
     private TableView<SummaryData.SummaryDataEntry> procSummary;
@@ -136,6 +138,8 @@
     private List<LocalDateTime> suspectList;
     
     private ResourceBundle resource;
+    
+    private EpochTimeConverter epochTimeConverter;
 
     /**
      * Initializes the controller class.
@@ -159,6 +163,8 @@
         popupText.setStyle("-fx-font-family: monospace; -fx-text-fill: white; -fx-background-color: black;");
         chartPopup.getContent().add(popupText);
         archiveList = new SimpleObjectProperty<>();
+        
+        epochTimeConverter = new EpochTimeConverter();
     }
 
     /**
@@ -227,25 +233,31 @@
      * @param event Mouse event.
      * @param labelFunc Function to format label string.
      */
-    private void showChartPopup(XYChart<String, ? extends Number> chart, String xValue, MouseEvent event, Function<? super Number, String> labelFunc) {
-        String label = chart.getData().stream()
-                .map(s -> s.getName() + " = " + s.getData().stream()
-                        .filter(d -> d.getXValue().equals(xValue))
-                        .map(d -> labelFunc.apply(d.getYValue()))
-                        .findAny()
-                        .orElse("<none>"))
-                .collect(Collectors.joining("\n"));
-
-        popupText.setText(xValue + "\n" + label);
-        chartPopup.show(chart, event.getScreenX() + 15.0d, event.getScreenY() + 3.0d);
+    private void showChartPopup(XYChart<Number, ? extends Number> chart, Number xValue, MouseEvent event, Function<? super Number, String> labelFunc) {
+        boolean isContained = chart.getData()
+                                   .stream()
+                                   .flatMap(s -> s.getData().stream())
+                                   .anyMatch(d -> d.getXValue().longValue() == xValue.longValue());
+        if(isContained){
+            String label = chart.getData()
+                                .stream()
+                                .map(s -> s.getName() + " = " + s.getData()
+                                                                 .stream()
+                                                                 .filter(d -> d.getXValue().longValue() == xValue.longValue())
+                                                                 .map(d -> labelFunc.apply(d.getYValue()))
+                                                                 .findAny()
+                                                                 .get())
+                                .collect(Collectors.joining("\n"));
+            popupText.setText(epochTimeConverter.toString(xValue) + "\n" + label);
+            chartPopup.show(chart, event.getScreenX() + 15.0d, event.getScreenY() + 3.0d);
+        }
     }
 
     @FXML
     @SuppressWarnings("unchecked")
     private void onChartMouseMoved(MouseEvent event) {
-        XYChart<String, ? extends Number> chart = (XYChart<String, ? extends Number>) event.getSource();
-        CategoryAxis xAxis = (CategoryAxis) chart.getXAxis();
-        double startXPoint = xAxis.getLayoutX() + xAxis.getStartMargin();
+        XYChart<Number, ? extends Number> chart = (XYChart<Number, ? extends Number>) event.getSource();
+        NumberAxis xAxis = (NumberAxis)chart.getXAxis();
         Function<? super Number, String> labelFunc;
 
         if ((chart == javaCPUChart) || (chart == systemCPUChart)) {
@@ -258,7 +270,7 @@
             labelFunc = d -> d.toString();
         }
 
-        Optional.ofNullable(chart.getXAxis().getValueForDisplay(event.getX() - startXPoint))
+        Optional.ofNullable(chart.getXAxis().getValueForDisplay(event.getX() - xAxis.getLayoutX()))
                 .ifPresent(v -> showChartPopup(chart, v, event, labelFunc));
     }
 
@@ -267,7 +279,7 @@
         chartPopup.hide();
     }
 
-    private void drawLineInternal(StackPane target, List<String> drawList, String style) {
+    private void drawLineInternal(StackPane target, List<Number> drawList, String style) {
         AnchorPane anchor = null;
         XYChart chart = null;
 
@@ -296,17 +308,17 @@
                 .filter(r -> r.getStyle().equals(style))
                 .collect(Collectors.toList()));
 
-        CategoryAxis xAxis = (CategoryAxis) chart.getXAxis();
+        NumberAxis xAxis = (NumberAxis) chart.getXAxis();
         Axis yAxis = chart.getYAxis();
         Label chartTitle = (Label) chart.getChildrenUnmodifiable().stream()
                 .filter(n -> n.getStyleClass().contains("chart-title"))
                 .findFirst()
                 .get();
 
-        double startX = xAxis.getLayoutX() + xAxis.getStartMargin() - 1.0d;
+        double startX = xAxis.getLayoutX() + 4.0d;
         double yPos = yAxis.getLayoutY() + chartTitle.getLayoutY() + chartTitle.getHeight();
         List<Rectangle> rectList = drawList.stream()
-                .map(s -> new Rectangle(xAxis.getDisplayPosition(s) + startX, yPos, 2.0d, yAxis.getHeight()))
+                .map(t -> new Rectangle(xAxis.getDisplayPosition(t) + startX, yPos, 2.0d, yAxis.getHeight()))
                 .peek(r -> ((Rectangle) r).setStyle(style))
                 .collect(Collectors.toList());
         anchorChildren.addAll(rectList);
@@ -318,9 +330,10 @@
             return;
         }
 
-        List<String> archiveDateList = archiveList.get().stream()
-                .map(a -> a.getDate().format(HeapStatsUtils.getDateTimeFormatter()))
-                .collect(Collectors.toList());
+        List<Number> archiveDateList = archiveList.get()
+                                                  .stream()
+                                                  .map(a -> a.getDate().atZone(ZoneId.systemDefault()).toEpochSecond())
+                                                  .collect(Collectors.toList());
         chartGrid.getChildren().stream()
                 .filter(n -> n instanceof StackPane)
                 .forEach(p -> drawLineInternal((StackPane) p, archiveDateList, "-fx-fill: black;"));
@@ -337,9 +350,9 @@
             return;
         }
 
-        List<String> suspectRebootDateList = suspectList.stream()
-                .map(d -> d.format(HeapStatsUtils.getDateTimeFormatter()))
-                .collect(Collectors.toList());
+        List<Number> suspectRebootDateList = suspectList.stream()
+                                                        .map(d -> d.atZone(ZoneId.systemDefault()).toEpochSecond())
+                                                        .collect(Collectors.toList());
         chartGrid.getChildren().stream()
                 .filter(n -> n instanceof StackPane)
                 .forEach(p -> drawLineInternal((StackPane) p, suspectRebootDateList, "-fx-fill: yellow;"));
@@ -359,33 +372,33 @@
     private class DrawLogChartTask extends Task<Void> {
 
         /* Java CPU */
-        private final ObservableList<XYChart.Data<String, Double>> javaUserUsageBuf;
-        private final ObservableList<XYChart.Data<String, Double>> javaSysUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> javaUserUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> javaSysUsageBuf;
 
         /* System CPU */
-        private final ObservableList<XYChart.Data<String, Double>> systemUserUsageBuf;
-        private final ObservableList<XYChart.Data<String, Double>> systemNiceUsageBuf;
-        private final ObservableList<XYChart.Data<String, Double>> systemSysUsageBuf;
-        private final ObservableList<XYChart.Data<String, Double>> systemIdleUsageBuf;
-        private final ObservableList<XYChart.Data<String, Double>> systemIOWaitUsageBuf;
-        private final ObservableList<XYChart.Data<String, Double>> systemIRQUsageBuf;
-        private final ObservableList<XYChart.Data<String, Double>> systemSoftIRQUsageBuf;
-        private final ObservableList<XYChart.Data<String, Double>> systemStealUsageBuf;
-        private final ObservableList<XYChart.Data<String, Double>> systemGuestUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> systemUserUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> systemNiceUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> systemSysUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> systemIdleUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> systemIOWaitUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> systemIRQUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> systemSoftIRQUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> systemStealUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Double>> systemGuestUsageBuf;
 
         /* Java Memory */
-        private final ObservableList<XYChart.Data<String, Long>> javaVSZUsageBuf;
-        private final ObservableList<XYChart.Data<String, Long>> javaRSSUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> javaVSZUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> javaRSSUsageBuf;
 
         /* Safepoints */
-        private final ObservableList<XYChart.Data<String, Long>> safepointsBuf;
-        private final ObservableList<XYChart.Data<String, Long>> safepointTimeBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> safepointsBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> safepointTimeBuf;
 
         /* Threads */
-        private final ObservableList<XYChart.Data<String, Long>> threadsBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> threadsBuf;
 
         /* Monitor contantion */
-        private final ObservableList<XYChart.Data<String, Long>> monitorsBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> monitorsBuf;
 
         private final List<LogData> targetLogData;
 
@@ -420,7 +433,7 @@
         }
 
         private void addDiffData(DiffData data) {
-            String time = data.getDateTime().format(HeapStatsUtils.getDateTimeFormatter());
+            long time = data.getDateTime().atZone(ZoneId.systemDefault()).toEpochSecond();
 
             javaUserUsageBuf.add(new XYChart.Data<>(time, data.getJavaUserUsage()));
             javaSysUsageBuf.add(new XYChart.Data<>(time, data.getJavaSysUsage()));
@@ -441,7 +454,7 @@
         }
 
         private void addLogData(LogData data) {
-            String time = data.getDateTime().format(HeapStatsUtils.getDateTimeFormatter());
+            long time = data.getDateTime().atZone(ZoneId.systemDefault()).toEpochSecond();
 
             javaVSZUsageBuf.add(new XYChart.Data<>(time, data.getJavaVSSize() / 1024 / 1024));
             javaRSSUsageBuf.add(new XYChart.Data<>(time, data.getJavaRSSize() / 1024 / 1024));
@@ -451,6 +464,22 @@
         }
 
         private void setChartData() {
+            /* Set chart range */
+            long startLogEpoch = targetLogData.get(0).getDateTime().atZone(ZoneId.systemDefault()).toEpochSecond();
+            long endLogEpoch = targetLogData.get(targetLogData.size() - 1).getDateTime().atZone(ZoneId.systemDefault()).toEpochSecond();
+            long startDiffEpoch = targetDiffData.get(0).getDateTime().atZone(ZoneId.systemDefault()).toEpochSecond();
+            long endDiffEpoch = targetDiffData.get(targetDiffData.size() - 1).getDateTime().atZone(ZoneId.systemDefault()).toEpochSecond();
+            Stream.of(javaMemoryChart, threadChart)
+                  .map(c -> (NumberAxis)c.getXAxis())
+                  .peek(a -> a.setTickUnit((endLogEpoch - startLogEpoch) / HeapStatsUtils.getXTickUnit()))
+                  .peek(a -> a.setLowerBound(startLogEpoch))
+                  .forEach(a -> a.setUpperBound(endLogEpoch));
+            Stream.of(javaCPUChart, systemCPUChart, safepointChart, safepointTimeChart, monitorChart)
+                  .map(c -> (NumberAxis)c.getXAxis())
+                  .peek(a -> a.setTickUnit((endDiffEpoch - startDiffEpoch) / HeapStatsUtils.getXTickUnit()))
+                  .peek(a -> a.setLowerBound(startDiffEpoch))
+                  .forEach(a -> a.setUpperBound(endDiffEpoch));
+            
             /* Replace new chart data */
             javaUserUsage.setData(javaUserUsageBuf);
             javaSysUsage.setData(javaSysUsageBuf);
--- a/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/SnapShotController.java	Wed Nov 09 21:15:19 2016 +0900
+++ b/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/SnapShotController.java	Wed Nov 09 22:31:27 2016 +0900
@@ -20,6 +20,7 @@
 import java.io.File;
 import java.net.URL;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -48,7 +49,7 @@
 import javafx.fxml.Initializable;
 import javafx.scene.Node;
 import javafx.scene.chart.Axis;
-import javafx.scene.chart.CategoryAxis;
+import javafx.scene.chart.NumberAxis;
 import javafx.scene.chart.XYChart;
 import javafx.scene.control.Button;
 import javafx.scene.control.ComboBox;
@@ -375,7 +376,7 @@
         parseThread.start();
     }
 
-    private void drawRebootSuspectLine(XYChart<String, ? extends Number> target) {
+    private void drawRebootSuspectLine(XYChart<Number, ? extends Number> target) {
 
         if (target.getData().isEmpty() || target.getData().get(0).getData().isEmpty()) {
             return;
@@ -389,18 +390,18 @@
         ObservableList<Node> anchorChildren = anchor.getChildren();
         anchorChildren.clear();
 
-        CategoryAxis xAxis = (CategoryAxis) target.getXAxis();
+        NumberAxis xAxis = (NumberAxis)target.getXAxis();
         Axis yAxis = target.getYAxis();
         Label chartTitle = (Label) target.getChildrenUnmodifiable().stream()
                 .filter(n -> n.getStyleClass().contains("chart-title"))
                 .findFirst()
                 .get();
 
-        double startX = xAxis.getLayoutX() + xAxis.getStartMargin() - 1.0d;
+        double startX = xAxis.getLayoutX() + 4.0d;
         double yPos = yAxis.getLayoutY() + chartTitle.getLayoutY() + chartTitle.getHeight();
         List<Rectangle> rectList = summaryData.get().getRebootSuspectList()
                 .stream()
-                .map(d -> d.format(HeapStatsUtils.getDateTimeFormatter()))
+                .map(d -> d.atZone(ZoneId.systemDefault()).toEpochSecond())
                 .map(s -> new Rectangle(xAxis.getDisplayPosition(s) + startX, yPos, 4d, yAxis.getHeight()))
                 .peek(r -> ((Rectangle) r).setStyle("-fx-fill: yellow;"))
                 .collect(Collectors.toList());
--- a/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/HistogramController.java	Wed Nov 09 21:15:19 2016 +0900
+++ b/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/HistogramController.java	Wed Nov 09 22:31:27 2016 +0900
@@ -20,6 +20,7 @@
 import java.io.File;
 import java.net.URL;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -103,7 +104,7 @@
     private Button selectFilterApplyBtn;
 
     @FXML
-    private StackedAreaChart<String, Long> topNChart;
+    private StackedAreaChart<Number, Long> topNChart;
 
     @FXML
     private AnchorPane topNChartAnchor;
@@ -145,7 +146,7 @@
 
     private LongProperty currentObjectTag;
 
-    private Consumer<XYChart<String, ? extends Number>> drawRebootSuspectLine;
+    private Consumer<XYChart<Number, ? extends Number>> drawRebootSuspectLine;
 
     private Consumer<Task<Void>> taskExecutor;
 
@@ -224,8 +225,8 @@
      * chart series as value.
      * @param objData ObjectData which is you want to build.
      */
-    private void buildTopNChartData(SnapShotHeader header, Map<String, XYChart.Series<String, Long>> seriesMap, ObjectData objData) {
-        XYChart.Series<String, Long> series = seriesMap.get(objData.getName());
+    private void buildTopNChartData(SnapShotHeader header, Map<String, XYChart.Series<Number, Long>> seriesMap, ObjectData objData) {
+        XYChart.Series<Number, Long> series = seriesMap.get(objData.getName());
 
         if (series == null) {
             series = new XYChart.Series<>();
@@ -234,10 +235,10 @@
             seriesMap.put(objData.getName(), series);
         }
 
-        String time = header.getSnapShotDate().format(HeapStatsUtils.getDateTimeFormatter());
+        long time = header.getSnapShotDate().atZone(ZoneId.systemDefault()).toEpochSecond();
         long yValue = instanceGraph.get() ? objData.getCount()
                 : objData.getTotalSize() / 1024 / 1024;
-        XYChart.Data<String, Long> data = new XYChart.Data<>(time, yValue);
+        XYChart.Data<Number, Long> data = new XYChart.Data<>(time, yValue);
 
         series.getData().add(data);
         String unit = instanceGraph.get() ? "instances" : "MB";
@@ -245,7 +246,7 @@
         Tooltip.install(data.getNode(), new Tooltip(tip));
     }
 
-    private void setTopNChartColor(XYChart.Series<String, Long> series) {
+    private void setTopNChartColor(XYChart.Series<Number, Long> series) {
         String color = ChartColorManager.getNextColor(series.getName());
 
         series.getNode().lookup(".chart-series-area-line").setStyle(String.format("-fx-stroke: %s;", color));
@@ -263,7 +264,15 @@
      * @param seriesMap Chart series map which is contains class name as key,
      * chart series as value.
      */
-    private void onDiffTaskSucceeded(DiffCalculator diff, Map<String, XYChart.Series<String, Long>> seriesMap) {
+    private void onDiffTaskSucceeded(DiffCalculator diff, Map<String, XYChart.Series<Number, Long>> seriesMap) {
+        /* Set chart range */
+        long startEpoch = currentTarget.get().get(0).getSnapShotDate().atZone(ZoneId.systemDefault()).toEpochSecond();
+        long endEpoch = currentTarget.get().get(currentTarget.get().size() - 1).getSnapShotDate().atZone(ZoneId.systemDefault()).toEpochSecond();
+        NumberAxis xAxis = (NumberAxis)topNChart.getXAxis();
+        xAxis.setTickUnit((endEpoch - startEpoch) / HeapStatsUtils.getXTickUnit());
+        xAxis.setLowerBound(startEpoch);
+        xAxis.setUpperBound(endEpoch);
+        
         topNList.set(FXCollections.observableMap(diff.getTopNList()));
 
         currentTarget.get().stream()
@@ -443,7 +452,7 @@
     public Task<Void> getDrawTopNDataTask(List<SnapShotHeader> target, boolean includeOthers, Predicate<? super ObjectData> predicate) {
         topNChart.getData().clear();
         lastDiffTable.getItems().clear();
-        Map<String, XYChart.Series<String, Long>> seriesMap = new HashMap<>();
+        Map<String, XYChart.Series<Number, Long>> seriesMap = new HashMap<>();
 
         TaskAdapter<DiffCalculator> diff = new TaskAdapter<>(new DiffCalculator(target, HeapStatsUtils.getRankLevel(),
                 includeOthers, predicate, HeapStatsUtils.getReplaceClassName(), instanceGraph.get()));
@@ -457,7 +466,7 @@
      *
      * @param drawRebootSuspectLine Consumer for drawing reboot line.
      */
-    public void setDrawRebootSuspectLine(Consumer<XYChart<String, ? extends Number>> drawRebootSuspectLine) {
+    public void setDrawRebootSuspectLine(Consumer<XYChart<Number, ? extends Number>> drawRebootSuspectLine) {
         this.drawRebootSuspectLine = drawRebootSuspectLine;
     }
 
@@ -513,7 +522,7 @@
      *
      * @return TopN chart.
      */
-    public StackedAreaChart<String, Long> getTopNChart() {
+    public StackedAreaChart<Number, Long> getTopNChart() {
         return topNChart;
     }
 
--- a/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/SummaryController.java	Wed Nov 09 21:15:19 2016 +0900
+++ b/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/SummaryController.java	Wed Nov 09 22:31:27 2016 +0900
@@ -18,6 +18,7 @@
 package jp.co.ntt.oss.heapstats.plugin.builtin.snapshot.tabs;
 
 import java.net.URL;
+import java.time.ZoneId;
 import java.util.Locale;
 import java.util.ResourceBundle;
 import java.util.function.Consumer;
@@ -34,14 +35,17 @@
 import javafx.fxml.Initializable;
 import javafx.scene.chart.AreaChart;
 import javafx.scene.chart.LineChart;
+import javafx.scene.chart.NumberAxis;
 import javafx.scene.chart.StackedAreaChart;
 import javafx.scene.chart.XYChart;
 import javafx.scene.control.TableColumn;
 import javafx.scene.control.TableView;
 import javafx.scene.control.cell.PropertyValueFactory;
 import javafx.scene.layout.AnchorPane;
+import javafx.util.StringConverter;
 import jp.co.ntt.oss.heapstats.container.snapshot.SnapShotHeader;
 import jp.co.ntt.oss.heapstats.container.snapshot.SummaryData;
+import jp.co.ntt.oss.heapstats.utils.EpochTimeConverter;
 import jp.co.ntt.oss.heapstats.utils.HeapStatsUtils;
 
 /**
@@ -59,30 +63,30 @@
     private TableColumn<SummaryData.SummaryDataEntry, String> valueColumn;
 
     @FXML
-    private StackedAreaChart<String, Long> heapChart;
+    private StackedAreaChart<Number, Long> heapChart;
 
-    private XYChart.Series<String, Long> youngUsage;
+    private XYChart.Series<Number, Long> youngUsage;
 
-    private XYChart.Series<String, Long> oldUsage;
+    private XYChart.Series<Number, Long> oldUsage;
 
-    private XYChart.Series<String, Long> free;
+    private XYChart.Series<Number, Long> free;
 
     @FXML
-    private LineChart<String, Long> instanceChart;
+    private LineChart<Number, Long> instanceChart;
 
-    private XYChart.Series<String, Long> instances;
+    private XYChart.Series<Number, Long> instances;
 
     @FXML
-    private LineChart<String, Long> gcTimeChart;
+    private LineChart<Number, Long> gcTimeChart;
 
-    private XYChart.Series<String, Long> gcTime;
+    private XYChart.Series<Number, Long> gcTime;
 
     @FXML
-    private AreaChart<String, Long> metaspaceChart;
+    private AreaChart<Number, Long> metaspaceChart;
 
-    private XYChart.Series<String, Long> metaspaceUsage;
+    private XYChart.Series<Number, Long> metaspaceUsage;
 
-    private XYChart.Series<String, Long> metaspaceCapacity;
+    private XYChart.Series<Number, Long> metaspaceCapacity;
 
     private ObjectProperty<SummaryData> summaryData;
 
@@ -108,6 +112,11 @@
               .peek(c -> c.lookup(".chart").setStyle(bgcolor))
               .forEach(c -> c.getXAxis().setTickMarkVisible(HeapStatsUtils.getTickMarkerSwitch()));
 
+        StringConverter<Number> converter = new EpochTimeConverter();
+        Stream.of(heapChart, instanceChart, gcTimeChart, metaspaceChart)
+              .map(c -> (NumberAxis)c.getXAxis())
+              .forEach(a -> a.setTickLabelFormatter(converter));
+        
         initializeChartSeries();
     }
 
@@ -181,22 +190,22 @@
 
         private int processedIndex;
 
-        private final Consumer<XYChart<String, ? extends Number>> drawRebootSuspectLine;
+        private final Consumer<XYChart<Number, ? extends Number>> drawRebootSuspectLine;
 
         /* Java Heap Usage Chart */
-        private final ObservableList<XYChart.Data<String, Long>> youngUsageBuf;
-        private final ObservableList<XYChart.Data<String, Long>> oldUsageBuf;
-        private final ObservableList<XYChart.Data<String, Long>> freeBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> youngUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> oldUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> freeBuf;
 
         /* Instances */
-        private final ObservableList<XYChart.Data<String, Long>> instanceBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> instanceBuf;
 
         /* GC time Chart */
-        private final ObservableList<XYChart.Data<String, Long>> gcTimeBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> gcTimeBuf;
 
         /* Metaspace Chart */
-        private final ObservableList<XYChart.Data<String, Long>> metaspaceUsageBuf;
-        private final ObservableList<XYChart.Data<String, Long>> metaspaceCapacityBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> metaspaceUsageBuf;
+        private final ObservableList<XYChart.Data<Number, Long>> metaspaceCapacityBuf;
 
         /**
          * Constructor of CalculateGCSummaryTask.
@@ -204,7 +213,7 @@
          * @param drawRebootSuspectLine Consumer for drawing reboot line. This
          * consumer is called in Platform#runLater() at succeeded().
          */
-        public CalculateGCSummaryTask(Consumer<XYChart<String, ? extends Number>> drawRebootSuspectLine) {
+        public CalculateGCSummaryTask(Consumer<XYChart<Number, ? extends Number>> drawRebootSuspectLine) {
             this.drawRebootSuspectLine = drawRebootSuspectLine;
 
             youngUsageBuf = FXCollections.observableArrayList();
@@ -217,7 +226,7 @@
         }
 
         private void processSnapShotHeader(SnapShotHeader header) {
-            String time = header.getSnapShotDate().format(HeapStatsUtils.getDateTimeFormatter());
+            long time = header.getSnapShotDate().atZone(ZoneId.systemDefault()).toEpochSecond();
 
             youngUsageBuf.add(new XYChart.Data<>(time, header.getNewHeap() / 1024 / 1024));
             oldUsageBuf.add(new XYChart.Data<>(time, header.getOldHeap() / 1024 / 1024));
@@ -250,6 +259,14 @@
 
         @Override
         protected void succeeded() {
+            long startEpoch = currentTarget.get().get(0).getSnapShotDate().atZone(ZoneId.systemDefault()).toEpochSecond();
+            long endEpoch = currentTarget.get().get(currentTarget.get().size() - 1).getSnapShotDate().atZone(ZoneId.systemDefault()).toEpochSecond();
+            Stream.of(heapChart, instanceChart, gcTimeChart, metaspaceChart)
+                  .peek(c -> ((NumberAxis)c.getXAxis()).setTickUnit((endEpoch - startEpoch) / HeapStatsUtils.getXTickUnit()))
+                  .peek(c -> ((NumberAxis)c.getXAxis()).setLowerBound(startEpoch))
+                  .peek(c -> ((NumberAxis)c.getXAxis()).setUpperBound(endEpoch))
+                  .forEach(c -> Platform.runLater(() -> drawRebootSuspectLine.accept(c)));
+            
             /* Replace new chart data */
             youngUsage.setData(youngUsageBuf);
             oldUsage.setData(oldUsageBuf);
@@ -261,9 +278,6 @@
 
             metaspaceUsage.setData(metaspaceUsageBuf);
             metaspaceCapacity.setData(metaspaceCapacityBuf);
-
-            Stream.of(heapChart, instanceChart, gcTimeChart, metaspaceChart)
-                    .forEach(c -> Platform.runLater(() -> drawRebootSuspectLine.accept(c)));
         }
 
     }
@@ -301,7 +315,7 @@
      * @param drawRebootSuspectLine Consumer for drawing reboot line.
      * @return Task for calculating GC summary.
      */
-    public Task<Void> getCalculateGCSummaryTask(Consumer<XYChart<String, ? extends Number>> drawRebootSuspectLine) {
+    public Task<Void> getCalculateGCSummaryTask(Consumer<XYChart<Number, ? extends Number>> drawRebootSuspectLine) {
         return new CalculateGCSummaryTask(drawRebootSuspectLine);
     }
 
@@ -310,7 +324,7 @@
      *
      * @return Java heap chart.
      */
-    public StackedAreaChart<String, Long> getHeapChart() {
+    public StackedAreaChart<Number, Long> getHeapChart() {
         return heapChart;
     }
 
@@ -319,7 +333,7 @@
      *
      * @return Instance chart.
      */
-    public LineChart<String, Long> getInstanceChart() {
+    public LineChart<Number, Long> getInstanceChart() {
         return instanceChart;
     }
 
@@ -328,7 +342,7 @@
      *
      * @return GC time chart.
      */
-    public LineChart<String, Long> getGcTimeChart() {
+    public LineChart<Number, Long> getGcTimeChart() {
         return gcTimeChart;
     }
 
@@ -337,7 +351,7 @@
      *
      * @return Metaspace chart.
      */
-    public AreaChart<String, Long> getMetaspaceChart() {
+    public AreaChart<Number, Long> getMetaspaceChart() {
         return metaspaceChart;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/utils/EpochTimeConverter.java	Wed Nov 09 22:31:27 2016 +0900
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 Yasumasa Suenaga
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package jp.co.ntt.oss.heapstats.utils;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import javafx.util.StringConverter;
+
+/**
+ * String converter for epoch time.
+ * This class supports SECOND time unit ONLY.
+ * 
+ * @author Yasumasa Suenaga
+ */
+public class EpochTimeConverter extends StringConverter<Number>{
+
+    @Override
+    public String toString(Number object) {
+        return LocalDateTime.ofInstant(Instant.ofEpochSecond(object.longValue()), ZoneId.systemDefault()).format(HeapStatsUtils.getDateTimeFormatter());
+    }
+
+    @Override
+    public Number fromString(String string) {
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+    
+}
--- a/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/utils/HeapStatsUtils.java	Wed Nov 09 21:15:19 2016 +0900
+++ b/analyzer/fx/src/main/java/jp/co/ntt/oss/heapstats/utils/HeapStatsUtils.java	Wed Nov 09 22:31:27 2016 +0900
@@ -194,6 +194,18 @@
             prop.setProperty("tickmarker", "false");
         }
 
+        /* TickUnit of X axis */
+        String xTickUnitStr = prop.getProperty("x_tickunit");
+        if (xTickUnitStr == null) {
+            prop.setProperty("x_tickunit", "20");
+        } else {
+            try {
+                Double.parseDouble(xTickUnitStr);
+            } catch (NumberFormatException e) {
+                throw new HeapStatsConfigException(resource.getString("invalid.option") + " x_tickunit=" + xTickUnitStr, e);
+            }
+        }
+
         /* Add shutdown hook for saving current settings. */
         Runnable savePropImpl = () -> {
             try (OutputStream out = Files.newOutputStream(properties, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE)) {
@@ -354,6 +366,15 @@
     }
     
     /**
+     * Get TickUnit on X axis.
+     * 
+     * @return TickUnit of X axis.
+     */
+    public static double getXTickUnit(){
+        return Double.parseDouble(prop.getProperty("x_tickunit"));
+    }
+    
+    /**
      * Convert stack trace to String.
      *
      * @param e Throwable object to convert.
--- a/analyzer/fx/src/main/resources/jp/co/ntt/oss/heapstats/plugin/builtin/log/tabs/resources.fxml	Wed Nov 09 21:15:19 2016 +0900
+++ b/analyzer/fx/src/main/resources/jp/co/ntt/oss/heapstats/plugin/builtin/log/tabs/resources.fxml	Wed Nov 09 22:31:27 2016 +0900
@@ -41,7 +41,7 @@
                     <children>
                         <LineChart id="threadChart" fx:id="threadChart" animated="false" createSymbols="false" legendVisible="false" minHeight="0.0" minWidth="0.0" onMouseExited="#onChartMouseExited" onMouseMoved="#onChartMouseMoved" title="%chart.thread">
                             <xAxis>
-                                <CategoryAxis side="BOTTOM" tickLabelsVisible="false" />
+                                <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" autoRanging="false" />
                             </xAxis>
                             <yAxis>
                                 <NumberAxis side="LEFT" minorTickVisible="false" />
@@ -63,7 +63,7 @@
                     <children>
                         <StackedAreaChart id="javaCPUChart" fx:id="javaCPUChart" animated="false" createSymbols="false" legendSide="BOTTOM" legendVisible="true" minHeight="0.0" minWidth="0.0" onMouseExited="#onChartMouseExited" onMouseMoved="#onChartMouseMoved" title="%chart.javacpu">
                             <xAxis>
-                                <CategoryAxis side="BOTTOM" tickLabelsVisible="false" />
+                                <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" autoRanging="false" />
                             </xAxis>
                             <yAxis>
                                 <NumberAxis autoRanging="false" label="\%" lowerBound="0.0" side="LEFT" upperBound="100.0d" tickUnit="10.0" minorTickVisible="false" />
@@ -76,7 +76,7 @@
                     <children>
                         <StackedAreaChart id="systemCPUChart" fx:id="systemCPUChart" animated="false" createSymbols="false" legendSide="BOTTOM" legendVisible="true" minHeight="0.0" minWidth="0.0" onMouseExited="#onChartMouseExited" onMouseMoved="#onChartMouseMoved" title="%chart.systemcpu">
                             <xAxis>
-                                <CategoryAxis side="BOTTOM" tickLabelsVisible="false" />
+                                <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" autoRanging="false" />
                             </xAxis>
                             <yAxis>
                                 <NumberAxis autoRanging="false" label="\%" lowerBound="0.0" side="LEFT" upperBound="100.0d" tickUnit="10.0" minorTickVisible="false" />
@@ -89,7 +89,7 @@
                     <children>
                         <LineChart id="javaMemoryChart" fx:id="javaMemoryChart" animated="false" createSymbols="false" legendSide="BOTTOM" legendVisible="true" minHeight="0.0" minWidth="0.0" onMouseExited="#onChartMouseExited" onMouseMoved="#onChartMouseMoved" title="%chart.nativememory">
                             <xAxis>
-                                <CategoryAxis side="BOTTOM" tickLabelsVisible="false" />
+                                <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" autoRanging="false" />
                             </xAxis>
                             <yAxis>
                                 <NumberAxis label="MB" side="LEFT" minorTickVisible="false" />
@@ -102,7 +102,7 @@
                     <children>
                         <LineChart id="safepointChart" fx:id="safepointChart" animated="false" createSymbols="false" legendVisible="false" minHeight="0.0" minWidth="0.0" onMouseExited="#onChartMouseExited" onMouseMoved="#onChartMouseMoved" title="%chart.safepoint.count">
                             <xAxis>
-                                <CategoryAxis side="BOTTOM" tickLabelsVisible="false" visible="false" />
+                                <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" visible="false" autoRanging="false" />
                             </xAxis>
                             <yAxis>
                                 <NumberAxis side="LEFT" minorTickVisible="false" />
@@ -115,7 +115,7 @@
                     <children>
                         <LineChart id="safepointTimeChart" fx:id="safepointTimeChart" animated="false" createSymbols="false" legendVisible="false" minHeight="0.0" minWidth="0.0" onMouseExited="#onChartMouseExited" onMouseMoved="#onChartMouseMoved" title="%chart.safepoint.time">
                             <xAxis>
-                                <CategoryAxis side="BOTTOM" tickLabelsVisible="false" visible="false" />
+                                <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" visible="false" autoRanging="false" />
                             </xAxis>
                             <yAxis>
                                 <NumberAxis label="ms" side="LEFT" minorTickVisible="false" />
@@ -128,7 +128,7 @@
                     <children>
                         <LineChart id="monitorChart" fx:id="monitorChart" animated="false" createSymbols="false" legendVisible="false" minHeight="0.0" minWidth="0.0" onMouseExited="#onChartMouseExited" onMouseMoved="#onChartMouseMoved" title="%chart.monitorcontention">
                             <xAxis>
-                                <CategoryAxis side="BOTTOM" tickLabelsVisible="false" />
+                                <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" autoRanging="false" />
                             </xAxis>
                             <yAxis>
                                 <NumberAxis side="LEFT" minorTickVisible="false" />
--- a/analyzer/fx/src/main/resources/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/histogram.fxml	Wed Nov 09 21:15:19 2016 +0900
+++ b/analyzer/fx/src/main/resources/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/histogram.fxml	Wed Nov 09 22:31:27 2016 +0900
@@ -66,7 +66,7 @@
                             <children>
                                 <StackedAreaChart fx:id="topNChart" animated="false" legendVisible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                                     <xAxis>
-                                        <CategoryAxis side="BOTTOM" tickLabelsVisible="false" />
+                                        <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" autoRanging="false" />
                                     </xAxis>
                                     <yAxis>
                                         <NumberAxis fx:id="topNYAxis" autoRanging="false" label="MB" side="LEFT" minorTickVisible="false" />
--- a/analyzer/fx/src/main/resources/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/summary.fxml	Wed Nov 09 21:15:19 2016 +0900
+++ b/analyzer/fx/src/main/resources/jp/co/ntt/oss/heapstats/plugin/builtin/snapshot/tabs/summary.fxml	Wed Nov 09 22:31:27 2016 +0900
@@ -46,7 +46,7 @@
                             <children>
                                 <StackedAreaChart id="heapChart" fx:id="heapChart" animated="false" createSymbols="false" layoutX="-129.0" layoutY="-91.0" minHeight="0.0" title="%chart.javaheap" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                                     <xAxis>
-                                        <CategoryAxis side="BOTTOM" tickLabelsVisible="false" />
+                                        <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" autoRanging="false" />
                                     </xAxis>
                                     <yAxis>
                                         <NumberAxis label="MB" side="LEFT" minorTickVisible="false" />
@@ -59,7 +59,7 @@
                             <children>
                                 <LineChart id="instanceChart" fx:id="instanceChart" animated="false" createSymbols="false" layoutX="-149.0" layoutY="-120.0" legendVisible="false" minHeight="0.0" title="%chart.instances" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                                     <xAxis>
-                                        <CategoryAxis side="BOTTOM" tickLabelsVisible="false" visible="false" />
+                                        <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" visible="false" autoRanging="false" />
                                     </xAxis>
                                     <yAxis>
                                         <NumberAxis label="instances" side="LEFT" minorTickVisible="false" />
@@ -72,7 +72,7 @@
                             <children>
                                 <LineChart id="gcTimeChart" fx:id="gcTimeChart" animated="false" createSymbols="false" layoutX="-169.0" layoutY="-120.0" legendVisible="false" minHeight="0.0" title="%chart.gctime" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                                     <xAxis>
-                                        <CategoryAxis side="BOTTOM" tickLabelsVisible="false" />
+                                        <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" autoRanging="false" />
                                     </xAxis>
                                     <yAxis>
                                         <NumberAxis label="ms" side="LEFT" minorTickVisible="false" />
@@ -85,7 +85,7 @@
                             <children>
                                 <AreaChart id="metaspaceChart" fx:id="metaspaceChart" animated="false" createSymbols="false" layoutX="-174.0" layoutY="-166.0" minHeight="0.0" title="%chart.metaspace" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                                     <xAxis>
-                                        <CategoryAxis side="BOTTOM" tickLabelsVisible="false" />
+                                        <NumberAxis side="BOTTOM" tickLabelsVisible="false" minorTickVisible="false" autoRanging="false" />
                                     </xAxis>
                                     <yAxis>
                                         <NumberAxis label="MB" side="LEFT" minorTickVisible="false" />