You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by co...@apache.org on 2015/12/15 06:18:33 UTC

incubator-zeppelin git commit: Improve/split paragraph html

Repository: incubator-zeppelin
Updated Branches:
  refs/heads/master 8e4be1f65 -> 42100550f


Improve/split paragraph html

### What is this PR for?
This PR is the first step to divide the paragraph into smaller components.
In order to work gradually towards making paragraph.js more maintainable, this PR will focus only on splitting the HTML.

### What type of PR is it?
Refactoring

### Todos
* [x] - Split Pragraph HTML
* [x] - Split Notebook action bar HTML
* [x] - Fix some z-index problems
* [x] - Fix failing selenium test

### Is there a relevant Jira issue?
No

### How should this be tested?
* There wasn't any real code changes, just moving code, so you can just use Zeppelin Normally
* For the z-index fixes, you can check that the paragraph menu, progress bar and graph tooltip are not showing on top of the navbar and actionbar

### Screenshots (if appropriate)

### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No

Author: Damien CORNEAU <co...@gmail.com>
Author: Damien Corneau <co...@gmail.com>

Closes #324 from corneadoug/improve/SplitParagraphHtml and squashes the following commits:

01a2234 [Damien CORNEAU] Fix waitForParagraph xpath in selenium test
668d297 [Damien CORNEAU] Try bumping selenium wait time for waitParagraph
69ac2c6 [Damien CORNEAU] Add Header on new files
6d62852 [Damien CORNEAU] Fix Empty HTML result when slow page loading
ebdf0bd [Damien CORNEAU] Fix ActionBar Z-index after rebase broke it
186ae1e [Damien CORNEAU] Finish spliting paragraph + split notebook actionbar
be550ed [Damien Corneau] Add license in new files
125c02d [Damien Corneau] Fix z-index levels
f7df3ba [Damien Corneau] Fix z-index of for nvtooltip
74fdb49 [Damien Corneau] Fix z-index of paragraph settings and progressbar
09578fd [Damien Corneau] Separate progress Bar
400a7dc [Damien Corneau] Split Chart Selector and Paragraph Controls


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

Branch: refs/heads/master
Commit: 42100550f3b7aa092a139977a42893a95c086fcf
Parents: 8e4be1f
Author: Damien CORNEAU <co...@gmail.com>
Authored: Thu Dec 10 18:59:10 2015 +0900
Committer: Damien CORNEAU <co...@gmail.com>
Committed: Tue Dec 15 14:18:11 2015 +0900

----------------------------------------------------------------------
 .../java/org/apache/zeppelin/ZeppelinIT.java    |  12 +-
 .../src/app/notebook/notebook-actionBar.html    | 135 ++++++
 zeppelin-web/src/app/notebook/notebook.css      |   7 +-
 zeppelin-web/src/app/notebook/notebook.html     | 124 +-----
 .../paragraph/paragraph-chart-selector.html     |  49 +++
 .../notebook/paragraph/paragraph-control.html   |  90 ++++
 .../app/notebook/paragraph/paragraph-graph.html |  55 +++
 .../paragraph/paragraph-graphOptions.html       |  31 ++
 .../paragraph-parameterizedQueryForm.html       |  40 ++
 .../app/notebook/paragraph/paragraph-pivot.html | 168 +++++++
 .../paragraph/paragraph-progressBar.html        |  22 +
 .../notebook/paragraph/paragraph-results.html   |  47 ++
 .../notebook/paragraph/paragraph.controller.js  |   5 +-
 .../src/app/notebook/paragraph/paragraph.css    |   6 +-
 .../src/app/notebook/paragraph/paragraph.html   | 435 +------------------
 .../src/assets/styles/looknfeel/default.css     |   1 -
 16 files changed, 663 insertions(+), 564 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java
index 2b2f233..bbba084 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java
@@ -137,7 +137,7 @@ public class ZeppelinIT {
     (new WebDriverWait(driver, 60)).until(new ExpectedCondition<Boolean>() {
       public Boolean apply(WebDriver d) {
         return driver.findElement(By.xpath(getParagraphXPath(paragraphNo)
-            + "//div[@class='control']//span[1][contains(.,'" + state + "')]"))
+            + "//div[contains(@class, 'control')]//span[1][contains(.,'" + state + "')]"))
             .isDisplayed();
       }
 
@@ -211,7 +211,7 @@ public class ZeppelinIT {
      */
     WebElement paragraph3Editor = driver.findElement(By.xpath(getParagraphXPath(3) + "//textarea"));
     paragraph3Editor.sendKeys(
-        "print" + Keys.chord(Keys.SHIFT, "9") + "\"myVar=\"" + Keys.chord(Keys.ADD) 
+        "print" + Keys.chord(Keys.SHIFT, "9") + "\"myVar=\"" + Keys.chord(Keys.ADD)
         + "z.angular" + Keys.chord(Keys.SHIFT, "9") + "\"myVar\"))");
     paragraph3Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER));
     waitForParagraph(3, "FINISHED");
@@ -239,7 +239,7 @@ public class ZeppelinIT {
     WebElement paragraph4Editor = driver.findElement(By.xpath(getParagraphXPath(4) + "//textarea"));
     paragraph4Editor.sendKeys(
         "z.angularWatch" + Keys.chord(Keys.SHIFT, "9") + "\"myVar\", "
-        + Keys.chord(Keys.SHIFT, "9") 
+        + Keys.chord(Keys.SHIFT, "9")
         + "before:Object, after:Object, context:org.apache.zeppelin.interpreter.InterpreterContext)"
         + Keys.EQUALS + ">{ z.run" +Keys.chord(Keys.SHIFT, "9") + "2, context)}");
     paragraph4Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER));
@@ -291,12 +291,12 @@ public class ZeppelinIT {
 
   private void createNewNote() {
     List<WebElement> notebookLinks = driver.findElements(By
-        .xpath("//div[contains(@class, \"col-md-4\")]/div/ul/li"));    
+        .xpath("//div[contains(@class, \"col-md-4\")]/div/ul/li"));
     List<String> notebookTitles = new LinkedList<String>();
     for (WebElement el : notebookLinks) {
       notebookTitles.add(el.getText());
     }
-    
+
     WebElement createNoteLink = driver.findElement(By.xpath("//div[contains(@class, \"col-md-4\")]/div/h5/a[contains(.,'Create new note')]"));
     createNoteLink.click();
 
@@ -308,6 +308,6 @@ public class ZeppelinIT {
     try {
       Thread.sleep(500); // wait for notebook list updated
     } catch (InterruptedException e) {
-    } 
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/notebook-actionBar.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html
new file mode 100644
index 0000000..f9239f1
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html
@@ -0,0 +1,135 @@
+<!--
+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.
+-->
+<div class="noteAction" ng-show="note.id && !paragraphUrl">
+  <h3>
+    <input type="text" pu-elastic-input class="form-control2" placeholder="{{note.name || 'Note ' + note.id}}" style="min-width: 200px; max-width: 600px;"
+           ng-show="showEditor" ng-model="note.name" ng-blur="sendNewName()" ng-enter="sendNewName()" ng-escape="note.name = oldName; showEditor = false" focus-if="showEditor" />
+    <p class="form-control-static2" ng-click="showEditor = true; oldName = note.name" ng-show="!showEditor">{{note.name || 'Note ' + note.id}}</p>
+    <span class="labelBtn btn-group">
+      <button type="button"
+              class="btn btn-default btn-xs"
+              ng-click="runNote()"
+              ng-class="{'disabled':isNoteRunning()}"
+              tooltip-placement="bottom" tooltip="Run all the notes">
+        <i class="icon-control-play"></i>
+      </button>
+      <button type="button"
+              class="btn btn-default btn-xs"
+              ng-click="toggleAllEditor()"
+              ng-hide="viewOnly"
+              tooltip-placement="bottom" tooltip="Show/hide the code">
+        <i ng-class="editorToggled ?  'fa icon-size-fullscreen' :'fa icon-size-actual'"></i></button>
+      <button type="button"
+              class="btn btn-default btn-xs"
+              ng-click="toggleAllTable()"
+              ng-hide="viewOnly"
+              tooltip-placement="bottom" tooltip="Show/hide the output">
+        <i ng-class="tableToggled ? 'fa icon-notebook' : 'fa icon-book-open'"></i>
+      </button>
+      <button type="button"
+              class="btn btn-default btn-xs"
+              ng-click="clearAllParagraphOutput()"
+              ng-hide="viewOnly"
+              ng-class="{'disabled':isNoteRunning()}"
+              tooltip-placement="bottom" tooltip="Clear output">
+        <i class="fa fa-eraser"></i>
+      </button>
+      <button type="button"
+              class="btn btn-default btn-xs"
+              ng-click="removeNote(note.id)"
+              ng-hide="viewOnly"
+              tooltip-placement="bottom" tooltip="Remove the notebook">
+        <i class="icon-trash"></i>
+      </button>
+      <button type="button"
+              class="btn btn-default btn-xs"
+              ng-hide="viewOnly"
+              tooltip-placement="bottom" tooltip="Clone the notebook"
+              data-toggle="modal" data-target="#noteNameModal" data-clone="true"
+              >
+        <i class="fa fa-copy"></i>
+      </button>
+      <button type="button"
+              class="btn btn-default btn-xs"
+              ng-hide="viewOnly"
+              ng-click="exportNotebook()"
+              tooltip-placement="bottom" tooltip="Export the notebook">
+        <i class="fa fa-download"></i>
+      </button>
+    </span>
+
+    <span ng-hide="viewOnly">
+      <div class="labelBtn btn-group">
+        <div class="btn btn-default btn-xs dropdown-toggle"
+             type="button"
+             data-toggle="dropdown"
+             ng-class="{ 'btn-info' : note.config.cron, 'btn-danger' : note.info.cron, 'btn-default' : !note.config.cron}"
+             tooltip-placement="bottom" tooltip="Run scheduler">
+          <span class="fa fa-clock-o"></span> {{getCronOptionNameFromValue(note.config.cron)}}
+        </div>
+        <ul class="dropdown-menu" role="menu" style="width:300px">
+          <li>
+            <div class="cron-preset-container">
+              Run note with cron scheduler.
+              Either choose from<br/>preset or write your own <a href="http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger" target=_blank>cron expression</a>.
+              <div>
+                <span>- Preset</span>
+                <a class="cron-preset" ng-repeat="cr in cronOption"
+                   type="button"
+                   ng-click="setCronScheduler(cr.value)"
+                   dropdown-input ng-class="{ 'selected' : cr.value == note.config.cron}">{{cr.name}}</a>
+              </div>
+              <div>
+                <span>- Cron expression</span>
+                <input type="text"
+                       ng-model="note.config.cron"
+                       ng-change="setCronScheduler(note.config.cron)"
+                       dropdown-input ng-model-options="{ debounce: 1000 }" />
+                <p ng-show="note.info.cron" class="text-danger cron-info">
+                  {{note.info.cron}}
+                </p>
+              </div>
+            </div>
+          </li>
+        </ul>
+      </div>
+    </span>
+
+    <div class="pull-right" style="margin-top:15px; margin-right:15px; font-size:15px;">
+      <span style="position:relative; top:3px; margin-right:4px; cursor:pointer"
+            data-toggle="modal"
+            data-target="#shortcutModal"
+            tooltip-placement="bottom" tooltip="List of shortcut">
+        <i class="icon-question"></i>
+      </span>
+      <span style="position:relative; top:2px; margin-right:4px; cursor:pointer;"
+            ng-click="toggleSetting()"
+            tooltip-placement="bottom" tooltip="Interpreter binding">
+        <i class="fa fa-cog" ng-style="{color: showSetting ? '#3071A9' : 'black' }"></i>
+      </span>
+
+      <span class="btn-group">
+        <button type="button" class="btn btn-default btn-xs dropdown-toggle"
+                data-toggle="dropdown">
+          {{note.config.looknfeel}} <span class="caret"></span>
+        </button>
+        <ul class="dropdown-menu pull-right" role="menu">
+          <li ng-repeat="looknfeel in looknfeelOption">
+            <a style="cursor:pointer" ng-click="setLookAndFeel(looknfeel)">{{looknfeel}}</a>
+          </li>
+        </ul>
+      </span>
+    </div>
+  </h3>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/notebook.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook.css b/zeppelin-web/src/app/notebook/notebook.css
index c7b7a78..8c37e3b 100644
--- a/zeppelin-web/src/app/notebook/notebook.css
+++ b/zeppelin-web/src/app/notebook/notebook.css
@@ -74,6 +74,11 @@
   pointer-events: none;
 }
 
+.navbar-fixed-top,
+.navbar-fixed-top .dropdown-menu {
+  z-index: 10002;
+}
+
 .noteAction {
   margin-left: -10px;
   margin-right: -10px;
@@ -83,7 +88,7 @@
   top: 50px;
   width: 100%;
   height: 54px;
-  z-index: 3;
+  z-index: 10001;
 }
 
 .noteAction h3 {

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/notebook.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook.html b/zeppelin-web/src/app/notebook/notebook.html
index 9679ac5..227f8cd 100644
--- a/zeppelin-web/src/app/notebook/notebook.html
+++ b/zeppelin-web/src/app/notebook/notebook.html
@@ -12,129 +12,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 -->
 <!-- Here the controller <NotebookCtrl> is not needed because explicitly set in the app.js (route) -->
-<div class="noteAction" ng-show="note.id && !paragraphUrl">
-  <h3>
-    <input type="text" pu-elastic-input class="form-control2" placeholder="{{note.name || 'Note ' + note.id}}" style="min-width: 200px; max-width: 600px;"
-           ng-show="showEditor" ng-model="note.name" ng-blur="sendNewName()" ng-enter="sendNewName()" ng-escape="note.name = oldName; showEditor = false" focus-if="showEditor" />
-    <p class="form-control-static2" ng-click="showEditor = true; oldName = note.name" ng-show="!showEditor">{{note.name || 'Note ' + note.id}}</p>
-    <span class="labelBtn btn-group">
-      <button type="button"
-              class="btn btn-default btn-xs"
-              ng-click="runNote()"
-              ng-class="{'disabled':isNoteRunning()}"
-              tooltip-placement="bottom" tooltip="Run all the notes">
-        <i class="icon-control-play"></i>
-      </button>
-      <button type="button"
-              class="btn btn-default btn-xs"
-              ng-click="toggleAllEditor()"
-              ng-hide="viewOnly"
-              tooltip-placement="bottom" tooltip="Show/hide the code">
-        <i ng-class="editorToggled ?  'fa icon-size-fullscreen' :'fa icon-size-actual'"></i></button>
-      <button type="button"
-              class="btn btn-default btn-xs"
-              ng-click="toggleAllTable()"
-              ng-hide="viewOnly"
-              tooltip-placement="bottom" tooltip="Show/hide the output">
-        <i ng-class="tableToggled ? 'fa icon-notebook' : 'fa icon-book-open'"></i>
-      </button>
-      <button type="button"
-              class="btn btn-default btn-xs"
-              ng-click="clearAllParagraphOutput()"
-              ng-hide="viewOnly"
-              ng-class="{'disabled':isNoteRunning()}"
-              tooltip-placement="bottom" tooltip="Clear output">
-        <i class="fa fa-eraser"></i>
-      </button>
-      <button type="button"
-              class="btn btn-default btn-xs"
-              ng-click="removeNote(note.id)"
-              ng-hide="viewOnly"
-              tooltip-placement="bottom" tooltip="Remove the notebook">
-        <i class="icon-trash"></i>
-      </button>
-      <button type="button"
-              class="btn btn-default btn-xs"
-              ng-hide="viewOnly"
-              tooltip-placement="bottom" tooltip="Clone the notebook"
-              data-toggle="modal" data-target="#noteNameModal" data-clone="true"
-              >
-        <i class="fa fa-copy"></i>
-      </button>
-      <button type="button"
-              class="btn btn-default btn-xs"
-              ng-hide="viewOnly"
-              ng-click="exportNotebook()"
-              tooltip-placement="bottom" tooltip="Export the notebook">
-        <i class="fa fa-download"></i>
-      </button>
-    </span>
-
-    <span ng-hide="viewOnly">
-      <div class="labelBtn btn-group">
-        <div class="btn btn-default btn-xs dropdown-toggle"
-             type="button"
-             data-toggle="dropdown"
-             ng-class="{ 'btn-info' : note.config.cron, 'btn-danger' : note.info.cron, 'btn-default' : !note.config.cron}"
-             tooltip-placement="bottom" tooltip="Run scheduler">
-          <span class="fa fa-clock-o"></span> {{getCronOptionNameFromValue(note.config.cron)}}
-        </div>
-        <ul class="dropdown-menu" role="menu" style="width:300px">
-          <li>
-            <div class="cron-preset-container">
-              Run note with cron scheduler.
-              Either choose from<br/>preset or write your own <a href="http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger" target=_blank>cron expression</a>.
-              <div>
-                <span>- Preset</span>
-                <a class="cron-preset" ng-repeat="cr in cronOption"
-                   type="button"
-                   ng-click="setCronScheduler(cr.value)"
-                   dropdown-input ng-class="{ 'selected' : cr.value == note.config.cron}">{{cr.name}}</a>
-              </div>
-              <div>
-                <span>- Cron expression</span>
-                <input type="text"
-                       ng-model="note.config.cron"
-                       ng-change="setCronScheduler(note.config.cron)"
-                       dropdown-input ng-model-options="{ debounce: 1000 }" />
-                <p ng-show="note.info.cron" class="text-danger cron-info">
-                  {{note.info.cron}}
-                </p>
-              </div>
-            </div>
-          </li>
-        </ul>
-      </div>
-    </span>
-
-    <div class="pull-right" style="margin-top:15px; margin-right:15px; font-size:15px;">
-      <span style="position:relative; top:3px; margin-right:4px; cursor:pointer"
-            data-toggle="modal"
-            data-target="#shortcutModal"
-            tooltip-placement="bottom" tooltip="List of shortcut">
-        <i class="icon-question"></i>
-      </span>
-      <span style="position:relative; top:2px; margin-right:4px; cursor:pointer;"
-            ng-click="toggleSetting()"
-            tooltip-placement="bottom" tooltip="Interpreter binding">
-        <i class="fa fa-cog" ng-style="{color: showSetting ? '#3071A9' : 'black' }"></i>
-      </span>
-
-      <span class="btn-group">
-        <button type="button" class="btn btn-default btn-xs dropdown-toggle"
-                data-toggle="dropdown">
-          {{note.config.looknfeel}} <span class="caret"></span>
-        </button>
-        <ul class="dropdown-menu pull-right" role="menu">
-          <li ng-repeat="looknfeel in looknfeelOption">
-            <a style="cursor:pointer" ng-click="setLookAndFeel(looknfeel)">{{looknfeel}}</a>
-          </li>
-        </ul>
-      </span>
-    </div>
-  </h3>
-</div>
-
+<div ng-include src="'app/notebook/notebook-actionBar.html'"></div>
 <div style="padding-top: 36px;">
   <!-- settings -->
   <div ng-if="showSetting" class="setting">

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph-chart-selector.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-chart-selector.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-chart-selector.html
new file mode 100644
index 0000000..b7ebbed
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-chart-selector.html
@@ -0,0 +1,49 @@
+<!--
+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.
+-->
+
+<div id="{{paragraph.id}}_switch"
+     ng-if="paragraph.result.type == 'TABLE' && !asIframe && !viewOnly"
+     class="btn-group"
+     style='margin-bottom: 10px;'>
+  <button type="button" class="btn btn-default btn-sm"
+          ng-class="{'active': isGraphMode('table')}"
+          ng-click="setGraphMode('table', true)" ><i class="fa fa-table"></i>
+  </button>
+  <button type="button" class="btn btn-default btn-sm"
+          ng-class="{'active': isGraphMode('multiBarChart')}"
+          ng-click="setGraphMode('multiBarChart', true)"><i class="fa fa-bar-chart"></i>
+  </button>
+  <button type="button" class="btn btn-default btn-sm"
+          ng-class="{'active': isGraphMode('pieChart')}"
+          ng-click="setGraphMode('pieChart', true)"><i class="fa fa-pie-chart"></i>
+  </button>
+  <button type="button" class="btn btn-default btn-sm"
+          ng-class="{'active': isGraphMode('stackedAreaChart')}"
+          ng-click="setGraphMode('stackedAreaChart', true)"><i class="fa fa-area-chart"></i>
+  </button>
+  <button type="button" class="btn btn-default btn-sm"
+          ng-class="{'active': isGraphMode('lineChart') || isGraphMode('lineWithFocusChart')}"
+          ng-click="paragraph.config.graph.lineWithFocus ? setGraphMode('lineWithFocusChart', true) : setGraphMode('lineChart', true)"><i class="fa fa-line-chart"></i>
+  </button>
+  <button type="button" class="btn btn-default btn-sm"
+          ng-class="{'active': isGraphMode('scatterChart')}"
+          ng-click="setGraphMode('scatterChart', true)"><i class="cf cf-scatter-chart"></i>
+  </button>
+</div>
+<span ng-if="getResultType()=='TABLE' && getGraphMode()!='table' && !asIframe && !viewOnly"
+      style="margin-left:10px; cursor:pointer; display: inline-block; vertical-align:top; position: relative; line-height:30px;">
+  <a class="btnText" ng-click="toggleGraphOption()">
+    settings <span ng-class="paragraph.config.graph.optionOpen ? 'fa fa-caret-up' : 'fa fa-caret-down'"></span>
+  </a>
+</span>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
new file mode 100644
index 0000000..f6bf9b4
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
@@ -0,0 +1,90 @@
+<!--
+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.
+-->
+
+<div id="{{paragraph.id}}_control" class="control" ng-show="!asIframe">
+
+  <span>
+    {{paragraph.status}}
+  </span>
+
+  <span ng-if="paragraph.status=='RUNNING'">
+    {{getProgress()}}%
+  </span>
+
+  <!-- Run / Cancel button -->
+  <span class="icon-control-play" style="cursor:pointer;color:#3071A9" tooltip-placement="top" tooltip="Run this paragraph (Shift+Enter)"
+        ng-click="runParagraph(getEditorValue())"
+        ng-show="paragraph.status!='RUNNING' && paragraph.status!='PENDING' && paragraph.config.enabled"></span>
+  <span class="icon-control-pause" style="cursor:pointer;color:#CD5C5C" tooltip-placement="top" tooltip="Cancel"
+        ng-click="cancelParagraph()"
+        ng-show="paragraph.status=='RUNNING' || paragraph.status=='PENDING'"></span>
+  <span class="{{paragraph.config.editorHide ? 'icon-size-fullscreen' : 'icon-size-actual'}}" style="cursor:pointer;" tooltip-placement="top" tooltip="{{(paragraph.config.editorHide ? 'Show' : 'Hide') + ' editor'}}"
+        ng-click="toggleEditor()"></span>
+  <span class="{{paragraph.config.tableHide ? 'icon-notebook' : 'icon-book-open'}}" style="cursor:pointer;" tooltip-placement="top" tooltip="{{(paragraph.config.tableHide ? 'Show' : 'Hide') + ' output'}}"
+        ng-click="toggleOutput()"></span>
+  <span class="dropdown navbar-right">
+    <span class="icon-settings" style="cursor:pointer"
+          data-toggle="dropdown"
+          type="button">
+    </span>
+    <ul class="dropdown-menu" role="menu" style="width:200px;">
+      <li>
+        <a ng-click="$event.stopPropagation()" class="dropdown"><span class="fa fa-arrows-h"></span> Width
+          <form style="display:inline; margin-left:5px;">
+            <select ng-model="paragraph.config.colWidth"
+                    class="selectpicker"
+                    ng-change="changeColWidth()"
+                    ng-options="col for col in colWidthOption"></select>
+          </form>
+        </a>
+      </li>
+      <li>
+        <a ng-click="moveUp()"><span class="icon-arrow-up"></span> Move Up</a>
+      </li>
+      <li>
+        <a ng-click="moveDown()"><span class="icon-arrow-down"></span> Move Down</a>
+      </li>
+      <li>
+        <a ng-click="insertNew()"><span class="icon-plus"></span> Insert New</a>
+      </li>
+      <li>
+        <!-- paragraph handler -->
+        <a ng-click="hideTitle()"
+           ng-show="paragraph.config.title"><span class="fa fa-font"></span> Hide title</a>
+        <a ng-click="showTitle()"
+           ng-show="!paragraph.config.title"><span class="fa fa-font"></span> Show title</a>
+      </li>
+      <li>
+        <a ng-click="hideLineNumbers()"
+           ng-show="paragraph.config.lineNumbers"><span class="fa fa-list-ol"></span> Hide line numbers</a>
+        <a ng-click="showLineNumbers()"
+           ng-show="!paragraph.config.lineNumbers"><span class="fa fa-list-ol"></span> Show line numbers</a>
+      </li>
+      <li>
+        <a ng-click="toggleEnableDisable()"><span class="icon-control-play"></span>
+          {{paragraph.config.enabled ? "Disable" : "Enable"}} run</a>
+      </li>
+      <li>
+        <a ng-click="goToSingleParagraph()"><span class="icon-share-alt"></span> Link this paragraph</a>
+      </li>
+      <li>
+        <a ng-click="clearParagraphOutput()"><span class="fa fa-eraser"></span> Clear output</a>
+      </li>
+      <li>
+        <!-- remove paragraph -->
+        <a ng-click="removeParagraph()"><span class="fa fa-times"></span> Remove</a>
+      </li>
+    </ul>
+  </span>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph-graph.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-graph.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-graph.html
new file mode 100644
index 0000000..e72ad0e
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-graph.html
@@ -0,0 +1,55 @@
+<!--
+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.
+-->
+<div id="p{{paragraph.id}}_graph"
+     class="graphContainer"
+     ng-class="{'noOverflow': getGraphMode()=='table'}"
+     ng-if="getResultType()=='TABLE'"
+     allowresize="{{!asIframe && !viewOnly}}"
+     resizable on-resize="setGraphHeight();">
+
+  <div ng-if="getGraphMode()=='table'"
+       id="p{{paragraph.id}}_table"
+       class="table">
+  </div>
+
+  <div ng-if="getGraphMode()=='multiBarChart'"
+       id="p{{paragraph.id}}_multiBarChart">
+    <svg></svg>
+  </div>
+
+  <div ng-if="getGraphMode()=='pieChart'"
+       id="p{{paragraph.id}}_pieChart">
+    <svg></svg>
+  </div>
+
+  <div ng-if="getGraphMode()=='stackedAreaChart'"
+       id="p{{paragraph.id}}_stackedAreaChart">
+    <svg></svg>
+  </div>
+
+  <div ng-if="getGraphMode()=='lineChart'"
+       id="p{{paragraph.id}}_lineChart">
+    <svg></svg>
+  </div>
+
+  <div ng-if="getGraphMode()=='lineWithFocusChart'"
+       id="p{{paragraph.id}}_lineWithFocusChart">
+    <svg></svg>
+  </div>
+
+  <div ng-if="getGraphMode()=='scatterChart'"
+       id="p{{paragraph.id}}_scatterChart">
+    <svg></svg>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph-graphOptions.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-graphOptions.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-graphOptions.html
new file mode 100644
index 0000000..d4df1a4
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-graphOptions.html
@@ -0,0 +1,31 @@
+<!--
+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.
+-->
+<div>
+  <div ng-if="isGraphMode('lineChart') || isGraphMode('lineWithFocusChart')">
+    <label>
+      <input type="checkbox"
+             ng-model="paragraph.config.graph.forceY"
+             ng-click="onGraphOptionChange()">
+      force Y to 0
+    </label>
+    <br/>
+
+    <label>
+      <input type="checkbox"
+             ng-model="paragraph.config.graph.lineWithFocus"
+             ng-click="toggleLineWithFocus()">
+      show line chart with focus
+    </label>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html
new file mode 100644
index 0000000..bbcf764
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-parameterizedQueryForm.html
@@ -0,0 +1,40 @@
+<!--
+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.
+-->
+<form id="{{paragraph.id}}_form" role="form"
+      ng-show="!paragraph.config.tableHide"
+      class=" paragraphForm form-horizontal row">
+  <div class="form-group col-sm-6 col-md-6 col-lg-4"
+       ng-repeat="formulaire in paragraph.settings.forms"
+       ng-Init="loadForm(formulaire, paragraph.settings.params)">
+    <label class="control-label input-sm" ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }">{{formulaire.name}}</label>
+    <div>
+
+      <input class="form-control input-sm"
+             ng-if="!paragraph.settings.forms[formulaire.name].options"
+             ng-enter="runParagraph(getEditorValue())"
+             ng-model="paragraph.settings.params[formulaire.name]"
+             ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
+             name="{{formulaire.name}}" />
+
+      <select class="form-control input-sm"
+             ng-if="paragraph.settings.forms[formulaire.name].options"
+             ng-change="runParagraph(getEditorValue())"
+             ng-model="paragraph.settings.params[formulaire.name]"
+             ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
+             name="{{formulaire.name}}"
+             ng-options="option.value as (option.displayName||option.value) for option in paragraph.settings.forms[formulaire.name].options">
+      </select>
+    </div>
+  </div>
+</form>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph-pivot.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-pivot.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-pivot.html
new file mode 100644
index 0000000..66f570b
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-pivot.html
@@ -0,0 +1,168 @@
+<!--
+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.
+-->
+<div class="option lightBold" style="overflow: visible;"
+   ng-if="getResultType()=='TABLE' && getGraphMode()!='table'
+   && paragraph.config.graph.optionOpen && !asIframe && !viewOnly">
+
+  <div ng-include src="'app/notebook/paragraph/paragraph-graphOptions.html'"></div>
+
+  All fields:
+  <div class="allFields row">
+    <ul class="noDot">
+      <li class="liVertical" ng-repeat="col in paragraph.result.columnNames">
+        <div class="btn btn-default btn-xs"
+             data-drag="true"
+             data-jqyoui-options="{revert: 'invalid', helper: 'clone'}"
+             ng-model="paragraph.result.columnNames"
+             jqyoui-draggable="{index: {{$index}}, placeholder: 'keep'}">
+           {{col.name | limitTo: 30}}{{col.name.length > 30 ? '...' : ''}}
+        </div>
+      </li>
+    </ul>
+  </div>
+
+  <div class="row" ng-if="getGraphMode()!='scatterChart'">
+    <div class="col-md-4">
+      <span class="columns lightBold">
+        Keys
+        <ul data-drop="true"
+            ng-model="paragraph.config.graph.keys"
+            jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
+            class="list-unstyled">
+          <li ng-repeat="item in paragraph.config.graph.keys">
+            <div class="btn btn-primary btn-xs">
+              {{item.name}} <span class="fa fa-close" ng-click="removeGraphOptionKeys($index)"></span>
+            </div>
+          </li>
+        </ul>
+      </span>
+    </div>
+    <div class="col-md-4">
+      <span class="columns lightBold">
+        Groups
+        <ul data-drop="true"
+            ng-model="paragraph.config.graph.groups"
+            jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
+            class="list-unstyled">
+          <li ng-repeat="item in paragraph.config.graph.groups">
+            <div class="btn btn-success btn-xs">
+              {{item.name}} <span class="fa fa-close" ng-click="removeGraphOptionGroups($index)"></span>
+            </div>
+          </li>
+        </ul>
+      </span>
+    </div>
+    <div class="col-md-4">
+      <span class="columns lightBold">
+        Values
+        <ul data-drop="true"
+            ng-model="paragraph.config.graph.values"
+            jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
+            class="list-unstyled">
+          <li ng-repeat="item in paragraph.config.graph.values">
+            <div class="btn-group">
+              <div class="btn btn-info btn-xs dropdown-toggle"
+                   type="button"
+                   data-toggle="dropdown">
+                {{item.name | limitTo: 30}}{{item.name.length > 30 ? '...' : ''}}
+                <font style="color:#EEEEEE;"><span class="lightBold" style="text-transform: uppercase;">{{item.aggr}}</span></font>
+                <span class="fa fa-close" ng-click="removeGraphOptionValues($index)"></span>
+              </div>
+              <ul class="dropdown-menu" role="menu">
+                <li ng-click="setGraphOptionValueAggr($index, 'sum')"><a>sum</a></li>
+                <li ng-click="setGraphOptionValueAggr($index, 'count')"><a>count</a></li>
+                <li ng-click="setGraphOptionValueAggr($index, 'avg')"><a>avg</a></li>
+                <li ng-click="setGraphOptionValueAggr($index, 'min')"><a>min</a></li>
+                <li ng-click="setGraphOptionValueAggr($index, 'max')"><a>max</a></li>
+              </ul>
+            </div>
+          </li>
+        </ul>
+      </span>
+    </div>
+  </div>
+
+  <div class="row" ng-if="getGraphMode()=='scatterChart'">
+    <div class="col-md-3">
+      <span class="columns lightBold">
+        xAxis
+        <ul data-drop="true"
+            ng-model="paragraph.config.graph.scatter.xAxis"
+            jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
+            class="list-unstyled"
+            style="height:36px">
+          <li ng-if="paragraph.config.graph.scatter.xAxis">
+            <div class="btn btn-primary btn-xs">
+              {{paragraph.config.graph.scatter.xAxis.name}} <span class="fa fa-close" ng-click="removeScatterOptionXaxis($index)"></span>
+            </div>
+          </li>
+        </ul>
+      </span>
+    </div>
+    <div class="col-md-3">
+      <span class="columns lightBold">
+        yAxis
+        <ul data-drop="true"
+            ng-model="paragraph.config.graph.scatter.yAxis"
+            jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
+            class="list-unstyled"
+            style="height:36px">
+          <li ng-if="paragraph.config.graph.scatter.yAxis">
+            <div class="btn btn-success btn-xs">
+              {{paragraph.config.graph.scatter.yAxis.name}} <span class="fa fa-close" ng-click="removeScatterOptionYaxis($index)"></span>
+            </div>
+          </li>
+        </ul>
+      </span>
+    </div>
+    <div class="col-md-3">
+      <span class="columns lightBold">
+        group
+        <ul data-drop="true"
+            ng-model="paragraph.config.graph.scatter.group"
+            jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
+            class="list-unstyled"
+            style="height:36px">
+          <li ng-if="paragraph.config.graph.scatter.group">
+            <div class="btn btn-info btn-xs">
+              {{paragraph.config.graph.scatter.group.name}} <span class="fa fa-close" ng-click="removeScatterOptionGroup($index)"></span>
+            </div>
+          </li>
+        </ul>
+      </span>
+    </div>
+    <div class="col-md-3">
+      <span class="columns lightBold">
+        size
+        <a tabindex="0" class="fa fa-info-circle" role="button" popover-placement="top"
+           popover-trigger="focus"
+           popover-html-unsafe="<li>Size option is valid only when you drop numeric field here.</li>
+                                <li>When data in each axis are discrete, 'number of values in corresponding coordinate' will be used as size.</li>
+                                <li>Zeppelin consider values as discrete when the values contain string value or the number of distinct values are bigger than 5% of total number of values.</li>
+                                <li>Size field button turns to grey when the option you chose is not valid.</li>"></a>
+        <ul data-drop="true"
+            ng-model="paragraph.config.graph.scatter.size"
+            jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
+            class="list-unstyled"
+            style="height:36px">
+          <li ng-if="paragraph.config.graph.scatter.size">
+            <div class="btn btn-xs" style="color:white" ng-class="{'btn-warning': isValidSizeOption(paragraph.config.graph.scatter, paragraph.result.rows)}">
+              {{paragraph.config.graph.scatter.size.name}} <span class="fa fa-close" ng-click="removeScatterOptionSize($index)"></span>
+            </div>
+          </li>
+        </ul>
+      </span>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph-progressBar.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-progressBar.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-progressBar.html
new file mode 100644
index 0000000..010cea7
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-progressBar.html
@@ -0,0 +1,22 @@
+<!--
+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.
+-->
+
+<div id="{{paragraph.id}}_runControl" class="runControl" ng-show="paragraph.status=='RUNNING'">
+  <div id="{{paragraph.id}}_progress" class="progress">
+      <div ng-if="getProgress()>0 && getProgress()<100 && paragraph.status=='RUNNING'"
+        class="progress-bar" role="progressbar" style="width:{{getProgress()}}%;"></div>
+      <div ng-if="(getProgress()<=0 || getProgress()>=100) && (paragraph.status=='RUNNING' )"
+          class="progress-bar progress-bar-striped active" role="progressbar" style="width:100%;"></div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph-results.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-results.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-results.html
new file mode 100644
index 0000000..7980d72
--- /dev/null
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-results.html
@@ -0,0 +1,47 @@
+<!--
+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.
+-->
+<div ng-include src="'app/notebook/paragraph/paragraph-graph.html'"></div>
+
+<div id="{{paragraph.id}}_comment"
+     class="text"
+     ng-if="getResultType()=='TABLE' && paragraph.result.comment"
+     ng-bind-html="paragraph.result.comment">
+</div>
+
+<div id="{{paragraph.id}}_text"
+     class="text"
+     ng-if="paragraph.result.type == 'TEXT'"
+     ng-bind="paragraph.result.msg">
+</div>
+
+<div id="p{{paragraph.id}}_html"
+     class="resultContained"
+     ng-if="paragraph.result.type == 'HTML'">
+</div>
+
+<div id="p{{paragraph.id}}_angular"
+     class="resultContained"
+     ng-if="paragraph.result.type == 'ANGULAR'">
+</div>
+
+<img id="{{paragraph.id}}_img"
+     ng-if="paragraph.result.type == 'IMG'"
+     ng-src="{{getBase64ImageSrc(paragraph.result.msg)}}">
+</img>
+
+<div id="{{paragraph.id}}_error"
+     class="error"
+     ng-if="paragraph.status == 'ERROR'"
+     ng-bind="paragraph.errorMessage">
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
index 5aff815..1a91c27 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
@@ -67,10 +67,10 @@ angular.module('zeppelinWebApp')
           console.log('HTML rendering error %o', err);
         }
       } else {
+        $timeout(retryRenderer, 10);
       }
     };
     $timeout(retryRenderer);
-
   };
 
   $scope.renderAngular = function() {
@@ -84,11 +84,10 @@ angular.module('zeppelinWebApp')
           console.log('ANGULAR rendering error %o', err);
         }
       } else {
-        $timeout(retryRenderer,10);
+        $timeout(retryRenderer, 10);
       }
     };
     $timeout(retryRenderer);
-
   };
 
 

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.css b/zeppelin-web/src/app/notebook/paragraph/paragraph.css
index 6e370dd..392785b 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.css
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.css
@@ -142,7 +142,7 @@
   font-size: 1px;
   color: #AAAAAA;
   height:4px;
-  margin: 1px 0 0 0;
+  margin: 0px 0px 3px 0px;
 }
 
 .paragraph .runControl .progress {
@@ -153,10 +153,6 @@
   border-radius: 0;
 }
 
-.paragraph .runControl .progress .progress-bar {
-  z-index: 100;
-}
-
 .paragraph .control span {
     margin-left: 4px;
 }

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/app/notebook/paragraph/paragraph.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.html b/zeppelin-web/src/app/notebook/paragraph/paragraph.html
index cded6d8..043b6e8 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.html
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.html
@@ -35,7 +35,7 @@ limitations under the License.
   </div>
 
   <div>
-    <div ng-show="!paragraph.config.editorHide && !viewOnly">
+    <div ng-show="!paragraph.config.editorHide && !viewOnly" style="margin-bottom:3px;">
       <div id="{{paragraph.id}}_editor"
            style="opacity: 1;"
            class="editor"
@@ -50,438 +50,23 @@ limitations under the License.
       </div>
     </div>
 
-    <div id="{{paragraph.id}}_runControl" class="runControl">
-      <div ng-if="(getProgress()<=0 || getProgress()>=100) && (paragraph.status=='RUNNING' )">
-        <div id="{{paragraph.id}}_progress"
-             class="progress">
-            <div class="progress-bar progress-bar-striped active" role="progressbar" style="width:100%;"></div>
-          <span class="sr-only"></span>
-        </div>
-      </div>
-      <div ng-if="getProgress()>0 && getProgress()<100 && paragraph.status=='RUNNING'">
-        <div id="{{paragraph.id}}_progress"
-             class="progress">
-          <div class="progress-bar" role="progressbar" style="width:{{getProgress()}}%;"></div>
-          <span class="sr-only">{{getProgress()}}%</span>
-        </div>
-      </div>
-    </div>
-
-    <form id="{{paragraph.id}}_form" role="form"
-          ng-show="!paragraph.config.tableHide"
-          class=" paragraphForm form-horizontal row">
-      <div class="form-group col-sm-6 col-md-6 col-lg-4"
-           ng-repeat="formulaire in paragraph.settings.forms"
-           ng-Init="loadForm(formulaire, paragraph.settings.params)">
-        <label class="control-label input-sm" ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }">{{formulaire.name}}</label>
-        <div>
-
-          <input class="form-control input-sm"
-                 ng-if="!paragraph.settings.forms[formulaire.name].options"
-                 ng-enter="runParagraph(getEditorValue())"
-                 ng-model="paragraph.settings.params[formulaire.name]"
-                 ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
-                 name="{{formulaire.name}}">
-          </input>
-
-          <select class="form-control input-sm"
-                 ng-if="paragraph.settings.forms[formulaire.name].options"
-                 ng-change="runParagraph(getEditorValue())"
-                 ng-model="paragraph.settings.params[formulaire.name]"
-                 ng-class="{'disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' }"
-                 name="{{formulaire.name}}"
-                 ng-options="option.value as (option.displayName||option.value) for option in paragraph.settings.forms[formulaire.name].options"
-                 >
-<!--
-            <option
-                ng-repeat="option in paragraph.settings.forms[formulaire.name].options"
-                value="{{option.value}}"
-                >{{option.displayName || option.value}}
-            </option>
--->
-          </select>
-        </div>
-      </div>
-    </form>
+    <div ng-include src="'app/notebook/paragraph/paragraph-progressBar.html'"></div>
+    <div ng-include src="'app/notebook/paragraph/paragraph-parameterizedQueryForm.html'"></div>
 
     <!-- Rendering -->
     <div class='tableDisplay' ng-show="!paragraph.config.tableHide">
-      <div id="{{paragraph.id}}_switch"
-           ng-if="paragraph.result.type == 'TABLE' && !asIframe && !viewOnly"
-           class="btn-group"
-           style='margin-bottom: 10px;'>
-        <button type="button" class="btn btn-default btn-sm"
-                ng-class="{'active': isGraphMode('table')}"
-                ng-click="setGraphMode('table', true)" ><i class="fa fa-table"></i>
-        </button>
-        <button type="button" class="btn btn-default btn-sm"
-                ng-class="{'active': isGraphMode('multiBarChart')}"
-                ng-click="setGraphMode('multiBarChart', true)"><i class="fa fa-bar-chart"></i>
-        </button>
-        <button type="button" class="btn btn-default btn-sm"
-                ng-class="{'active': isGraphMode('pieChart')}"
-                ng-click="setGraphMode('pieChart', true)"><i class="fa fa-pie-chart"></i>
-        </button>
-        <button type="button" class="btn btn-default btn-sm"
-                ng-class="{'active': isGraphMode('stackedAreaChart')}"
-                ng-click="setGraphMode('stackedAreaChart', true)"><i class="fa fa-area-chart"></i>
-        </button>
-        <button type="button" class="btn btn-default btn-sm"
-                ng-class="{'active': isGraphMode('lineChart') || isGraphMode('lineWithFocusChart')}"
-                ng-click="paragraph.config.graph.lineWithFocus ? setGraphMode('lineWithFocusChart', true) : setGraphMode('lineChart', true)"><i class="fa fa-line-chart"></i>
-        </button>
-        <button type="button" class="btn btn-default btn-sm"
-                ng-class="{'active': isGraphMode('scatterChart')}"
-                ng-click="setGraphMode('scatterChart', true)"><i class="cf cf-scatter-chart"></i>
-        </button>
-      </div>
-      <span ng-if="getResultType()=='TABLE' && getGraphMode()!='table' && !asIframe && !viewOnly"
-            style="margin-left:10px; cursor:pointer; display: inline-block; vertical-align:top; position: relative; line-height:30px;">
-        <a ng-if="paragraph.config.graph.optionOpen"
-           ng-click="toggleGraphOption()">
-          settings <span class="fa fa-caret-up"></span>
-        </a>
-        <a ng-if="!paragraph.config.graph.optionOpen"
-           ng-click="toggleGraphOption()" >
-          settings <span class="fa fa-caret-down"></span>
-        </a>
-      </span>
-
-      <div class="option lightBold" style="overflow: visible;"
-         ng-if="getResultType()=='TABLE' && getGraphMode()!='table'
-         && paragraph.config.graph.optionOpen && !asIframe && !viewOnly">
-        <div ng-if="isGraphMode('lineChart') || isGraphMode('lineWithFocusChart')">
-          <label>
-            <input type="checkbox"
-                   ng-model="paragraph.config.graph.forceY"
-                   ng-click="onGraphOptionChange()">
-            force Y to 0
-          </label>
-          <br/>
-
-          <label>
-            <input type="checkbox"
-                   ng-model="paragraph.config.graph.lineWithFocus"
-                   ng-click="toggleLineWithFocus()">
-            show line chart with focus
-          </label>
-        </div>
-
-        All fields:
-        <div class="allFields row">
-          <ul class="noDot">
-            <li class="liVertical" ng-repeat="col in paragraph.result.columnNames">
-              <div class="btn btn-default btn-xs"
-                   data-drag="true"
-                   data-jqyoui-options="{revert: 'invalid', helper: 'clone'}"
-                   ng-model="paragraph.result.columnNames"
-                   jqyoui-draggable="{index: {{$index}}, placeholder: 'keep'}">
-                 {{col.name | limitTo: 30}}{{col.name.length > 30 ? '...' : ''}}
-              </div>
-            </li>
-          </ul>
-        </div>
-
-        <div class="row" ng-if="getGraphMode()!='scatterChart'">
-          <div class="col-md-4">
-            <span class="columns lightBold">
-              Keys
-              <ul data-drop="true"
-                  ng-model="paragraph.config.graph.keys"
-                  jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
-                  class="list-unstyled">
-                <li ng-repeat="item in paragraph.config.graph.keys">
-                  <div class="btn btn-primary btn-xs">
-                    {{item.name}} <span class="fa fa-close" ng-click="removeGraphOptionKeys($index)"></span>
-                  </div>
-                </li>
-              </ul>
-            </span>
-          </div>
-          <div class="col-md-4">
-            <span class="columns lightBold">
-              Groups
-              <ul data-drop="true"
-                  ng-model="paragraph.config.graph.groups"
-                  jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
-                  class="list-unstyled">
-                <li ng-repeat="item in paragraph.config.graph.groups">
-                  <div class="btn btn-success btn-xs">
-                    {{item.name}} <span class="fa fa-close" ng-click="removeGraphOptionGroups($index)"></span>
-                  </div>
-                </li>
-              </ul>
-            </span>
-          </div>
-          <div class="col-md-4">
-            <span class="columns lightBold">
-              Values
-              <ul data-drop="true"
-                  ng-model="paragraph.config.graph.values"
-                  jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
-                  class="list-unstyled">
-                <li ng-repeat="item in paragraph.config.graph.values">
-                  <div class="btn-group">
-                    <div class="btn btn-info btn-xs dropdown-toggle"
-                         type="button"
-                         data-toggle="dropdown">
-                      {{item.name | limitTo: 30}}{{item.name.length > 30 ? '...' : ''}}
-                      <font style="color:#EEEEEE;"><span class="lightBold" style="text-transform: uppercase;">{{item.aggr}}</span></font>
-                      <span class="fa fa-close" ng-click="removeGraphOptionValues($index)"></span>
-                    </div>
-                    <ul class="dropdown-menu" role="menu">
-                      <li ng-click="setGraphOptionValueAggr($index, 'sum')"><a>sum</a></li>
-                      <li ng-click="setGraphOptionValueAggr($index, 'count')"><a>count</a></li>
-                      <li ng-click="setGraphOptionValueAggr($index, 'avg')"><a>avg</a></li>
-                      <li ng-click="setGraphOptionValueAggr($index, 'min')"><a>min</a></li>
-                      <li ng-click="setGraphOptionValueAggr($index, 'max')"><a>max</a></li>
-                    </ul>
-                  </div>
-                </li>
-              </ul>
-            </span>
-          </div>
-        </div>
-
-        <div class="row" ng-if="getGraphMode()=='scatterChart'">
-          <div class="col-md-3">
-            <span class="columns lightBold">
-              xAxis
-              <ul data-drop="true"
-                  ng-model="paragraph.config.graph.scatter.xAxis"
-                  jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
-                  class="list-unstyled"
-                  style="height:36px">
-                <li ng-if="paragraph.config.graph.scatter.xAxis">
-                  <div class="btn btn-primary btn-xs">
-                    {{paragraph.config.graph.scatter.xAxis.name}} <span class="fa fa-close" ng-click="removeScatterOptionXaxis($index)"></span>
-                  </div>
-                </li>
-              </ul>
-            </span>
-          </div>
-          <div class="col-md-3">
-            <span class="columns lightBold">
-              yAxis
-              <ul data-drop="true"
-                  ng-model="paragraph.config.graph.scatter.yAxis"
-                  jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
-                  class="list-unstyled"
-                  style="height:36px">
-                <li ng-if="paragraph.config.graph.scatter.yAxis">
-                  <div class="btn btn-success btn-xs">
-                    {{paragraph.config.graph.scatter.yAxis.name}} <span class="fa fa-close" ng-click="removeScatterOptionYaxis($index)"></span>
-                  </div>
-                </li>
-              </ul>
-            </span>
-          </div>
-          <div class="col-md-3">
-            <span class="columns lightBold">
-              group
-              <ul data-drop="true"
-                  ng-model="paragraph.config.graph.scatter.group"
-                  jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
-                  class="list-unstyled"
-                  style="height:36px">
-                <li ng-if="paragraph.config.graph.scatter.group">
-                  <div class="btn btn-info btn-xs">
-                    {{paragraph.config.graph.scatter.group.name}} <span class="fa fa-close" ng-click="removeScatterOptionGroup($index)"></span>
-                  </div>
-                </li>
-              </ul>
-            </span>
-          </div>
-          <div class="col-md-3">
-            <span class="columns lightBold">
-              size
-              <a tabindex="0" class="fa fa-info-circle" role="button" popover-placement="top"
-                 popover-trigger="focus"
-                 popover-html-unsafe="<li>Size option is valid only when you drop numeric field here.</li>
-                                      <li>When data in each axis are discrete, 'number of values in corresponding coordinate' will be used as size.</li>
-                                      <li>Zeppelin consider values as discrete when the values contain string value or the number of distinct values are bigger than 5% of total number of values.</li>
-                                      <li>Size field button turns to grey when the option you chose is not valid.</li>"></a>
-              <ul data-drop="true"
-                  ng-model="paragraph.config.graph.scatter.size"
-                  jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
-                  class="list-unstyled"
-                  style="height:36px">
-                <li ng-if="paragraph.config.graph.scatter.size">
-                  <div class="btn btn-xs" style="color:white" ng-class="{'btn-warning': isValidSizeOption(paragraph.config.graph.scatter, paragraph.result.rows)}">
-                    {{paragraph.config.graph.scatter.size.name}} <span class="fa fa-close" ng-click="removeScatterOptionSize($index)"></span>
-                  </div>
-                </li>
-              </ul>
-            </span>
-          </div>
-        </div>
-
-      </div>
-
-
-      <div id="p{{paragraph.id}}_graph"
-           class="graphContainer"
-           ng-class="{'noOverflow': getGraphMode()=='table'}"
-           ng-if="getResultType()=='TABLE'"
-           allowresize="{{!asIframe && !viewOnly}}"
-           resizable on-resize="setGraphHeight();">
-
-        <div ng-if="getGraphMode()=='table'"
-             id="p{{paragraph.id}}_table"
-             class="table">
-        </div>
-
-        <div ng-if="getGraphMode()=='multiBarChart'"
-             id="p{{paragraph.id}}_multiBarChart">
-          <svg></svg>
-        </div>
-
-        <div ng-if="getGraphMode()=='pieChart'"
-             id="p{{paragraph.id}}_pieChart">
-          <svg></svg>
-        </div>
-
-        <div ng-if="getGraphMode()=='stackedAreaChart'"
-             id="p{{paragraph.id}}_stackedAreaChart">
-          <svg></svg>
-        </div>
-
-        <div ng-if="getGraphMode()=='lineChart'"
-             id="p{{paragraph.id}}_lineChart">
-          <svg></svg>
-        </div>
-
-        <div ng-if="getGraphMode()=='lineWithFocusChart'"
-             id="p{{paragraph.id}}_lineWithFocusChart">
-          <svg></svg>
-        </div>
-
-        <div ng-if="getGraphMode()=='scatterChart'"
-             id="p{{paragraph.id}}_scatterChart">
-          <svg></svg>
-        </div>
-      </div>
-
-      <div id="{{paragraph.id}}_comment"
-           class="text"
-           ng-if="getResultType()=='TABLE' && paragraph.result.comment"
-           ng-Init="loadResultType(paragraph.result)"
-           ng-bind-html="paragraph.result.comment">
-      </div>
-
-      <div id="{{paragraph.id}}_text"
-           class="text"
-           ng-if="paragraph.result.type == 'TEXT'"
-           ng-Init="loadResultType(paragraph.result)"
-           ng-bind="paragraph.result.msg">
-      </div>
-
-      <div id="p{{paragraph.id}}_html"
-           class="resultContained"
-           ng-if="paragraph.result.type == 'HTML'"
-           ng-Init="loadResultType(paragraph.result)">
-      </div>
-
-      <div id="p{{paragraph.id}}_angular"
-           class="resultContained"
-           ng-if="paragraph.result.type == 'ANGULAR'"
-           ng-Init="loadResultType(paragraph.result)">
-      </div>
-
-      <img id="{{paragraph.id}}_img"
-           ng-if="paragraph.result.type == 'IMG'"
-           ng-Init="loadResultType(paragraph.result)"
-           ng-src="{{getBase64ImageSrc(paragraph.result.msg)}}">
-      </img>
-
-      <div id="{{paragraph.id}}_error"
-           class="error"
-           ng-if="paragraph.status == 'ERROR'"
-           ng-bind="paragraph.errorMessage">
-      </div>
+      <div ng-include src="'app/notebook/paragraph/paragraph-chart-selector.html'"></div>
+      <div ng-include src="'app/notebook/paragraph/paragraph-pivot.html'"></div>
+      <div ng-include src="'app/notebook/paragraph/paragraph-results.html'"></div>
     </div>
   </div>
 
-  <div id="{{paragraph.id}}_control" class="control" ng-show="!asIframe">
-
-    <span>
-      {{paragraph.status}}
-    </span>
-
-    <span ng-if="paragraph.status=='RUNNING'">
-      {{getProgress()}}%
-    </span>
-
-    <!-- Run / Cancel button -->
-    <span class="icon-control-play" style="cursor:pointer;color:#3071A9" tooltip-placement="top" tooltip="Run this paragraph (Shift+Enter)"
-          ng-click="runParagraph(getEditorValue())"
-          ng-show="paragraph.status!='RUNNING' && paragraph.status!='PENDING' && paragraph.config.enabled"></span>
-    <span class="icon-control-pause" style="cursor:pointer;color:#CD5C5C" tooltip-placement="top" tooltip="Cancel"
-          ng-click="cancelParagraph()"
-          ng-show="paragraph.status=='RUNNING' || paragraph.status=='PENDING'"></span>
-    <span class="{{paragraph.config.editorHide ? 'icon-size-fullscreen' : 'icon-size-actual'}}" style="cursor:pointer;" tooltip-placement="top" tooltip="{{(paragraph.config.editorHide ? 'Show' : 'Hide') + ' editor'}}"
-          ng-click="toggleEditor()"></span>
-    <span class="{{paragraph.config.tableHide ? 'icon-notebook' : 'icon-book-open'}}" style="cursor:pointer;" tooltip-placement="top" tooltip="{{(paragraph.config.tableHide ? 'Show' : 'Hide') + ' output'}}"
-          ng-click="toggleOutput()"></span>
-    <span class="dropdown navbar-right">
-      <span class="icon-settings" style="cursor:pointer"
-            data-toggle="dropdown"
-            type="button">
-      </span>
-      <ul class="dropdown-menu" role="menu" style="width:200px;">
-        <li>
-          <a ng-click="$event.stopPropagation()" class="dropdown"><span class="fa fa-arrows-h"></span> Width
-            <form style="display:inline; margin-left:5px;">
-              <select ng-model="paragraph.config.colWidth"
-                      class="selectpicker"
-                      ng-change="changeColWidth()"
-                      ng-options="col for col in colWidthOption"></select>
-            </form>
-          </a>
-        </li>
-        <li>
-          <a ng-click="moveUp()"><span class="icon-arrow-up"></span> Move Up</a>
-        </li>
-        <li>
-          <a ng-click="moveDown()"><span class="icon-arrow-down"></span> Move Down</a>
-        </li>
-        <li>
-          <a ng-click="insertNew()"><span class="icon-plus"></span> Insert New</a>
-        </li>
-        <li>
-          <!-- paragraph handler -->
-          <a ng-click="hideTitle()"
-             ng-show="paragraph.config.title"><span class="fa fa-font"></span> Hide title</a>
-          <a ng-click="showTitle()"
-             ng-show="!paragraph.config.title"><span class="fa fa-font"></span> Show title</a>
-        </li>
-        <li>
-          <a ng-click="hideLineNumbers()"
-             ng-show="paragraph.config.lineNumbers"><span class="fa fa-list-ol"></span> Hide line numbers</a>
-          <a ng-click="showLineNumbers()"
-             ng-show="!paragraph.config.lineNumbers"><span class="fa fa-list-ol"></span> Show line numbers</a>
-        </li>
-        <li>
-          <a ng-click="toggleEnableDisable()"><span class="icon-control-play"></span>
-            {{paragraph.config.enabled ? "Disable" : "Enable"}} run</a>
-        </li>
-        <li>
-          <a ng-click="goToSingleParagraph()"><span class="icon-share-alt"></span> Link this paragraph</a>
-        </li>
-        <li>
-          <a ng-click="clearParagraphOutput()"><span class="fa fa-eraser"></span> Clear output</a>
-        </li>
-        <li>
-          <!-- remove paragraph -->
-          <a ng-click="removeParagraph()"><span class="fa fa-times"></span> Remove</a>
-        </li>
-      </ul>
-    </span>
-  </div>
+  <div ng-include src="'app/notebook/paragraph/paragraph-control.html'"></div>
 
   <div ng-if="!asIframe" class="paragraphFooter">
-    <div ng-show="!paragraph.config.tableHide && !viewOnly" id="{{paragraph.id}}_executionTime" class="executionTime" ng-bind-html="getExecutionTime()">
+    <div ng-show="!paragraph.config.tableHide && !viewOnly"
+         id="{{paragraph.id}}_executionTime"
+         class="executionTime" ng-bind-html="getExecutionTime()">
     </div>
   </div>
-
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/42100550/zeppelin-web/src/assets/styles/looknfeel/default.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/assets/styles/looknfeel/default.css b/zeppelin-web/src/assets/styles/looknfeel/default.css
index 10403a4..93d302a 100644
--- a/zeppelin-web/src/assets/styles/looknfeel/default.css
+++ b/zeppelin-web/src/assets/styles/looknfeel/default.css
@@ -20,7 +20,6 @@ body {
   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
   color: #2c3e50;
   border-bottom: 1px solid #E5E5E5;
-  z-index: 300;
 }
 
 .editor,