chukwa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ey...@apache.org
Subject [1/2] chukwa git commit: CHUKWA-785. Added banner, pie chart, gauge chart to graph explorer. (Eric Yang)
Date Mon, 23 Nov 2015 01:21:35 GMT
Repository: chukwa
Updated Branches:
  refs/heads/master a13bc5ae0 -> 0e518f8d7


CHUKWA-785. Added banner, pie chart, gauge chart to graph explorer.  (Eric Yang)


Project: http://git-wip-us.apache.org/repos/asf/chukwa/repo
Commit: http://git-wip-us.apache.org/repos/asf/chukwa/commit/5e66273f
Tree: http://git-wip-us.apache.org/repos/asf/chukwa/tree/5e66273f
Diff: http://git-wip-us.apache.org/repos/asf/chukwa/diff/5e66273f

Branch: refs/heads/master
Commit: 5e66273f6f5960f01eae97d8b719f50e1e394fd1
Parents: a13bc5a
Author: Eric Yang <eyang@apache.org>
Authored: Sun Oct 25 19:05:22 2015 -0700
Committer: Eric Yang <eyang@apache.org>
Committed: Sun Nov 22 17:16:32 2015 -0800

----------------------------------------------------------------------
 CHANGES.txt                                     |   2 +
 .../chukwa/datastore/ChukwaHBaseStore.java      |  56 +++++-
 .../apache/hadoop/chukwa/hicc/bean/Chart.java   |  37 ++++
 .../hadoop/chukwa/hicc/bean/ChartType.java      |  22 +++
 .../chukwa/hicc/rest/CirclesController.java     |  54 ++++--
 .../chukwa/hicc/rest/PieChartController.java    | 131 +++++++++++++
 .../hadoop/chukwa/hicc/rest/TileController.java | 128 +++++++++++++
 src/main/web/hicc/WEB-INF/vm/circles.vm         |  15 +-
 src/main/web/hicc/WEB-INF/vm/pie.vm             |  64 +++++++
 src/main/web/hicc/WEB-INF/vm/tile.vm            | 133 +++++++++++++
 .../hicc/home/css/bootstrap-iconpicker.min.css  |   9 +
 src/main/web/hicc/home/css/jquery.gridster.css  |  12 +-
 src/main/web/hicc/home/graph-explorer.html      | 186 ++++++++++++++++---
 .../hicc/home/js/bootstrap-iconpicker.min.js    |  19 ++
 .../home/js/iconset/iconset-glyphicon.min.js    |  21 +++
 src/main/web/hicc/home/tile.html                |  54 +++++-
 src/main/web/hicc/images/loading.svg            |  18 ++
 src/main/web/hicc/js/pie.js                     |  79 ++++++++
 src/main/web/hicc/loading.html                  |  49 +++++
 19 files changed, 1026 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 03b0fe8..718d869 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,8 @@ Trunk (unreleased changes)
 
   NEW FEATURES
 
+    CHUKWA-785. Added banner, pie chart, gauge chart to graph explorer.  (Eric Yang)
+
     CHUKWA-778. Added pie chart, circle chart and timeline javascripts.  (Eric Yang)
 
     CHUKWA-777. Added Home page and some widgets for the demo purpose. (Eric Yang)

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java b/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
index 4c6ccdb..fec9281 100644
--- a/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
+++ b/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
@@ -638,6 +638,43 @@ public class ChukwaHBaseStore {
     return list;
   }
 
+  public static synchronized List<String> getData(ArrayList<SeriesMetaData> series, long startTime, long endTime) {
+    ArrayList<String> data = new ArrayList<String>();
+    try {
+      getHBaseConnection();
+      Table table = connection.getTable(TableName.valueOf(CHUKWA));
+      Scan scan = new Scan();
+      for(SeriesMetaData s : series) {
+        String snapshot = "";
+        String[] parts = s.getUrl().toString().split("/");
+        String metric = parts[5];
+        String source = parts[6];
+        long currentDay = startTime;
+        byte[] rowKey = HBaseUtil.buildKey(currentDay, metric, source);
+        scan.addFamily(COLUMN_FAMILY);
+        scan.setStartRow(rowKey);
+        scan.setStopRow(rowKey);
+        scan.setTimeRange(startTime, endTime);
+        scan.setBatch(10000);
+        ResultScanner rs = table.getScanner(scan);
+        Iterator<Result> it = rs.iterator();
+        while(it.hasNext()) {
+          Result result = it.next();
+          for(Cell kv : result.rawCells()) {
+            snapshot = new String(CellUtil.cloneValue(kv));
+          }
+        }
+        data.add(snapshot);
+        rs.close();
+      }
+      table.close();
+    } catch(Exception e) {
+      closeHBase();
+      LOG.error(ExceptionUtil.getStackTrace(e));
+    }
+    return data;
+  }
+
   /**
    * Find widget by title prefix in HBase.
    * 
@@ -861,6 +898,16 @@ public class ChukwaHBaseStore {
       Dashboard dashboard = new Dashboard();
 
       widget = new Widget();
+      widget.setTitle("Welcome Page");
+      widget.setSrc(new URI("/hicc/welcome.html"));
+      widget.setCol(1);
+      widget.setRow(1);
+      widget.setSize_x(9);
+      widget.setSize_y(5);
+      createWidget(widget);
+      dashboard.add(widget);
+
+      widget = new Widget();
       widget.setTitle("Trial Downloading");
       widget.setSrc(new URI("/hicc/home/downloads.html"));
       widget.setCol(1);
@@ -868,7 +915,6 @@ public class ChukwaHBaseStore {
       widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
-      dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Cluster Running");
@@ -878,7 +924,6 @@ public class ChukwaHBaseStore {
       widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
-      dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Users Working");
@@ -888,7 +933,6 @@ public class ChukwaHBaseStore {
       widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
-      dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Applications Running");
@@ -898,7 +942,6 @@ public class ChukwaHBaseStore {
       widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
-      dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Trial Abandon Rate");
@@ -908,7 +951,6 @@ public class ChukwaHBaseStore {
       widget.setSize_x(2);
       widget.setSize_y(2);
       createWidget(widget);
-      dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Clusters Health");
@@ -918,7 +960,6 @@ public class ChukwaHBaseStore {
       widget.setSize_x(2);
       widget.setSize_y(2);
       createWidget(widget);
-      dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Top Active Clusters");
@@ -928,7 +969,6 @@ public class ChukwaHBaseStore {
       widget.setSize_x(2);
       widget.setSize_y(2);
       createWidget(widget);
-      dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Top Applications");
@@ -938,7 +978,6 @@ public class ChukwaHBaseStore {
       widget.setSize_x(2);
       widget.setSize_y(2);
       createWidget(widget);
-//      dashboard.add(widget);
 
       widget = new Widget();
       widget.setTitle("Applications Usage");
@@ -948,7 +987,6 @@ public class ChukwaHBaseStore {
       widget.setSize_x(2);
       widget.setSize_y(2);
       createWidget(widget);
-      dashboard.add(widget);
 
       updateDashboard("default", "", dashboard);
 

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Chart.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Chart.java b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Chart.java
index 19cde5f..06b2bd5 100644
--- a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Chart.java
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Chart.java
@@ -24,6 +24,7 @@ import java.util.List;
 
 public class Chart {
   private String id;
+  private ChartType type;
   private String title;
   private List<SeriesMetaData> series;
   private boolean xLabelOn;
@@ -42,9 +43,13 @@ public class Chart {
   private boolean userDefinedMax = true;
   private boolean userDefinedMin = true;
   private String yUnitType = "";
+  private String icon = "";
+  private String bannerText = "";
+  private String suffixText = "";
 
   public Chart(String id) {
     this.id = id;
+    this.type = ChartType.TIME_SERIES;
     this.title = "Untitled Chart";
     this.xLabelOn = true;
     this.yLabelOn = true;
@@ -56,6 +61,14 @@ public class Chart {
     this.userDefinedMin = false;
   }
 
+  public ChartType getType() {
+    return this.type;
+  }
+  
+  public void setType(ChartType type) {
+    this.type = type;
+  }
+
   public void setYMax(double max) {
     this.max = max;
     this.userDefinedMax = true;
@@ -196,4 +209,28 @@ public class Chart {
   public String getYUnitType() {
     return this.yUnitType;
   }
+
+  public void setIcon(String icon) {
+    this.icon = icon;
+  }
+
+  public String getIcon() {
+    return this.icon;
+  }
+
+  public void setBannerText(String bannerText) {
+    this.bannerText = bannerText;
+  }
+
+  public String getBannerText() {
+    return this.bannerText;
+  }
+
+  public void setSuffixText(String suffixText) {
+    this.suffixText = suffixText;
+  }
+
+  public String getSuffixText() {
+    return this.suffixText;
+  }
 }

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/java/org/apache/hadoop/chukwa/hicc/bean/ChartType.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/ChartType.java b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/ChartType.java
new file mode 100644
index 0000000..26d87ea
--- /dev/null
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/ChartType.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.hadoop.chukwa.hicc.bean;
+
+public enum ChartType {
+  TIME_SERIES, PIE, CIRCLE, TILE, BAR, DONUT;
+}

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/java/org/apache/hadoop/chukwa/hicc/rest/CirclesController.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/CirclesController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/CirclesController.java
index 62b4b71..5127b1c 100644
--- a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/CirclesController.java
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/CirclesController.java
@@ -90,6 +90,28 @@ public class CirclesController {
   }
 
   @PUT
+  @Path("preview")
+  public String preview(String buffer) {
+    VelocityContext context = new VelocityContext();
+    StringWriter sw = null;
+    try {
+      Gson gson = new Gson();
+      Chart chart = gson.fromJson(buffer, Chart.class);
+      List<SeriesMetaData> series = chart.getSeries();
+      String seriesMetaData = gson.toJson(series);
+      context.put("chart", chart);
+      context.put("seriesMetaData", seriesMetaData);
+      Template template = velocity.getTemplate("circles.vm");
+      sw = new StringWriter();
+      template.merge(context, sw);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return e.getMessage();
+    }
+    return sw.toString();
+  }
+  
+  @PUT
   @Path("preview/series")
   @Produces("application/json")
   public String previewSeries(@Context HttpServletRequest request, String buffer) {
@@ -98,31 +120,33 @@ public class CirclesController {
     long startTime = 0;
     long endTime = 0;
     TimeHandler time = new TimeHandler(request);
-    startTime = time.getEndTime() - TimeUnit.SECONDS.toMillis(300);
+    startTime = time.getStartTime();
     endTime = time.getEndTime();
     Gson gson = new Gson();
     ArrayList<SeriesMetaData> series = gson.fromJson(buffer, listType);
     double percent;
-    long timestamp;
-    series = ChukwaHBaseStore.getChartSeries(series, startTime, endTime);
+    List<String> data = ChukwaHBaseStore.getData(series, startTime, endTime);
     if(series.size()>=2) {
-      ArrayList<ArrayList<Number>> a = series.get(0).getData();
-      ArrayList<Number> b = a.get(a.size()-1);
-      timestamp = b.get(0).longValue();
-      double x = b.get(b.size()-1).doubleValue();
-      a = series.get(1).getData();
-      b = a.get(a.size()-1);
-      double y = b.get(b.size()-1).doubleValue();
+      double x = 0;
+      double y = 1;
+      try {
+        x = Double.parseDouble(data.get(0));
+      } catch(NumberFormatException e) {
+        x = 0;
+      }
+      try {
+        y = Double.parseDouble(data.get(1));
+      } catch(NumberFormatException e) {
+        y = 1;
+      }
       percent = x / y * 100d;
     } else {
-      ArrayList<ArrayList<Number>> a = series.get(0).getData();
-      ArrayList<Number> b = a.get(a.size()-1);
-      timestamp = b.get(0).longValue();
-      percent = b.get(b.size()-1).doubleValue();
+      double x = Double.parseDouble(data.get(0));
+      percent = x;
     }
     percent = Math.round(percent * 100d) / 100d;
     Series answer = new Series("circle");
-    answer.add(timestamp, percent);
+    answer.add(endTime, percent);
     String result = gson.toJson(answer);
     return result;
   }

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/java/org/apache/hadoop/chukwa/hicc/rest/PieChartController.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/PieChartController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/PieChartController.java
new file mode 100644
index 0000000..8f33af8
--- /dev/null
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/PieChartController.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.hadoop.chukwa.hicc.rest;
+
+import java.io.StringWriter;
+import java.lang.reflect.Type;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.hadoop.chukwa.datastore.ChukwaHBaseStore;
+import org.apache.hadoop.chukwa.hicc.TimeHandler;
+import org.apache.hadoop.chukwa.hicc.bean.Chart;
+import org.apache.hadoop.chukwa.hicc.bean.ChartType;
+import org.apache.hadoop.chukwa.hicc.bean.SeriesMetaData;
+import org.apache.log4j.Logger;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+@Path("/piechart")
+public class PieChartController extends ChartController{
+  static Logger LOG = Logger.getLogger(ChartController.class);
+  SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+
+  @Context
+  VelocityEngine velocity;
+
+  /**
+   * Render pie chart using chartist.js
+   * 
+   * @param id Reference ID of Chart stored in HBase chukwa_meta table.
+   * @return html chart widget
+   */
+  @GET
+  @Path("draw/{id}")
+  @Produces(MediaType.TEXT_HTML)
+  public String draw(@PathParam("id") String id) {
+    VelocityContext context = new VelocityContext();
+    StringWriter sw = null;
+    try {
+      Chart chart = ChukwaHBaseStore.getChart(id);
+      List<SeriesMetaData> series = chart.getSeries();
+      Gson gson = new Gson();
+      String seriesMetaData = gson.toJson(series);
+
+      context.put("chart", chart);
+      context.put("seriesMetaData", seriesMetaData);
+      context.put("chartTypeDonut", ChartType.DONUT);
+      Template template = velocity.getTemplate("pie.vm");
+      sw = new StringWriter();
+      template.merge(context, sw);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return e.getMessage();
+    }
+    return sw.toString();
+  }
+
+  /**
+   * Preview a pie chart
+   */
+  @PUT
+  @Path("preview")
+  public String preview(String buffer) {
+    VelocityContext context = new VelocityContext();
+    StringWriter sw = null;
+    try {
+      Gson gson = new Gson();
+      Chart chart = gson.fromJson(buffer, Chart.class);
+      List<SeriesMetaData> series = chart.getSeries();
+      String seriesMetaData = gson.toJson(series);
+
+      context.put("chart", chart);
+      context.put("seriesMetaData", seriesMetaData);
+      context.put("chartTypeDonut", ChartType.DONUT);
+      Template template = velocity.getTemplate("pie.vm");
+      sw = new StringWriter();
+      template.merge(context, sw);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return e.getMessage();
+    }
+    return sw.toString();
+  }
+
+  @PUT
+  @Path("preview/series")
+  @Produces("application/json")
+  public String previewSeries(@Context HttpServletRequest request, String buffer) {
+    Type listType = new TypeToken<ArrayList<SeriesMetaData>>() {
+    }.getType();
+    long startTime = 0;
+    long endTime = 0;
+    TimeHandler time = new TimeHandler(request);
+    startTime = time.getStartTime();
+    endTime = time.getEndTime();
+    Gson gson = new Gson();
+    ArrayList<SeriesMetaData> series = gson.fromJson(buffer, listType);
+    List<String> data = ChukwaHBaseStore.getData(series, startTime, endTime);
+    String result = gson.toJson(data);
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/java/org/apache/hadoop/chukwa/hicc/rest/TileController.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/TileController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/TileController.java
new file mode 100644
index 0000000..8e259a9
--- /dev/null
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/TileController.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.hadoop.chukwa.hicc.rest;
+
+import java.io.StringWriter;
+import java.lang.reflect.Type;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.hadoop.chukwa.datastore.ChukwaHBaseStore;
+import org.apache.hadoop.chukwa.hicc.TimeHandler;
+import org.apache.hadoop.chukwa.hicc.bean.Chart;
+import org.apache.hadoop.chukwa.hicc.bean.SeriesMetaData;
+import org.apache.log4j.Logger;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+@Path("/tile")
+public class TileController extends ChartController{
+  static Logger LOG = Logger.getLogger(ChartController.class);
+  SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+
+  @Context
+  VelocityEngine velocity;
+
+  /**
+   * Render a banner
+   * 
+   * @param id Reference ID of Chart stored in HBase chukwa_meta table.
+   * @return html chart widget
+   */
+  @GET
+  @Path("draw/{id}")
+  @Produces(MediaType.TEXT_HTML)
+  public String draw(@PathParam("id") String id) {
+    VelocityContext context = new VelocityContext();
+    StringWriter sw = null;
+    try {
+      Chart chart = ChukwaHBaseStore.getChart(id);
+      List<SeriesMetaData> series = chart.getSeries();
+      Gson gson = new Gson();
+      String seriesMetaData = gson.toJson(series);
+
+      context.put("chart", chart);
+      context.put("seriesMetaData", seriesMetaData);
+      Template template = velocity.getTemplate("tile.vm");
+      sw = new StringWriter();
+      template.merge(context, sw);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return e.getMessage();
+    }
+    return sw.toString();
+  }
+
+  /**
+   * Preview a banner tile
+   */
+  @PUT
+  @Path("preview")
+  public String preview(String buffer) {
+    VelocityContext context = new VelocityContext();
+    StringWriter sw = null;
+    try {
+      Gson gson = new Gson();
+      Chart chart = gson.fromJson(buffer, Chart.class);
+      List<SeriesMetaData> series = chart.getSeries();
+      String seriesMetaData = gson.toJson(series);
+
+      context.put("chart", chart);
+      context.put("seriesMetaData", seriesMetaData);
+      Template template = velocity.getTemplate("tile.vm");
+      sw = new StringWriter();
+      template.merge(context, sw);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return e.getMessage();
+    }
+    return sw.toString();
+  }
+
+  @PUT
+  @Path("preview/series")
+  @Produces("application/json")
+  public String previewSeries(@Context HttpServletRequest request, String buffer) {
+    Type listType = new TypeToken<ArrayList<SeriesMetaData>>() {
+    }.getType();
+    long startTime = 0;
+    long endTime = 0;
+    TimeHandler time = new TimeHandler(request);
+    startTime = time.getStartTime();
+    endTime = time.getEndTime();
+    Gson gson = new Gson();
+    ArrayList<SeriesMetaData> series = gson.fromJson(buffer, listType);
+    List<String> data = ChukwaHBaseStore.getData(series, startTime, endTime);
+    String result = gson.toJson(data);
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/WEB-INF/vm/circles.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/circles.vm b/src/main/web/hicc/WEB-INF/vm/circles.vm
index 76acfda..76d9b41 100644
--- a/src/main/web/hicc/WEB-INF/vm/circles.vm
+++ b/src/main/web/hicc/WEB-INF/vm/circles.vm
@@ -15,16 +15,14 @@
   See the License for the specific language governing permissions and
   limitations under the License.
  *#
-<html>
+<!DOCTYPE html>
+<html lang="en" class="no-js">
 <head>
 <title>Circliful</title>
 
 <link href="/hicc/css/jquery.circliful.css" rel="stylesheet" type="text/css" />
 <link href="/hicc/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
 
-<script src="/hicc/js/jquery.js"></script>
-<script src="/hicc/js/jquery.circliful.min.js"></script>
-
 <style>
 body {
     font-family: arial,verdana, sans-serif;
@@ -57,6 +55,9 @@ body {
 </div>
 </div>
 
+<script src="/hicc/js/jquery.js" type="text/javascript"></script>
+<script src="/hicc/js/jquery.circliful.min.js" type="text/javascript"></script>
+
 <script>
 var tracker;
 
@@ -78,6 +79,7 @@ function load() {
         render(result);
       }
     });
+    tracker = setTimeout(load, 3000);
 }
 
 function render(result) {
@@ -85,7 +87,7 @@ function render(result) {
     var width = 30;
     var fontsize = 38;
     var percent = result.series.data[0][1];
-    var text = percent+"%";
+    var text = percent+"$chart.getSuffixText()";
     var color = "#70cac8";
     if(percent > 75) {
       color = "#fc6e64";
@@ -103,11 +105,10 @@ function render(result) {
     attr('data-fgcolor', color).
     attr('data-text', text).circliful();
     document.body.style.overflow = 'hidden';
-    tracker = setTimeout(load, 3000);
 }
 
 $( document ).ready(function() {
-  load();
+    load();
 });
 </script>
 </body>

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/WEB-INF/vm/pie.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/pie.vm b/src/main/web/hicc/WEB-INF/vm/pie.vm
new file mode 100644
index 0000000..5bb74d2
--- /dev/null
+++ b/src/main/web/hicc/WEB-INF/vm/pie.vm
@@ -0,0 +1,64 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+ -->
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <title>$chart.getTitle()</title>
+    <link href="/hicc/css/bootstrap-theme.min.css" type="text/css" rel="stylesheet" />
+    <link href="/hicc/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
+    <link href="/hicc/css/chartist.css" type="text/css" rel="stylesheet" />
+    <script src="/hicc/js/jquery.js"></script>
+    <script src="/hicc/js/bootstrap.min.js" type="text/javascript"></script>
+    <script src="/hicc/js/chartist.min.js" type="text/javascript"></script>
+<style>
+.outer {
+    display: table;
+    position: absolute;
+    height: 100%;
+    width: 100%;
+}
+
+.middle {
+    display: table-cell;
+    vertical-align: middle;
+}
+
+.inner {
+    margin-left: auto;
+    margin-right: auto;
+}
+
+</style>
+  </head>
+  <body>
+    <div class="outer">
+      <div class="middle">
+        <div class="ct-chart ct-perfect-fourth inner"></div>
+      </div>
+    </div>
+    <script>
+      var _series=$seriesMetaData;
+      #if ( $chart.getType() == $chartTypeDonut )
+        var donut=true;
+      #else
+        var donut=false;
+      #end
+    </script>
+    <script src="/hicc/js/pie.js"></script>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/WEB-INF/vm/tile.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/tile.vm b/src/main/web/hicc/WEB-INF/vm/tile.vm
new file mode 100644
index 0000000..edb157d
--- /dev/null
+++ b/src/main/web/hicc/WEB-INF/vm/tile.vm
@@ -0,0 +1,133 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+--> 
+<!DOCTYPE html>
+<html lang="en" class="no-js">
+  <head>
+    <title>$chart.getTitle()</title>
+    <link href="/hicc/css/bootstrap-theme.min.css" type="text/css" rel="stylesheet" />
+    <link href="/hicc/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
+    <script src="/hicc/js/jquery.js" type="text/javascript"></script>
+    <script src="/hicc/js/bootstrap.min.js" type="text/javascript"></script>
+    <style>
+      .tile {
+        color: #ffffff;
+        background-color: #5bc0de;
+      }
+      .container {
+        width: 100%;
+      }
+      .row {
+        display: -webkit-box;
+        display: -webkit-flex;
+        display: -ms-flexbox;
+        display:         flex;
+      }
+
+      .jumbotron.vertical-center {
+        margin-bottom: 0; /* Remove the default bottom margin of .jumbotron */
+      }
+
+      .vertical-center {
+        min-height: 100%;  /* Fallback for vh unit */
+        min-height: 100vh; /* You might also want to use
+                              'height' property instead.
+
+                               Note that for percentage values of
+                              'height' or 'min-height' properties,
+                               the 'height' of the parent element
+                               should be specified explicitly.
+ 
+                               In this case the parent of '.vertical-center'
+                               is the <body> element */
+
+        /* Make it a flex container */
+        display: -webkit-box;
+        display: -moz-box;
+        display: -ms-flexbox;
+        display: -webkit-flex;
+        display: flex;
+ 
+        /* Align the bootstrap's container vertically */
+          -webkit-box-align : center;
+        -webkit-align-items : center;
+             -moz-box-align : center;
+             -ms-flex-align : center;
+                align-items : center;
+
+        /* In legacy web browsers such as Firefox 9
+           we need to specify the width of the flex container */
+        width: 100%;
+
+        /* Also 'margin: 0 auto' doesn't have any effect on flex items in such web browsers
+           hence the bootstrap's container won't be aligned to the center anymore.
+
+           Therefore, we should use the following declarations to get it centered again */
+               -webkit-box-pack : center;
+                  -moz-box-pack : center;
+                  -ms-flex-pack : center;
+        -webkit-justify-content : center;
+                justify-content : center;
+      }
+
+    </style>
+  </head>
+  <body onResize="resize()">
+    <div class="vertical-center">
+    <div class="container">
+      <div class="row">
+        <div class="col-xs-5 col-md-5 text-center tile">
+            <h2><span class="glyphicon $chart.getIcon()" aria-hidden="true"></span></h2>
+            $chart.getBannerText()
+        </div>
+        <div class="col-xs-7 col-md-7 text-center">
+          <p><h1 id="value"></h1> $chart.getSuffixText()</p>
+        </div>
+      </div>
+    </div>
+    </div>
+
+    <script src="/hicc/js/jquery.js"></script>
+    <script>
+      var tracker;
+
+      function resize() {
+        clearTimeout(tracker);
+        tracker = setTimeout(render, 50);
+      }
+
+      function render() {
+        var _series=$seriesMetaData;
+        var buffer=JSON.stringify(_series);
+        $.ajax({
+          type: "PUT",
+          url: "/hicc/v1/tile/preview/series",
+          dataType: "json",
+          data: buffer,
+          success: function(data) {
+            $("#value").html(data.join("/"));
+          }
+        });
+        tracker = setTimeout(render, 3000);
+      }
+
+      $( document ).ready(function() {
+        render();
+      });
+    </script>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/home/css/bootstrap-iconpicker.min.css
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/home/css/bootstrap-iconpicker.min.css b/src/main/web/hicc/home/css/bootstrap-iconpicker.min.css
new file mode 100644
index 0000000..fd0160c
--- /dev/null
+++ b/src/main/web/hicc/home/css/bootstrap-iconpicker.min.css
@@ -0,0 +1,9 @@
+/*!
+ * Bootstrap-iconpicker v1.7.0
+ *
+ * Copyright 2013-2015 Victor Valencia Rico.
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world by @recktoner.
+ */.iconpicker .caret{margin-left:10px!important}.iconpicker{min-width:60px}.iconpicker input.search-control{margin-bottom:6px;margin-top:6px}div.iconpicker.left .table-icons{margin-right:auto}div.iconpicker.center .table-icons{margin-left:auto;margin-right:auto}div.iconpicker.right .table-icons{margin-left:auto}.table-icons .btn{min-height:30px;min-width:35px;text-align:center;padding:0;margin:2px}.table-icons td{min-width:39px}.popover{max-width:inherit!important}.iconpicker-popover{z-index:1050!important}.iconpicker-popover .search-control{margin-bottom:6px;margin-top:6px}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/home/css/jquery.gridster.css
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/home/css/jquery.gridster.css b/src/main/web/hicc/home/css/jquery.gridster.css
index ee40430..9251929 100755
--- a/src/main/web/hicc/home/css/jquery.gridster.css
+++ b/src/main/web/hicc/home/css/jquery.gridster.css
@@ -35,7 +35,7 @@ ul, ol {
 }
 
 body {
-    background-color: #EEEEEE;
+    background-color: #ffffff;
     font-family: 'Helvetica Neue', Arial, sans-serif;
     -webkit-font-smoothing: antialiased;
     font-size: x-small;
@@ -44,10 +44,12 @@ body {
 
 .gridster {
     margin-top: 70px;
-    margin-left: 0 auto;
-    margin-right: 0 auto;
-    margin-bottom: 0 auto;
+    margin-left: auto;
+    margin-right: auto;
+    margin-bottom: auto;
     /*position:relative;*/
+    padding: 10px;
+    width: 99%;
 }
 
 .gridster > * {
@@ -87,7 +89,7 @@ body {
 .gridster .preview-holder {
     z-index: 1;
     position: absolute;
-    background-color: #fff;
+    background-color: #ccc;
     border-color: #fff;
     opacity: 0.3;
 }

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/home/graph-explorer.html
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/home/graph-explorer.html b/src/main/web/hicc/home/graph-explorer.html
index 73580d5..03ede7c 100644
--- a/src/main/web/hicc/home/graph-explorer.html
+++ b/src/main/web/hicc/home/graph-explorer.html
@@ -23,9 +23,7 @@
   <link href="../css/bootstrap.min.css" type="text/css" rel="stylesheet" />
   <link href="../css/bootstrap-theme.min.css" type="text/css" rel="stylesheet" />
   <link href="css/select2.min.css" rel="stylesheet" />
-  <script src="../js/jquery.js" type="text/javascript"></script>
-  <script src="../js/bootstrap.min.js" type="text/javascript"></script>
-  <script src="js/select2.min.js"></script>
+  <link href="css/bootstrap-iconpicker.min.css"/>
   <style>
     .nowrap td {
       white-space: nowrap;
@@ -50,24 +48,59 @@
           <label>Metrics</label> <select class="metrics form-control" multiple="multiple"></select>
           <label>Sources</label> <select class="sources form-control" multiple="multiple"></select>
           <label>Title</label> <input type=text id="title" class="form-control" />
-          <label>Y-axis Min</label> <input type="text" id="ymin" class="form-control" />
-          <label>Y-axis Max</label> <input type="text" id="ymax" class="form-control" />
-          <label>Y-axis Unit</label>
-          <select id="yunit" class="form-control">
-            <option>generic</option>
-            <option>bytes</option>
-            <option>bytes-decimal</option>
-            <option value="ops">op/s</option>
-            <option value="percent">%</option>
-          </select>
-          <div id="chartType"></div>
-            <input type=button name="action" value="Plot" class="btn btn-default" onClick="plot()">
-            <input type=button name="action" value="Publish" class="btn btn-default" onClick="publishChart()">
+          <ul id="view" class="nav nav-pills">
+            <li role="presentation" class="active"><a data-toggle="pill" href="#time">Time Series</a></li>
+            <li role="presentation"><a data-toggle="pill" href="#tile">Tile</a></li>
+            <li role="presentation"><a data-toggle="pill" href="#pie">Pie Chart</a></li>
+            <li role="presentation"><a data-toggle="pill" href="#ring">Ring Chart</a></li>
+          </ul>
+
+          <div class="tab-content">
+            <div role="tabpanel" class="tab-pane active" id="time">
+              <label>Y-axis Min</label> <input type="text" id="ymin" class="form-control" />
+              <label>Y-axis Max</label> <input type="text" id="ymax" class="form-control" />
+              <label>Y-axis Unit</label>
+              <select id="yunit" class="form-control">
+                <option>generic</option>
+                <option>bytes</option>
+                <option>bytes-decimal</option>
+                <option value="ops">op/s</option>
+                <option value="percent">%</option>
+              </select>
+              <div id="chartType"></div>
+            </div>
+            <div role="tabpanel" class="tab-pane" id="tile">
+              <label>Banner Icon</label><button name="icon" class="btn btn-default form-control" role="iconpicker"></button>
+              <label>Banner Text</label><input type="text" id="banner" class="form-control" />
+              <label>Suffix Label</label><input type="text" id="suffix" class="form-control" />
+            </div>
+            <div role="tabpanel" class="tab-pane" id="pie">
+              <div class="checkbox">
+                <label><input type="checkbox" id="donut"/>Donut</label>
+              </div>
+            </div>
+            <div role="tabpanel" class="tab-pane" id="ring">
+              <label>Threshold</label>
+              <select id="threshold" class="form-control">
+                <option>Upper bound</option>
+                <option>Lower bound</option>
+              </select>
+              <label>Suffix Label</label><input type="text" id="ringSuffix" class="form-control" />
+            </div>
+          </div>
+
+          <input type=button name="action" value="Plot" class="btn btn-default" onClick="preview()">
+          <input type=button name="action" value="Publish" class="btn btn-default" onClick="publishChart()">
         </div>
         <div class="col-md-8 col-lg-8">
           <iframe id="graph" width="100%" height="700px" frameBorder="0" scrolling="no"></iframe>
         </div>
     </form>
+  <script src="../js/jquery.js" type="text/javascript"></script>
+  <script src="../js/bootstrap.min.js" type="text/javascript"></script>
+  <script src="js/select2.min.js"></script>
+  <script src="js/iconset/iconset-glyphicon.min.js"></script>
+  <script src="js/bootstrap-iconpicker.min.js"></script>
   <script>
     function status(type, message) {
       $('#status').html('<div class="alert alert-'+type+' alert-dismissible" role="alert">'+
@@ -162,6 +195,7 @@ $(function() {
     $metricsEventSelect.on("select2:unselect", function(e) {
       $('#chartType').html("");
     });
+
 });
 
 
@@ -171,7 +205,6 @@ $(function() {
         $('.sources option:eq(0)').attr('selected',true);
       }
       var url = [];
-      var idx = 0;
       $('.metrics :selected').each(function(i, selected) {
         var id = '#ctype' + i;
         var chartType = $(id).val();
@@ -186,24 +219,59 @@ $(function() {
           } else {
             s[chartType]=chartTypeOption;
           }
-          url[idx++] = s;
+          url.push(s);
         }); 
       });
       var title = $('#title').val();
+      var icon = $('input[name="icon"]').val();
       var ymin = $('#ymin').val() ;
       var ymax = $('#ymax').val();
       var yunit = $('#yunit').val();
-      var data = { 'title' : title, 'yUnitType' : yunit, 'width' : 300, 'height' : 200, 'series' : url };
+      var banner = $('#banner').val();
+      var suffix = $('#suffix').val();
+      var view = $("ul#view li.active");
+      if(view.text()=="Ring Chart") {
+        suffix = $('#ringSuffix').val();
+      }
+
+      var data = { 
+                   'title' : title,
+                   'icon' : icon,
+                   'bannerText' : banner, 
+                   'suffixText' : suffix, 
+                   'yUnitType' : yunit, 
+                   'width' : 300, 
+                   'height' : 200, 
+                   'series' : url 
+      };
       if(ymin!='') {
         data['min']=ymin;
       }
       if(ymax!='') {
         data['max']=ymax;
       }
+
+      if( document.getElementById('donut').checked) {
+        data['type']="DONUT";
+      }
+
       return data;
     }
 
-    function plot() {
+    function preview() {
+      var view = $("ul#view li.active");
+      if(view.text()=="Time Series") {
+        plotTimeSeries();
+      } else if(view.text()=="Tile") {
+        plotTile();
+      } else if(view.text()=="Pie Chart") {
+        plotPie();
+      } else if(view.text()=="Ring Chart") {
+        plotCircle();
+      }
+    }
+
+    function plotTimeSeries() {
       var data = buildChart();
       $.ajax({
         url: '/hicc/v1/chart/preview',
@@ -211,10 +279,67 @@ $(function() {
         contentType: 'application/json',
         data: JSON.stringify(data),
         success: function(result) {
-          $('#graph')[0].src="about:blank";
-          $('#graph')[0].contentWindow.document.open();
-          $('#graph')[0].contentWindow.document.write(result);
-          $('#graph')[0].contentWindow.document.close();
+          $('#graph')[0].src="/hicc/loading.html";
+          setTimeout(function() {
+            $('#graph')[0].contentWindow.document.open();
+            $('#graph')[0].contentWindow.document.write(result);
+            $('#graph')[0].contentWindow.document.close();
+          }, 500);
+        }
+      });
+    }
+
+    function plotTile() {
+      var data = buildChart();
+      $.ajax({
+        url: '/hicc/v1/tile/preview',
+        type: 'PUT',
+        contentType: 'application/json',
+        data: JSON.stringify(data),
+        success: function(result) {
+          $('#graph')[0].src="/hicc/loading.html";
+          setTimeout(function() {
+            $('#graph')[0].contentWindow.document.open();
+            $('#graph')[0].contentWindow.document.write(result);
+            $('#graph')[0].contentWindow.document.close();
+          }, 500);
+        }
+      });
+    }
+
+    function plotPie() {
+      var data = buildChart();
+      $.ajax({
+        url: '/hicc/v1/piechart/preview',
+        type: 'PUT',
+        contentType: 'application/json',
+        data: JSON.stringify(data),
+        success: function(result) {
+          $('#graph')[0].src="/hicc/loading.html";
+          setTimeout(function() {
+            $('#graph')[0].contentWindow.document.open();
+            $('#graph')[0].contentWindow.document.write(result);
+            $('#graph')[0].contentWindow.document.close();
+          }, 500);
+        }
+      });
+    }
+
+    function plotCircle() {
+      var data = buildChart();
+      $.ajax({
+        url: '/hicc/v1/circles/preview',
+        type: 'PUT',
+        contentType: 'application/json',
+        data: JSON.stringify(data),
+        success: function(result) {
+          console.log(result);
+          $('#graph')[0].src="/hicc/loading.html";
+          setTimeout(function() {
+            $('#graph')[0].contentWindow.document.open();
+            $('#graph')[0].contentWindow.document.write(result);
+            $('#graph')[0].contentWindow.document.close();
+          }, 500);
         }
       });
     }
@@ -263,7 +388,18 @@ $(function() {
         contentType : "application/json",
         data: JSON.stringify(json),
         success: function(data) {
-          buildWidget(json.title, '/hicc/v1/chart/draw/'+data);
+          var view = $("ul#view li.active");
+          if(view.text()=="Time Series") {
+            type="chart";
+          } else if(view.text()=="Tile") {
+            type="tile";
+          } else if(view.text()=="Pie Chart") {
+            type="piechart";
+          } else if(view.text()=="Ring Chart") {
+            type="circles";
+          }
+          var target = '/hicc/v1/'+type+'/draw/'+data
+          buildWidget(json.title, target);
         },
         error: function(data) {
           alert("failed");

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/home/js/bootstrap-iconpicker.min.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/home/js/bootstrap-iconpicker.min.js b/src/main/web/hicc/home/js/bootstrap-iconpicker.min.js
new file mode 100644
index 0000000..66513f9
--- /dev/null
+++ b/src/main/web/hicc/home/js/bootstrap-iconpicker.min.js
@@ -0,0 +1,19 @@
+/*!========================================================================
+ * Bootstrap: bootstrap-iconpicker.js v1.7.0 by @recktoner
+ * https://victor-valencia.github.com/bootstrap-iconpicker
+ * ========================================================================
+ * Copyright 2013-2015 Victor Valencia Rico.
+ *
+ * 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.
+ * ======================================================================== */
+!function($){"use strict";var Iconpicker=function(element,options){this.$element=$(element),this.options=$.extend({},Iconpicker.DEFAULTS,this.$element.data()),this.options=$.extend({},this.options,options)};Iconpicker.ICONSET_EMPTY={iconClass:"",iconClassFix:"",icons:[]},Iconpicker.ICONSET={_custom:null,elusiveicon:$.iconset_elusiveicon||Iconpicker.ICONSET_EMPTY,fontawesome:$.iconset_fontawesome||Iconpicker.ICONSET_EMPTY,ionicon:$.iconset_ionicon||Iconpicker.ICONSET_EMPTY,glyphicon:$.iconset_glyphicon||Iconpicker.ICONSET_EMPTY,mapicon:$.iconset_mapicon||Iconpicker.ICONSET_EMPTY,materialdesign:$.iconset_materialdesign||Iconpicker.ICONSET_EMPTY,octicon:$.iconset_octicon||Iconpicker.ICONSET_EMPTY,typicon:$.iconset_typicon||Iconpicker.ICONSET_EMPTY,weathericon:$.iconset_weathericon||Iconpicker.ICONSET_EMPTY},Iconpicker.DEFAULTS={align:"center",arrowClass:"btn-primary",arrowNextIconClass:"glyphicon glyphicon-arrow-right",arrowPrevIconClass:"glyphicon glyphicon-arrow-left",cols:4,icon:"",
 iconset:"glyphicon",header:!0,labelHeader:"{0} / {1}",footer:!0,labelFooter:"{0} - {1} of {2}",placement:"bottom",rows:4,search:!0,searchText:"Search icon",selectedClass:"btn-warning",unselectedClass:"btn-default"},Iconpicker.prototype.bindEvents=function(){var op=this.options,el=this;op.table.find(".btn-previous, .btn-next").off("click").on("click",function(e){e.preventDefault();var inc=parseInt($(this).val(),10);el.changeList(op.page+inc)}),op.table.find(".btn-icon").off("click").on("click",function(e){e.preventDefault(),el.select($(this).val()),op.inline===!1?el.$element.popover("destroy"):op.table.find("i."+$(this).val()).parent().addClass(op.selectedClass)}),op.table.find(".search-control").off("keyup").on("keyup",function(){el.changeList(1)})},Iconpicker.prototype.changeList=function(page){this.filterIcons(),this.updateLabels(page),this.updateIcons(page),this.options.page=page,this.bindEvents()},Iconpicker.prototype.filterIcons=function(){var op=this.options,search=op.table.fi
 nd(".search-control").val();if(""===search)op.icons=Iconpicker.ICONSET[op.iconset].icons;else{var result=[];$.each(Iconpicker.ICONSET[op.iconset].icons,function(i,v){v.indexOf(search)>-1&&result.push(v)}),op.icons=result}},Iconpicker.prototype.removeAddClass=function(target,remove,add){return this.options.table.find(target).removeClass(remove).addClass(add),add},Iconpicker.prototype.reset=function(){this.updatePicker(),this.changeList(1)},Iconpicker.prototype.select=function(icon){var op=this.options,el=this.$element;op.selected=$.inArray(icon.replace(op.iconClassFix,""),op.icons),-1===op.selected&&(op.selected=0,icon=op.iconClassFix+op.icons[op.selected]),""!==icon&&op.selected>=0&&(op.icon=icon,op.inline===!1&&(el.find("input").val(icon),el.find("i").attr("class","").addClass(op.iconClass).addClass(icon)),icon===op.iconClassFix?el.trigger({type:"change",icon:"empty"}):el.trigger({type:"change",icon:icon}),op.table.find("button."+op.selectedClass).removeClass(op.selectedClass))},Ic
 onpicker.prototype.switchPage=function(icon){var op=this.options;if(op.selected=$.inArray(icon.replace(op.iconClassFix,""),op.icons),op.selected>=0){var page=Math.ceil((op.selected+1)/this.totalIconsPerPage());this.changeList(page)}""===icon?op.table.find("i."+op.iconClassFix).parent().addClass(op.selectedClass):op.table.find("i."+icon).parent().addClass(op.selectedClass)},Iconpicker.prototype.totalPages=function(){return Math.ceil(this.totalIcons()/this.totalIconsPerPage())},Iconpicker.prototype.totalIcons=function(){return this.options.icons.length},Iconpicker.prototype.totalIconsPerPage=function(){return 0===this.options.rows?this.options.icons.length:this.options.cols*this.options.rows},Iconpicker.prototype.updateArrows=function(page){var op=this.options,total_pages=this.totalPages();1===page?op.table.find(".btn-previous").addClass("disabled"):op.table.find(".btn-previous").removeClass("disabled"),page===total_pages||0===total_pages?op.table.find(".btn-next").addClass("disabled"
 ):op.table.find(".btn-next").removeClass("disabled")},Iconpicker.prototype.updateIcons=function(page){var op=this.options,tbody=op.table.find("tbody").empty(),offset=(page-1)*this.totalIconsPerPage(),length=op.rows;0===op.rows&&(length=op.icons.length);for(var i=0;length>i;i++){for(var tr=$("<tr></tr>"),j=0;j<op.cols;j++){var pos=offset+i*op.cols+j,btn=$('<button class="btn '+op.unselectedClass+' btn-icon"></button>').hide();if(pos<op.icons.length){var v=op.iconClassFix+op.icons[pos];btn.val(v).attr("title",v).append('<i class="'+op.iconClass+" "+v+'"></i>').show(),op.icon===v&&btn.addClass(op.selectedClass).addClass("btn-icon-selected")}tr.append($("<td></td>").append(btn))}tbody.append(tr)}},Iconpicker.prototype.updateIconsCount=function(){var op=this.options;if(op.footer===!0){var icons_count=["<tr>",'   <td colspan="'+op.cols+'" class="text-center">','       <span class="icons-count"></span>',"   </td>","</tr>"];op.table.find("tfoot").empty().append(icons_count.join(""))}},Iconp
 icker.prototype.updateLabels=function(page){var op=this.options,total_icons=this.totalIcons(),total_pages=this.totalPages();op.table.find(".page-count").html(op.labelHeader.replace("{0}",0===total_pages?0:page).replace("{1}",total_pages));var offset=(page-1)*this.totalIconsPerPage(),total=page*this.totalIconsPerPage();op.table.find(".icons-count").html(op.labelFooter.replace("{0}",offset+1).replace("{1}",total_icons>total?total:total_icons).replace("{2}",total_icons)),this.updateArrows(page)},Iconpicker.prototype.updatePagesCount=function(){var op=this.options;if(op.header===!0){for(var tr=$("<tr></tr>"),i=0;i<op.cols;i++){var td=$('<td class="text-center"></td>');if(0===i||i===op.cols-1){var arrow=['<button class="btn btn-arrow '+(0===i?"btn-previous":"btn-next")+" "+op.arrowClass+'" value="'+(0===i?-1:1)+'">','<span class="'+(0===i?op.arrowPrevIconClass:op.arrowNextIconClass)+'"></span>',"</button>"];td.append(arrow.join("")),tr.append(td)}else 0===tr.find(".page-count").length&&(
 td.attr("colspan",op.cols-2).append('<span class="page-count"></span>'),tr.append(td))}op.table.find("thead").empty().append(tr)}},Iconpicker.prototype.updatePicker=function(){var op=this.options;if(op.cols<4)throw"Iconpicker => The number of columns must be greater than or equal to 4. [option.cols = "+op.cols+"]";if(op.rows<0)throw"Iconpicker => The number of rows must be greater than or equal to 0. [option.rows = "+op.rows+"]";this.updatePagesCount(),this.updateSearch(),this.updateIconsCount()},Iconpicker.prototype.updateSearch=function(){var op=this.options,search=["<tr>",'   <td colspan="'+op.cols+'">','       <input type="text" class="form-control search-control" style="width: '+39*op.cols+'px;" placeholder="'+op.searchText+'">',"   </td>","</tr>"];search=$(search.join("")),op.search===!0?search.show():search.hide(),op.table.find("thead").append(search)},Iconpicker.prototype.setAlign=function(value){this.$element.removeClass(this.options.align).addClass(value),this.options.alig
 n=value},Iconpicker.prototype.setArrowClass=function(value){this.options.arrowClass=this.removeAddClass(".btn-arrow",this.options.arrowClass,value)},Iconpicker.prototype.setArrowNextIconClass=function(value){this.options.arrowNextIconClass=this.removeAddClass(".btn-next > span",this.options.arrowNextIconClass,value)},Iconpicker.prototype.setArrowPrevIconClass=function(value){this.options.arrowPrevIconClass=this.removeAddClass(".btn-previous > span",this.options.arrowPrevIconClass,value)},Iconpicker.prototype.setCols=function(value){this.options.cols=value,this.reset()},Iconpicker.prototype.setFooter=function(value){var footer=this.options.table.find("tfoot");value===!0?footer.show():footer.hide(),this.options.footer=value},Iconpicker.prototype.setHeader=function(value){var header=this.options.table.find("thead");value===!0?header.show():header.hide(),this.options.header=value},Iconpicker.prototype.setIcon=function(value){this.select(value)},Iconpicker.prototype.setIconset=function(v
 alue){var op=this.options;$.isPlainObject(value)?(Iconpicker.ICONSET._custom=$.extend(Iconpicker.ICONSET_EMPTY,value),op.iconset="_custom"):Iconpicker.ICONSET.hasOwnProperty(value)?op.iconset=value:op.iconset=Iconpicker.DEFAULTS.iconset,op=$.extend(op,Iconpicker.ICONSET[op.iconset]),this.reset(),this.select(op.icon)},Iconpicker.prototype.setLabelHeader=function(value){this.options.labelHeader=value,this.updateLabels(this.options.page)},Iconpicker.prototype.setLabelFooter=function(value){this.options.labelFooter=value,this.updateLabels(this.options.page)},Iconpicker.prototype.setPlacement=function(value){this.options.placement=value},Iconpicker.prototype.setRows=function(value){this.options.rows=value,this.reset()},Iconpicker.prototype.setSearch=function(value){var search=this.options.table.find(".search-control");value===!0?search.show():search.hide(),search.val(""),this.changeList(1),this.options.search=value},Iconpicker.prototype.setSearchText=function(value){this.options.table.fi
 nd(".search-control").attr("placeholder",value),this.options.searchText=value},Iconpicker.prototype.setSelectedClass=function(value){this.options.selectedClass=this.removeAddClass(".btn-icon-selected",this.options.selectedClass,value)},Iconpicker.prototype.setUnselectedClass=function(value){this.options.unselectedClass=this.removeAddClass(".btn-icon",this.options.unselectedClass,value)};var old=$.fn.iconpicker;$.fn.iconpicker=function(option,params){return this.each(function(){var $this=$(this),data=$this.data("bs.iconpicker"),options="object"==typeof option&&option;if(data||$this.data("bs.iconpicker",data=new Iconpicker(this,options)),"string"==typeof option){if("undefined"==typeof data[option])throw'Iconpicker => The "'+option+'" method does not exists.';data[option](params)}else{var op=data.options;op=$.extend(op,{inline:!1,page:1,selected:-1,table:$('<table class="table-icons"><thead></thead><tbody></tbody><tfoot></tfoot></table>')});var name="undefined"!=typeof $this.attr("name
 ")?'name="'+$this.attr("name")+'"':"";"BUTTON"===$this.prop("tagName")?($this.empty().append("<i></i>").append('<input type="hidden" '+name+"></input>").append('<span class="caret"></span>').addClass("iconpicker"),data.setIconset(op.iconset),$this.on("click",function(e){e.preventDefault(),$this.popover({animation:!1,trigger:"manual",html:!0,content:op.table,container:"body",placement:op.placement}).on("shown.bs.popover",function(){data.switchPage(op.icon),data.bindEvents()}),$this.data("bs.popover").tip().addClass("iconpicker-popover"),$this.popover("show")})):(op.inline=!0,data.setIconset(op.iconset),$this.empty().append('<input type="hidden" '+name+"></input>").append(op.table).addClass("iconpicker").addClass(op.align),data.switchPage(op.icon),data.bindEvents())}})},$.fn.iconpicker.Constructor=Iconpicker,$.fn.iconpicker.noConflict=function(){return $.fn.iconpicker=old,this},$(document).on("click","body",function(e){$(".iconpicker").each(function(){$(this).is(e.target)||0!==$(this)
 .has(e.target).length||0!==$(".popover").has(e.target).length||$(this).popover("destroy")})}),$('button[role="iconpicker"],div[role="iconpicker"]').iconpicker()}(jQuery);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/home/js/iconset/iconset-glyphicon.min.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/home/js/iconset/iconset-glyphicon.min.js b/src/main/web/hicc/home/js/iconset/iconset-glyphicon.min.js
new file mode 100644
index 0000000..da6b9fb
--- /dev/null
+++ b/src/main/web/hicc/home/js/iconset/iconset-glyphicon.min.js
@@ -0,0 +1,21 @@
+/*!========================================================================
+ * Bootstrap: iconset-glyphicon.js by @recktoner 
+ * https://victor-valencia.github.com/bootstrap-iconpicker
+ * 
+ * Iconset: Glyphicons
+ * ========================================================================
+ * Copyright 2013-2015 Victor Valencia Rico.
+ *
+ * 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.
+ * ======================================================================== */
+!function($){$.iconset_glyphicon={iconClass:"glyphicon",iconClassFix:"glyphicon-",icons:["","adjust","align-center","align-justify","align-left","align-right","arrow-down","arrow-left","arrow-right","arrow-up","asterisk","backward","ban-circle","barcode","bell","bold","book","bookmark","briefcase","bullhorn","calendar","camera","certificate","check","chevron-down","chevron-left","chevron-right","chevron-up","circle-arrow-down","circle-arrow-left","circle-arrow-right","circle-arrow-up","cloud","cloud-download","cloud-upload","cog","collapse-down","collapse-up","comment","compressed","copyright-mark","credit-card","cutlery","dashboard","download","download-alt","earphone","edit","eject","envelope","euro","exclamation-sign","expand","export","eye-close","eye-open","facetime-video","fast-backward","fast-forward","file","film","filter","fire","flag","flash","floppy-disk","floppy-open","floppy-remove","floppy-save","floppy-saved","folder-close","folder-open","font","forward","fullscreen",
 "gbp","gift","glass","globe","hand-down","hand-left","hand-right","hand-up","hd-video","hdd","header","headphones","heart","heart-empty","home","import","inbox","indent-left","indent-right","info-sign","italic","leaf","link","list","list-alt","lock","log-in","log-out","magnet","map-marker","minus","minus-sign","move","music","new-window","off","ok","ok-circle","ok-sign","open","paperclip","pause","pencil","phone","phone-alt","picture","plane","play","play-circle","plus","plus-sign","print","pushpin","qrcode","question-sign","random","record","refresh","registration-mark","remove","remove-circle","remove-sign","repeat","resize-full","resize-horizontal","resize-small","resize-vertical","retweet","road","save","saved","screenshot","sd-video","search","send","share","share-alt","shopping-cart","signal","sort","sort-by-alphabet","sort-by-alphabet-alt","sort-by-attributes","sort-by-attributes-alt","sort-by-order","sort-by-order-alt","sound-5-1","sound-6-1","sound-7-1","sound-dolby","sound
 -stereo","star","star-empty","stats","step-backward","step-forward","stop","subtitles","tag","tags","tasks","text-height","text-width","th","th-large","th-list","thumbs-down","thumbs-up","time","tint","tower","transfer","trash","tree-conifer","tree-deciduous","unchecked","upload","usd","user","volume-down","volume-off","volume-up","warning-sign","wrench","zoom-in","zoom-out"]}}(jQuery);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/home/tile.html
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/home/tile.html b/src/main/web/hicc/home/tile.html
index cf1aa91..729462f 100644
--- a/src/main/web/hicc/home/tile.html
+++ b/src/main/web/hicc/home/tile.html
@@ -27,6 +27,10 @@
       .tile {
         color: #ffffff;
         background-color: #5bc0de;
+        text-overflow: hidden;
+      }
+      .container {
+        width: 100%;
       }
       .row {
         display: -webkit-box;
@@ -34,15 +38,60 @@
         display: -ms-flexbox;
         display:         flex;
       }
+.jumbotron.vertical-center {
+  margin-bottom: 0; /* Remove the default bottom margin of .jumbotron */
+}
+
+.vertical-center {
+  min-height: 100%;  /* Fallback for vh unit */
+  min-height: 100vh; /* You might also want to use
+                        'height' property instead.
+                        
+                        Note that for percentage values of
+                        'height' or 'min-height' properties,
+                        the 'height' of the parent element
+                        should be specified explicitly.
+  
+                        In this case the parent of '.vertical-center'
+                        is the <body> element */
+
+  /* Make it a flex container */
+  display: -webkit-box;
+  display: -moz-box;
+  display: -ms-flexbox;
+  display: -webkit-flex;
+  display: flex; 
+  
+  /* Align the bootstrap's container vertically */
+    -webkit-box-align : center;
+  -webkit-align-items : center;
+       -moz-box-align : center;
+       -ms-flex-align : center;
+          align-items : center;
+  
+  /* In legacy web browsers such as Firefox 9
+     we need to specify the width of the flex container */
+  width: 100%;
+  
+  /* Also 'margin: 0 auto' doesn't have any effect on flex items in such web browsers
+     hence the bootstrap's container won't be aligned to the center anymore.
+  
+     Therefore, we should use the following declarations to get it centered again */
+         -webkit-box-pack : center;
+            -moz-box-pack : center;
+            -ms-flex-pack : center;
+  -webkit-justify-content : center;
+          justify-content : center;
+}
     </style>
   </head>
   <body onResize="resize()">
-    <div class="jumbotron">
+    <div class="jumbotron vertical-center">
     <div class="container">
       <div class="row">
         <div class="col-xs-5 col-md-5 text-center tile">
             <h2><span class="glyphicon glyphicon-picture" aria-hidden="true"></span></h2>
-            Applications
+            <div class="tile">Applications</div>
         </div>
         <div class="col-xs-7 col-md-7 text-center">
           <p><h1>4</h1> Running</p>
@@ -67,6 +116,7 @@
       $( document ).ready(function() {
         render();
       });
+      document.body.style.overflow = 'hidden';
     </script>
   </body>
 </html>

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/images/loading.svg
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/images/loading.svg b/src/main/web/hicc/images/loading.svg
new file mode 100644
index 0000000..a8a7070
--- /dev/null
+++ b/src/main/web/hicc/images/loading.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+<svg width='120px' height='120px' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="uil-ring"><rect x="0" y="0" width="100" height="100" fill="none" class="bk"></rect><defs><filter id="uil-ring-shadow" x="-100%" y="-100%" width="300%" height="300%"><feOffset result="offOut" in="SourceGraphic" dx="0" dy="0"></feOffset><feGaussianBlur result="blurOut" in="offOut" stdDeviation="0"></feGaussianBlur><feBlend in="SourceGraphic" in2="blurOut" mode="normal"></feBlend></filter></defs><path d="M10,50c0,0,0,0.5,0.1,1.4c0,0.5,0.1,1,0.2,1.7c0,0.3,0.1,0.7,0.1,1.1c0.1,0.4,0.1,0.8,0.2,1.2c0.2,0.8,0.3,1.8,0.5,2.8 c0.3,1,0.6,2.1,0.9,3.2c0.3,1.1,0.9,2.3,1.4,3.5c0.5,1.2,1.2,2.4,1.8,3.7c0.3,0.6,0.8,1.2,1.2,1.9c0.4,0.6,0.8,1.3,1.3,1.9 c1,1.2,1.9,2.6,3.1,3.7c2.2,2.5,5,4.7,7.9,6.7c3,2,6.5,3.4,10.1,4.6c3.6,1.1,7.5,1.5,11.2,1.6c4-0.1,7.7-0.6,11.3-1.6 c3.6-1.2,7-2.6,10-4.6c3-2,5.8-4.2,7.9-6.7c1.2-1.2,2.1-2.5,3.1-3.7c0.5-0.6,0.9-1.3,1.3-1.9c0.4-0.6,0.8-1.3,1.2-1.9 c
 0.6-1.3,1.3-2.5,1.8-3.7c0.5-1.2,1-2.4,1.4-3.5c0.3-1.1,0.6-2.2,0.9-3.2c0.2-1,0.4-1.9,0.5-2.8c0.1-0.4,0.1-0.8,0.2-1.2 c0-0.4,0.1-0.7,0.1-1.1c0.1-0.7,0.1-1.2,0.2-1.7C90,50.5,90,50,90,50s0,0.5,0,1.4c0,0.5,0,1,0,1.7c0,0.3,0,0.7,0,1.1 c0,0.4-0.1,0.8-0.1,1.2c-0.1,0.9-0.2,1.8-0.4,2.8c-0.2,1-0.5,2.1-0.7,3.3c-0.3,1.2-0.8,2.4-1.2,3.7c-0.2,0.7-0.5,1.3-0.8,1.9 c-0.3,0.7-0.6,1.3-0.9,2c-0.3,0.7-0.7,1.3-1.1,2c-0.4,0.7-0.7,1.4-1.2,2c-1,1.3-1.9,2.7-3.1,4c-2.2,2.7-5,5-8.1,7.1 c-0.8,0.5-1.6,1-2.4,1.5c-0.8,0.5-1.7,0.9-2.6,1.3L66,87.7l-1.4,0.5c-0.9,0.3-1.8,0.7-2.8,1c-3.8,1.1-7.9,1.7-11.8,1.8L47,90.8 c-1,0-2-0.2-3-0.3l-1.5-0.2l-0.7-0.1L41.1,90c-1-0.3-1.9-0.5-2.9-0.7c-0.9-0.3-1.9-0.7-2.8-1L34,87.7l-1.3-0.6 c-0.9-0.4-1.8-0.8-2.6-1.3c-0.8-0.5-1.6-1-2.4-1.5c-3.1-2.1-5.9-4.5-8.1-7.1c-1.2-1.2-2.1-2.7-3.1-4c-0.5-0.6-0.8-1.4-1.2-2 c-0.4-0.7-0.8-1.3-1.1-2c-0.3-0.7-0.6-1.3-0.9-2c-0.3-0.7-0.6-1.3-0.8-1.9c-0.4-1.3-0.9-2.5-1.2-3.7c-0.3-1.2-0.5-2.3-0.7-3.3 c-0.2-1-0.3-2-0.4-2.8c-0.1-0.4-0.1-0.8-0.1-1.2c0-0.4,0-0.7,0-1.
 1c0-0.7,0-1.2,0-1.7C10,50.5,10,50,10,50z" fill="#5a707a" filter="url(#uil-ring-shadow)"><animateTransform attributeName="transform" type="rotate" from="0 50 50" to="360 50 50" repeatCount="indefinite" dur="1s"></animateTransform></path></svg>

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/js/pie.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/js/pie.js b/src/main/web/hicc/js/pie.js
new file mode 100644
index 0000000..b2656cb
--- /dev/null
+++ b/src/main/web/hicc/js/pie.js
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+var pieChart = null;
+var labels = [];
+var series = [];
+
+for (var i = 0; i < _series.length; i++) {
+  labels[i] = _series[i].label;
+  series[i] = 1;
+}
+
+var data = {
+  labels: labels,
+  series: series
+};
+
+var options = {
+  donut: donut,
+  labelInterpolationFnc: function(value) {
+    return value[0]
+  }
+};
+
+var responsiveOptions = [
+  ['screen and (min-width: 200px)', {
+    chartPadding: 20,
+    labelOffset: 20,
+    labelDirection: 'explode',
+    labelInterpolationFnc: function(value) {
+      return value;
+    }
+  }],
+  ['screen and (min-width: 400px)', {
+    labelOffset: 80,
+    chartPadding: 20
+  }]
+];
+
+var timer = null;
+
+function refresh() {
+  var buffer=JSON.stringify(_series);
+  $.ajax({
+    url: "/hicc/v1/piechart/preview/series",
+    type: 'PUT',
+    contentType: 'application/json',
+    data: buffer,
+    dataType: 'json',
+    success: function(result) {
+      var data = {
+        labels: labels,
+        series: result
+      };
+      if(pieChart == null) {
+        pieChart = new Chartist.Pie('.ct-chart', data, options, responsiveOptions);
+        timer = setTimeout(refresh, 3000);
+      } else {
+        pieChart.update(data, options, true);
+      }
+    }
+  });
+}
+
+refresh();

http://git-wip-us.apache.org/repos/asf/chukwa/blob/5e66273f/src/main/web/hicc/loading.html
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/loading.html b/src/main/web/hicc/loading.html
new file mode 100644
index 0000000..3ac7855
--- /dev/null
+++ b/src/main/web/hicc/loading.html
@@ -0,0 +1,49 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link href="css/bootstrap-theme.min.css" type="text/css" rel="stylesheet" />
+    <link href="css/bootstrap.min.css" type="text/css" rel="stylesheet" />
+    <style>
+      .vertical-center {
+        min-height: 100%;  /* Fallback for browsers do NOT support vh unit */
+        min-height: 100vh; /* These two lines are counted as one :-)       */
+        display: flex;
+        align-items: center;
+      }
+      .col-centered{
+        float: none;
+        margin: 0 auto;
+      }
+    </style>
+    <script src="js/jquery.js" type="text/javascript"></script>
+    <script src="js/bootstrap.min.js" type="text/javascript"></script>
+  </head>
+  <body>
+    <div class="jumbotron vertical-center">
+      <div class="container">
+      <div class="row">
+        <div class="col-lg-1 col-centered">
+          <center><img src="images/loading.svg"/></center>
+        </div>
+      </div>
+      </div>
+    </div>
+  </body>
+</html>


Mime
View raw message