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 2016/05/16 15:10:39 UTC
incubator-zeppelin git commit: ZEPPELIN-830 Improve table display to
handle large data
Repository: incubator-zeppelin
Updated Branches:
refs/heads/master 8350e7802 -> 4eccfcd52
ZEPPELIN-830 Improve table display to handle large data
### What is this PR for?
This is an improvement for table display. By using [Handsontable](https://github.com/handsontable/handsontable) we can load and display more data in paragraphs. Tested using sample tabular data consisting 10000x80 cells
### What type of PR is it?
Improvement
### Todos
* [x] - Decimal formatting
* [x] - Rendering without angular/html directives
* [x] - UI fixes
* [x] - License doc update
### What is the Jira issue?
* https://issues.apache.org/jira/browse/ZEPPELIN-830
### How should this be tested?
TODO : test cases to follow
### Screenshots (if appropriate)
![apr 26 2016 17 38](https://cloud.githubusercontent.com/assets/2031306/14817566/c034ab28-0bd5-11e6-8b7a-2216ceca8153.gif)
### Questions:
* Does the licenses files need update? Yes
* Is there breaking changes for older versions? No
* Does this needs documentation? Maybe
Author: Renjith Kamath <re...@gmail.com>
Closes #858 from r-kamath/ZEPPELIN-830 and squashes the following commits:
f13ba91 [Renjith Kamath] Merge branch 'master' of https://github.com/apache/incubator-zeppelin into ZEPPELIN-830
dd0ced7 [Renjith Kamath] ZEPPELIN-830 fix wrong variable name
4fbb22b [Renjith Kamath] Merge branch 'master' of https://github.com/apache/incubator-zeppelin into ZEPPELIN-830
2e422ea [Renjith Kamath] ZEPPELIN-830 update licence doc
adb8380 [Renjith Kamath] ZEPPELIN-830 remove unused floatThead dep
a96c94a [Renjith Kamath] ZEPPELIN-830 fix rendering without angular/html directives
b365e7f [Renjith Kamath] ZEPPELIN-830 fix test
b87245a [Renjith Kamath] ZEPPELIN-830 fix jshint error
de6d134 [Renjith Kamath] ZEPPELIN-830 License update
7bb508e [Renjith Kamath] ZEPPELIN-830 fix number formatting for table display
4e6beb8 [Renjith Kamath] fix selenium test failure
c833f6e [Renjith Kamath] ZEPPELIN-830 Improve table display to handle large data
Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/4eccfcd5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/4eccfcd5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/4eccfcd5
Branch: refs/heads/master
Commit: 4eccfcd5259a6e4f1df3a66927950c6ec30a37af
Parents: 8350e78
Author: Renjith Kamath <re...@gmail.com>
Authored: Tue May 10 10:01:37 2016 +0530
Committer: Damien CORNEAU <co...@gmail.com>
Committed: Mon May 16 08:10:24 2016 -0700
----------------------------------------------------------------------
zeppelin-distribution/src/bin_license/LICENSE | 4 +
.../zeppelin/integration/SparkParagraphIT.java | 5 +-
zeppelin-web/.jshintrc | 3 +-
zeppelin-web/bower.json | 4 +-
.../notebook/paragraph/paragraph.controller.js | 134 +++++--------------
.../src/app/notebook/paragraph/paragraph.css | 23 ++++
zeppelin-web/src/index.html | 18 +--
zeppelin-web/test/karma.conf.js | 14 +-
8 files changed, 75 insertions(+), 130 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/4eccfcd5/zeppelin-distribution/src/bin_license/LICENSE
----------------------------------------------------------------------
diff --git a/zeppelin-distribution/src/bin_license/LICENSE b/zeppelin-distribution/src/bin_license/LICENSE
index 09f98ad..e18cbef 100644
--- a/zeppelin-distribution/src/bin_license/LICENSE
+++ b/zeppelin-distribution/src/bin_license/LICENSE
@@ -132,6 +132,10 @@ The text of each license is also included at licenses/LICENSE-[project]-[version
(The MIT License) lodash v3.9.3 (https://lodash.com/) - https://github.com/lodash/lodash/blob/3.9.3/LICENSE.txt
(The MIT License) angular-filter v0.5.4 (https://github.com/a8m/angular-filter) - https://github.com/a8m/angular-filter/blob/v0.5.4/license.md
(The MIT License) ngToast v1.5.5 (http://tamerayd.in/ngToast/) - http://tameraydin.mit-license.org/
+ (The MIT License) Handsontable v0.24.2 (https://github.com/handsontable/handsontable) - https://github.com/handsontable/handsontable/blob/master/LICENSE
+ (The MIT License) Zeroclipboard v2.2.0 (https://github.com/zeroclipboard/zeroclipboard) - https://github.com/zeroclipboard/zeroclipboard/blob/v2.2.0/LICENSE
+ (The MIT License) Moment v2.9.0 (https://github.com/moment/moment) - https://github.com/moment/moment/blob/2.9.0/LICENSE
+ (The MIT License) Pikaday v1.3.2 (https://github.com/dbushell/Pikaday) - https://github.com/dbushell/Pikaday/blob/1.3.2/LICENSE
(The MIT License) slf4j v1.7.10 (org.slf4j:slf4j-api:jar:1.7.10 - http://www.slf4j.org) - http://www.slf4j.org/license.html
(The MIT License) slf4j-log4j12 v1.7.10 (org.slf4j:slf4j-log4j12:jar:1.7.10 - http://www.slf4j.org) - http://www.slf4j.org/license.html
(The MIT License) bcprov-jdk15on v1.51 (org.bouncycastle:bcprov-jdk15on:jar:1.51 - http://www.bouncycastle.org/java.html) - http://www.bouncycastle.org/licence.html
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/4eccfcd5/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java
index eb09539..1eadd0e 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java
@@ -167,9 +167,8 @@ public class SparkParagraphIT extends AbstractZeppelinIT {
WebElement paragraph1Result = driver.findElement(By.xpath(
getParagraphXPath(1) + "//div[@class=\"tableDisplay\"]"));
collector.checkThat("Paragraph from SparkParagraphIT of testSqlSpark result: ",
- paragraph1Result.getText().toString(), CoreMatchers.equalTo("age job marital education balance\n" +
- "30 unemployed married primary 1,787")
- );
+ paragraph1Result.getText().toString(), CoreMatchers.equalTo("age\njob\nmarital\neducation\nbalance\n30" +
+ " unemployed married primary 1,787\nage\njob\nmarital\neducation\nbalance"));
} catch (Exception e) {
handleException("Exception in SparkParagraphIT while testSqlSpark", e);
}
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/4eccfcd5/zeppelin-web/.jshintrc
----------------------------------------------------------------------
diff --git a/zeppelin-web/.jshintrc b/zeppelin-web/.jshintrc
index d15bbb9..bdcd213 100644
--- a/zeppelin-web/.jshintrc
+++ b/zeppelin-web/.jshintrc
@@ -31,6 +31,7 @@
"nv": false,
"ace": false,
"d3": false,
- "BootstrapDialog": false
+ "BootstrapDialog": false,
+ "Handsontable": false
}
}
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/4eccfcd5/zeppelin-web/bower.json
----------------------------------------------------------------------
diff --git a/zeppelin-web/bower.json b/zeppelin-web/bower.json
index 5f4f726..2000281 100644
--- a/zeppelin-web/bower.json
+++ b/zeppelin-web/bower.json
@@ -30,9 +30,7 @@
"ngtoast": "~2.0.0",
"ng-focus-if": "~1.0.2",
"bootstrap3-dialog": "bootstrap-dialog#~1.34.7",
- "floatThead": "~1.3.2",
- "datatables.net-bs": "~1.10.11",
- "datatables.net-buttons-bs": "~1.1.2"
+ "handsontable": "~0.24.2"
},
"devDependencies": {
"angular-mocks": "1.5.0"
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/4eccfcd5/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 b19003f..a886969 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
@@ -1219,110 +1219,42 @@ angular.module('zeppelinWebApp')
};
var setTable = function(type, data, refresh) {
- var getTableContentFormat = function(d) {
- if (isNaN(d)) {
- if (d.length>'%html'.length && '%html ' === d.substring(0, '%html '.length)) {
- return 'html';
- } else {
- return '';
- }
- } else {
- return '';
- }
- };
-
- var formatTableContent = function(d) {
- if (isNaN(d)) {
- var f = getTableContentFormat(d);
- if (f !== '') {
- return d.substring(f.length+2);
- } else {
- return d;
- }
- } else {
- var dStr = d.toString();
- var splitted = dStr.split('.');
- var formatted = splitted[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
- if (splitted.length>1) {
- formatted+= '.'+splitted[1];
- }
- return formatted;
- }
- };
-
-
var renderTable = function() {
- var html = '';
- html += '<table class="table table-hover table-condensed">';
- html += ' <thead>';
- html += ' <tr style="background-color: #F6F6F6; font-weight: bold;">';
- for (var titleIndex in $scope.paragraph.result.columnNames) {
- html += '<th>'+$scope.paragraph.result.columnNames[titleIndex].name+'</th>';
- }
- html += ' </tr>';
- html += ' </thead>';
- html += ' <tbody>';
- for (var r in $scope.paragraph.result.msgTable) {
- var row = $scope.paragraph.result.msgTable[r];
- html += ' <tr>';
- for (var index in row) {
- var v = row[index].value;
- if (getTableContentFormat(v) !== 'html') {
- v = v.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
- return '&#'+i.charCodeAt(0)+';';
- });
- }
- html += ' <td>'+formatTableContent(v)+'</td>';
+ var height = $scope.paragraph.config.graph.height;
+ angular.element('#p' + $scope.paragraph.id + '_table').css('height', height);
+ var resultRows = $scope.paragraph.result.rows;
+ var columnNames = _.pluck($scope.paragraph.result.columnNames, 'name');
+ var container = document.getElementById('p' + $scope.paragraph.id + '_table');
+
+ var handsontable = new Handsontable(container, {
+ data: resultRows,
+ colHeaders: columnNames,
+ rowHeaders: false,
+ stretchH: 'all',
+ sortIndicator: true,
+ columnSorting: true,
+ contextMenu: false,
+ manualColumnResize: true,
+ manualRowResize: true,
+ editor: false,
+ fillHandle: false,
+ disableVisualSelection: true,
+ cells: function (row, col, prop) {
+ var cellProperties = {};
+ cellProperties.renderer = function(instance, td, row, col, prop, value, cellProperties) {
+ Handsontable.NumericCell.renderer.apply(this, arguments);
+ if (!isNaN(value)) {
+ cellProperties.type = 'numeric';
+ cellProperties.format = '0,0';
+ cellProperties.editor = false;
+ td.style.textAlign = 'left';
+ } else if (value.length > '%html'.length && '%html ' === value.substring(0, '%html '.length)) {
+ td.innerHTML = value.substring('%html'.length);
+ }
+ };
+ return cellProperties;
}
- html += ' </tr>';
- }
- html += ' </tbody>';
- html += '</table>';
-
- var tableDomEl = angular.element('#p' + $scope.paragraph.id + '_table');
- tableDomEl.html(html);
- var oTable = tableDomEl.children(1).DataTable({
- paging: false,
- info: false,
- autoWidth: false,
- lengthChange: false,
- searching: false,
- dom: '<>'
});
-
- if ($scope.paragraph.result.msgTable.length > 10000) {
- tableDomEl.css({
- 'overflow': 'scroll',
- 'height': $scope.paragraph.config.graph.height
- });
- } else {
-
- var dataTable = angular.element('#p' + $scope.paragraph.id + '_table .table');
- dataTable.floatThead({
- scrollContainer: function(dataTable) {
- return tableDomEl;
- }
- });
-
- dataTable.on('remove', function () {
- dataTable.floatThead('destroy');
- });
-
- tableDomEl.css({
- 'position': 'relative',
- 'height': '100%'
- });
- tableDomEl.perfectScrollbar('destroy')
- .perfectScrollbar({minScrollbarLength: 20});
-
- angular.element('.ps-scrollbar-y-rail').css('z-index', '1002');
-
- // set table height
- var psHeight = $scope.paragraph.config.graph.height;
- tableDomEl.css('height', psHeight);
- tableDomEl.perfectScrollbar('update');
- }
-
};
var retryRenderer = function() {
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/4eccfcd5/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 60f3d7f..f0c650f 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.css
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.css
@@ -397,6 +397,29 @@ table.dataTable.table-condensed .sorting_desc:after {
}
/*
+ Handsontable
+*/
+
+.handsontable th {
+ font-weight: bold;
+}
+
+.handsontable th, .handsontable td {
+ border-right: 0px;
+ border-left: 0px !important;
+ padding: 4px;
+}
+
+.handsontable tr:first-child th {
+ text-align: left;
+ border-top: 0px;
+ padding: 4px 0px 0px 0px;
+ border-left: 0px;
+ border-right: 0px;
+ border-bottom: 2px solid #CCC;
+}
+
+/*
Pivot CSS
*/
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/4eccfcd5/zeppelin-web/src/index.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/index.html b/zeppelin-web/src/index.html
index 207320e..a634fbf 100644
--- a/zeppelin-web/src/index.html
+++ b/zeppelin-web/src/index.html
@@ -44,8 +44,8 @@ limitations under the License.
<link rel="stylesheet" href="bower_components/highlightjs/styles/github.css" />
<link rel="stylesheet" href="bower_components/ngtoast/dist/ngToast.css" />
<link rel="stylesheet" href="bower_components/bootstrap3-dialog/dist/css/bootstrap-dialog.min.css" />
- <link rel="stylesheet" href="bower_components/datatables.net-bs/css/dataTables.bootstrap.css" />
- <link rel="stylesheet" href="bower_components/datatables.net-buttons-bs/css/buttons.bootstrap.css" />
+ <link rel="stylesheet" href="bower_components/pikaday/css/pikaday.css" />
+ <link rel="stylesheet" href="bower_components/handsontable/dist/handsontable.css" />
<!-- endbower -->
<link rel="stylesheet" href="bower_components/jquery-ui/themes/base/all.css" />
<!-- endbuild -->
@@ -132,16 +132,10 @@ limitations under the License.
<script src="bower_components/ngtoast/dist/ngToast.js"></script>
<script src="bower_components/ng-focus-if/focusIf.js"></script>
<script src="bower_components/bootstrap3-dialog/dist/js/bootstrap-dialog.min.js"></script>
- <script src="bower_components/floatThead/dist/jquery.floatThead.js"></script>
- <script src="bower_components/floatThead/dist/jquery.floatThead.min.js"></script>
- <script src="bower_components/datatables.net/js/jquery.dataTables.js"></script>
- <script src="bower_components/datatables.net-bs/js/dataTables.bootstrap.js"></script>
- <script src="bower_components/datatables.net-buttons/js/dataTables.buttons.js"></script>
- <script src="bower_components/datatables.net-buttons/js/buttons.colVis.js"></script>
- <script src="bower_components/datatables.net-buttons/js/buttons.flash.js"></script>
- <script src="bower_components/datatables.net-buttons/js/buttons.html5.js"></script>
- <script src="bower_components/datatables.net-buttons/js/buttons.print.js"></script>
- <script src="bower_components/datatables.net-buttons-bs/js/buttons.bootstrap.js"></script>
+ <script src="bower_components/zeroclipboard/dist/ZeroClipboard.js"></script>
+ <script src="bower_components/moment/moment.js"></script>
+ <script src="bower_components/pikaday/pikaday.js"></script>
+ <script src="bower_components/handsontable/dist/handsontable.js"></script>
<!-- endbower -->
<!-- endbuild -->
<!-- build:js({.tmp,src}) scripts/scripts.js -->
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/4eccfcd5/zeppelin-web/test/karma.conf.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/test/karma.conf.js b/zeppelin-web/test/karma.conf.js
index 8049ac6..1ec6eb6 100644
--- a/zeppelin-web/test/karma.conf.js
+++ b/zeppelin-web/test/karma.conf.js
@@ -59,16 +59,10 @@ module.exports = function(config) {
'bower_components/ngtoast/dist/ngToast.js',
'bower_components/ng-focus-if/focusIf.js',
'bower_components/bootstrap3-dialog/dist/js/bootstrap-dialog.min.js',
- 'bower_components/floatThead/dist/jquery.floatThead.js',
- 'bower_components/floatThead/dist/jquery.floatThead.min.js',
- 'bower_components/datatables.net/js/jquery.dataTables.js',
- 'bower_components/datatables.net-bs/js/dataTables.bootstrap.js',
- 'bower_components/datatables.net-buttons/js/dataTables.buttons.js',
- 'bower_components/datatables.net-buttons/js/buttons.colVis.js',
- 'bower_components/datatables.net-buttons/js/buttons.flash.js',
- 'bower_components/datatables.net-buttons/js/buttons.html5.js',
- 'bower_components/datatables.net-buttons/js/buttons.print.js',
- 'bower_components/datatables.net-buttons-bs/js/buttons.bootstrap.js',
+ 'bower_components/zeroclipboard/dist/ZeroClipboard.js',
+ 'bower_components/moment/moment.js',
+ 'bower_components/pikaday/pikaday.js',
+ 'bower_components/handsontable/dist/handsontable.js',
'bower_components/angular-mocks/angular-mocks.js',
// endbower
'src/app/app.js',