DRILL-5802: Provide a sortable table for tables within a query profile

Using the DataTables jQuery library, we can now sort tables (fragments and 
operators) to group like values or sort on a column.
In addition, additional tooltips have been provided for these columns

closes #969


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

Branch: refs/heads/master
Commit: bec436f87d14a27180658b0b00b90ba6c6161f72
Parents: da88bf7
Author: Kunal Khatua <kkha...@maprtech.com>
Authored: Mon Oct 2 21:34:01 2017 -0700
Committer: Paul Rogers <prog...@maprtech.com>
Committed: Wed Oct 4 12:34:17 2017 -0700

----------------------------------------------------------------------
 .../server/rest/profile/FragmentWrapper.java    |  47 +++++-
 .../server/rest/profile/OperatorWrapper.java    |  36 +++-
 .../exec/server/rest/profile/TableBuilder.java  |  10 +-
 .../src/main/resources/rest/profile/profile.ftl |  23 +++
 .../resources/rest/static/img/black-asc.gif     | Bin 0 -> 48 bytes
 .../resources/rest/static/img/black-desc.gif    | Bin 0 -> 49 bytes
 .../rest/static/img/black-unsorted.gif          | Bin 0 -> 54 bytes
 .../static/js/jquery.dataTables-1.10.16.min.js  | 164 +++++++++++++++++++
 8 files changed, 266 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/drill/blob/bec436f8/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/FragmentWrapper.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/FragmentWrapper.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/FragmentWrapper.java
index b25b92a..2233f2e 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/FragmentWrapper.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/FragmentWrapper.java
@@ -17,12 +17,9 @@
  */
 package org.apache.drill.exec.server.rest.profile;
 
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Date;
 import java.util.List;
-import java.util.Locale;
 
 import org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile;
 import org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile;
@@ -205,14 +202,23 @@ public class FragmentWrapper {
     tb.appendBytes(maxMem.getMaxMemoryUsed());
   }
 
-  public static final String[] FRAGMENT_COLUMNS = {"Minor Fragment ID", "Host 
Name", "Start", "End",
-      "Runtime", "Max Records", "Max Batches", "Last Update", "Last Progress", 
"Peak Memory", "State"};
+  public static final String[] FRAGMENT_COLUMNS = {
+      FragmentTblTxt.MINOR_FRAGMENT, FragmentTblTxt.HOSTNAME, 
FragmentTblTxt.START_TIME, FragmentTblTxt.END_TIME,
+      FragmentTblTxt.RUNTIME, FragmentTblTxt.MAX_RECORDS, 
FragmentTblTxt.MAX_BATCHES, FragmentTblTxt.LAST_UPDATE,
+      FragmentTblTxt.LAST_PROGRESS, FragmentTblTxt.PEAK_MEMORY, 
FragmentTblTxt.STATE
+  };
+
+  public static final String[] FRAGMENT_COLUMNS_TOOLTIP = {
+      FragmentTblTooltip.MINOR_FRAGMENT, FragmentTblTooltip.HOSTNAME, 
FragmentTblTooltip.START_TIME, FragmentTblTooltip.END_TIME,
+      FragmentTblTooltip.RUNTIME, FragmentTblTooltip.MAX_RECORDS, 
FragmentTblTooltip.MAX_BATCHES, FragmentTblTooltip.LAST_UPDATE,
+      FragmentTblTooltip.LAST_PROGRESS, FragmentTblTooltip.PEAK_MEMORY, 
FragmentTblTooltip.STATE
+  };
 
   // Not including minor fragment ID
   private static final int NUM_NULLABLE_FRAGMENTS_COLUMNS = 
FRAGMENT_COLUMNS.length - 1;
 
   public String getContent() {
-    final TableBuilder builder = new TableBuilder(FRAGMENT_COLUMNS, null);
+    final TableBuilder builder = new TableBuilder(FRAGMENT_COLUMNS, 
FRAGMENT_COLUMNS_TOOLTIP, true);
 
     // Use only minor fragments that have complete profiles
     // Complete iff the fragment profile has at least one operator profile, 
and start and end times.
@@ -261,6 +267,34 @@ public class FragmentWrapper {
     return builder.build();
   }
 
+  private class FragmentTblTxt {
+    static final String MINOR_FRAGMENT = "Minor Fragment";
+    static final String HOSTNAME = "Hostname";
+    static final String START_TIME = "Start";
+    static final String END_TIME = "End";
+    static final String RUNTIME = "Runtime";
+    static final String MAX_BATCHES = "Max Batches";
+    static final String MAX_RECORDS = "Max Records";
+    static final String LAST_UPDATE = "Last Update";
+    static final String LAST_PROGRESS = "Last Progress";
+    static final String PEAK_MEMORY = "Peak Memory";
+    static final String STATE = "State";
+  }
+
+  private class FragmentTblTooltip {
+    static final String MINOR_FRAGMENT = "Minor Fragment ID";
+    static final String HOSTNAME = "Host on which the fragment ran";
+    static final String START_TIME = "Fragment Start Time";
+    static final String END_TIME = "Fragment End Time";
+    static final String RUNTIME = "Duration of the Fragment";
+    static final String MAX_BATCHES = "Max Records processed by the fragment";
+    static final String MAX_RECORDS = "Max Batches processed by the fragment";
+    static final String LAST_UPDATE = "Last time fragment reported heartbeat";
+    static final String LAST_PROGRESS = "Last time fragment reported back 
metrics";
+    static final String PEAK_MEMORY = "Fragment Peak Memory Usage";
+    static final String STATE = "State of the fragment";
+  }
+
   private class OverviewTblTxt {
     static final String MAJOR_FRAGMENT = "Major Fragment";
     static final String MINOR_FRAGMENTS_REPORTING = "Minor Fragments 
Reporting";
@@ -294,4 +328,3 @@ public class FragmentWrapper {
   }
 }
 
-

http://git-wip-us.apache.org/repos/asf/drill/blob/bec436f8/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/OperatorWrapper.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/OperatorWrapper.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/OperatorWrapper.java
index fce8998..cca9563 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/OperatorWrapper.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/OperatorWrapper.java
@@ -63,11 +63,18 @@ public class OperatorWrapper {
     return String.format("operator-%d-%d", major, 
opsAndHosts.get(0).getLeft().getLeft().getOperatorId());
   }
 
-  public static final String [] OPERATOR_COLUMNS = {"Minor Fragment", "Host 
Name", "Setup Time", "Process Time", "Wait Time",
-      "Max Batches", "Max Records", "Peak Memory"};
+  public static final String [] OPERATOR_COLUMNS = {
+      OperatorTblTxt.MINOR_FRAGMENT, OperatorTblTxt.HOSTNAME, 
OperatorTblTxt.SETUP_TIME, OperatorTblTxt.PROCESS_TIME, 
OperatorTblTxt.WAIT_TIME,
+      OperatorTblTxt.MAX_BATCHES, OperatorTblTxt.MAX_RECORDS, 
OperatorTblTxt.PEAK_MEMORY
+  };
+
+  public static final String [] OPERATOR_COLUMNS_TOOLTIP = {
+      OperatorTblTooltip.MINOR_FRAGMENT, OperatorTblTooltip.HOSTNAME, 
OperatorTblTooltip.SETUP_TIME, OperatorTblTooltip.PROCESS_TIME, 
OperatorTblTooltip.WAIT_TIME,
+      OperatorTblTooltip.MAX_BATCHES, OperatorTblTooltip.MAX_RECORDS, 
OperatorTblTooltip.PEAK_MEMORY
+  };
 
   public String getContent() {
-    TableBuilder builder = new TableBuilder(OPERATOR_COLUMNS, null);
+    TableBuilder builder = new TableBuilder(OPERATOR_COLUMNS, 
OPERATOR_COLUMNS_TOOLTIP, true);
 
     for (ImmutablePair<ImmutablePair<OperatorProfile, Integer>, String> ip : 
opsAndHosts) {
       int minor = ip.getLeft().getRight();
@@ -223,6 +230,28 @@ public class OperatorWrapper {
     return builder.build();
   }
 
+  private class OperatorTblTxt {
+    static final String MINOR_FRAGMENT = "Minor Fragment";
+    static final String HOSTNAME = "Hostname";
+    static final String SETUP_TIME = "Setup Time";
+    static final String PROCESS_TIME = "Process Time";
+    static final String WAIT_TIME = "Wait Time";
+    static final String MAX_BATCHES = "Max Batches";
+    static final String MAX_RECORDS = "Max Records";
+    static final String PEAK_MEMORY = "Peak Memory";
+  }
+
+  private class OperatorTblTooltip {
+    static final String MINOR_FRAGMENT = "Operator's Minor Fragment";
+    static final String HOSTNAME = "Host on which the minor fragment ran";
+    static final String SETUP_TIME = "Setup Time for the minor fragment's 
operator";
+    static final String PROCESS_TIME = "Process Time for the minor fragment's 
operator";
+    static final String WAIT_TIME = "Wait Time for the minor fragment's 
operator";
+    static final String MAX_BATCHES = "Max Batches processed by the minor 
fragment's operator";
+    static final String MAX_RECORDS = "Max Records processed by the minor 
fragment's operator";
+    static final String PEAK_MEMORY = "Peak Memory usage by the minor 
fragment's operator";
+  }
+
   private class OverviewTblTxt {
     static final String OPERATOR_ID = "Operator ID";
     static final String TYPE_OF_OPERATOR = "Type";
@@ -257,4 +286,3 @@ public class OperatorWrapper {
     static final String MAX_PEAK_MEMORY  =  "Highest memory consumption by a 
fragment";
   }
 }
-

http://git-wip-us.apache.org/repos/asf/drill/blob/bec436f8/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/TableBuilder.java
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/TableBuilder.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/TableBuilder.java
index 07598c5..b49382b 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/TableBuilder.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/TableBuilder.java
@@ -34,12 +34,16 @@ public class TableBuilder {
   private int width;
 
   public TableBuilder(final String[] columns, final String[] columnTooltip) {
+    this(columns, columnTooltip, false);
+  }
+
+  public TableBuilder(final String[] columns, final String[] columnTooltip, 
final boolean isSortable) {
     sb = new StringBuilder();
     width = columns.length;
 
     format.setMaximumFractionDigits(3);
 
-    sb.append("<table class=\"table table-bordered text-right\">\n<tr>");
+    sb.append("<table class=\"table table-bordered text-right"+(isSortable? " 
sortable" : "")+"\">\n<thead><tr>");
     for (int i = 0; i < columns.length; i++) {
       String cn = columns[i];
       String ctt = "";
@@ -51,7 +55,7 @@ public class TableBuilder {
       }
       sb.append("<th" + ctt + ">" + cn + "</th>");
     }
-    sb.append("</tr>\n");
+    sb.append("</tr></thead>\n<tbody>\n");
   }
 
   public void appendCell(final String s) {
@@ -208,7 +212,7 @@ public class TableBuilder {
 
   public String build() {
     String rv;
-    rv = sb.append("\n</table>").toString();
+    rv = sb.append("\n</tbody>\n</table>").toString();
     sb = null;
     return rv;
   }

http://git-wip-us.apache.org/repos/asf/drill/blob/bec436f8/exec/java-exec/src/main/resources/rest/profile/profile.ftl
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/resources/rest/profile/profile.ftl 
b/exec/java-exec/src/main/resources/rest/profile/profile.ftl
index 9318afc..468297e 100644
--- a/exec/java-exec/src/main/resources/rest/profile/profile.ftl
+++ b/exec/java-exec/src/main/resources/rest/profile/profile.ftl
@@ -14,12 +14,35 @@
 <script src="/static/js/d3.v3.js"></script>
 <script src="/static/js/dagre-d3.min.js"></script>
 <script src="/static/js/graph.js"></script>
+<script src="/static/js/jquery.dataTables-1.10.16.min.js"></script>
+
 <script>
     var globalconfig = {
         "queryid" : "${model.getQueryId()}",
         "operators" : ${model.getOperatorsJSON()?no_esc}
     };
+
+    $(document).ready(function() {
+      $(".sortable").DataTable( {
+        "searching": false,
+        "lengthChange": false,
+        "paging": false,
+        "info": false
+      }
+    );} );
 </script>
+<style>
+/* DataTables Sorting: inherited via sortable class */
+table.sortable thead .sorting,.sorting_asc,.sorting_desc {
+  background-repeat: no-repeat;
+  background-position: center right;
+  cursor: pointer;
+}
+/* Sorting Symbols */
+table.sortable thead .sorting { background-image: 
url("/static/img/black-unsorted.gif"); }
+table.sortable thead .sorting_asc { background-image: 
url("/static/img/black-asc.gif"); }
+table.sortable thead .sorting_desc { background-image: 
url("/static/img/black-desc.gif"); }
+</style>
 </#macro>
 
 <#macro page_body>

http://git-wip-us.apache.org/repos/asf/drill/blob/bec436f8/exec/java-exec/src/main/resources/rest/static/img/black-asc.gif
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/resources/rest/static/img/black-asc.gif 
b/exec/java-exec/src/main/resources/rest/static/img/black-asc.gif
new file mode 100644
index 0000000..730533f
Binary files /dev/null and 
b/exec/java-exec/src/main/resources/rest/static/img/black-asc.gif differ

http://git-wip-us.apache.org/repos/asf/drill/blob/bec436f8/exec/java-exec/src/main/resources/rest/static/img/black-desc.gif
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/resources/rest/static/img/black-desc.gif 
b/exec/java-exec/src/main/resources/rest/static/img/black-desc.gif
new file mode 100644
index 0000000..4c3b610
Binary files /dev/null and 
b/exec/java-exec/src/main/resources/rest/static/img/black-desc.gif differ

http://git-wip-us.apache.org/repos/asf/drill/blob/bec436f8/exec/java-exec/src/main/resources/rest/static/img/black-unsorted.gif
----------------------------------------------------------------------
diff --git 
a/exec/java-exec/src/main/resources/rest/static/img/black-unsorted.gif 
b/exec/java-exec/src/main/resources/rest/static/img/black-unsorted.gif
new file mode 100644
index 0000000..5647f65
Binary files /dev/null and 
b/exec/java-exec/src/main/resources/rest/static/img/black-unsorted.gif differ

Reply via email to