You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2016/09/03 12:46:39 UTC
[45/50] [abbrv] kylin git commit: KYLIN-1767-WEB-UI-FOR-TOPN
KYLIN-1767-WEB-UI-FOR-TOPN
Signed-off-by: shaofengshi <sh...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/9e2970bc
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/9e2970bc
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/9e2970bc
Branch: refs/heads/1.5.x-CDH5.7
Commit: 9e2970bc4a87d3848ba6677fd2d05c9ed86e15d9
Parents: 111e984
Author: zx chen <34...@qq.com>
Authored: Thu Sep 1 15:16:30 2016 +0800
Committer: shaofengshi <sh...@apache.org>
Committed: Fri Sep 2 19:42:22 2016 +0800
----------------------------------------------------------------------
webapp/app/js/controllers/cubeEdit.js | 25 ++++
webapp/app/js/controllers/cubeMeasures.js | 130 +++++++++++++++++++-
webapp/app/js/directives/directives.js | 29 ++++-
webapp/app/js/model/cubeDescModel.js | 6 +-
webapp/app/partials/cubeDesigner/measures.html | 77 ++++++++++--
5 files changed, 250 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/9e2970bc/webapp/app/js/controllers/cubeEdit.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubeEdit.js b/webapp/app/js/controllers/cubeEdit.js
index b620d7f..e2d0ab5 100755
--- a/webapp/app/js/controllers/cubeEdit.js
+++ b/webapp/app/js/controllers/cubeEdit.js
@@ -98,6 +98,31 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio
return me_columns;
};
+ $scope.getGroupBYColumns = function () {
+ //metric from model
+ var me_columns = [];
+ var table_columns=[];
+ var groupby_columns=[];
+ var tableColumns = $scope.getColumnsByTable($scope.metaModel.model.fact_table);
+ if($scope.metaModel.model.metrics){
+ angular.forEach($scope.metaModel.model.metrics,function(metric,index){
+ me_columns.push(metric);
+ });
+ }
+ angular.forEach($scope.cubeMetaFrame.dimensions,function(dimension){
+ if(dimension.table==$scope.metaModel.model.fact_table) {
+ table_columns.push(dimension.column);
+ }
+ });
+ angular.forEach(me_columns,function(column){
+ if(table_columns.indexOf(column)==-1) {
+ groupby_columns.push(column);
+ }
+ });
+
+ return groupby_columns;
+ };
+
$scope.getExtendedHostColumn = function(){
var me_columns = [];
//add cube dimension column for specific measure
http://git-wip-us.apache.org/repos/asf/kylin/blob/9e2970bc/webapp/app/js/controllers/cubeMeasures.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubeMeasures.js b/webapp/app/js/controllers/cubeMeasures.js
index 9dec379..794d2b2 100644
--- a/webapp/app/js/controllers/cubeMeasures.js
+++ b/webapp/app/js/controllers/cubeMeasures.js
@@ -19,7 +19,9 @@
'use strict';
KylinApp.controller('CubeMeasuresCtrl', function ($scope, $modal,MetaModel,cubesManager,CubeDescModel,SweetAlert) {
-
+ $scope.num=0;
+ $scope.convertedColumns=[];
+ $scope.groupby=[];
$scope.initUpdateMeasureStatus = function(){
$scope.updateMeasureStatus = {
isEdit:false,
@@ -38,6 +40,31 @@ KylinApp.controller('CubeMeasuresCtrl', function ($scope, $modal,MetaModel,cubes
if(!!measure && measure.function.parameter.next_parameter){
$scope.nextPara.value = measure.function.parameter.next_parameter.value;
}
+ if($scope.newMeasure.function.expression=="TOP_N"){
+ $scope.convertedColumns=[];
+ for(var configuration in $scope.newMeasure.function.configuration) {
+ var _name=configuration.slice(14);
+ var item=$scope.newMeasure.function.configuration[configuration];
+ var _isFixedLength = item.substring(0,12) === "fixed_length"?"true":"false";//fixed_length:12
+ var _isIntLength = item.substring(0,3) === "int"?"true":"false";//fixed_length:12
+ var _encoding = item;
+ var _valueLength = 0 ;
+ if(_isFixedLength !=="false"){
+ _valueLength = item.substring(13,item.length);
+ _encoding = "fixed_length";
+ }
+ if(_isIntLength!="false"){
+ _valueLength = item.substring(4,item.length);
+ _encoding = "int";
+ }
+ $scope.GroupBy = {
+ name:_name,
+ encoding:_encoding,
+ valueLength:_valueLength,
+ }
+ $scope.convertedColumns.push($scope.GroupBy);
+ };
+ }
};
@@ -103,9 +130,52 @@ KylinApp.controller('CubeMeasuresCtrl', function ($scope, $modal,MetaModel,cubes
$scope.saveNewMeasure = function () {
- if ($scope.newMeasure.function.expression === 'TOP_N' && $scope.nextPara.value == "") {
- SweetAlert.swal('', '[TOP_N] Group by Column is required', 'warning');
- return false;
+ if ($scope.newMeasure.function.expression === 'TOP_N' ) {
+ if($scope.newMeasure.function.parameter.value == ""){
+ SweetAlert.swal('', '[TOP_N] ORDER|SUM by Column is required', 'warning');
+ return false;
+ }
+ if($scope.convertedColumns.length<1){
+ SweetAlert.swal('', '[TOP_N] Group by Column is required', 'warning');
+ return false;
+ }
+
+ var hasExisted = [];
+
+ for (var column in $scope.convertedColumns){
+ if(hasExisted.indexOf($scope.convertedColumns[column].name)==-1){
+ hasExisted.push($scope.convertedColumns[column].name);
+ }
+ else{
+ SweetAlert.swal('', 'The column named ['+$scope.convertedColumns[column].name+'] already exits.', 'warning');
+ return false;
+ }
+ if ($scope.convertedColumns[column].encoding == 'int' && ($scope.convertedColumns[column].valueLength < 1 || $scope.convertedColumns[column].valueLength > 8)) {
+ SweetAlert.swal('', 'int encoding column length should between 1 and 8.', 'warning');
+ return false;
+ }
+ }
+ $scope.nextPara.next_parameter={};
+ $scope.newMeasure.function.configuration={};
+ $scope.groupby($scope.nextPara);
+ angular.forEach($scope.convertedColumns,function(item){
+ var a='topn.encoding.'+item.name;
+ var encoding="";
+ if(item.encoding!=="dict" && item.encoding!=="date"&& item.encoding!=="time"){
+ if(item.encoding=="fixed_length" && item.valueLength){
+ encoding = "fixed_length:"+item.valueLength;
+ }
+ else if(item.encoding=="int" && item.valueLength){
+ encoding = "int:"+item.valueLength;
+ }else{
+ encoding = item.encoding;
+ }
+ }else{
+ encoding = item.encoding;
+ item.valueLength=0;
+ }
+ $scope.newMeasure.function.configuration[a]=encoding;
+ });
}
if ($scope.isNameDuplicated($scope.cubeMetaFrame.measures, $scope.newMeasure) == true) {
@@ -143,17 +213,67 @@ KylinApp.controller('CubeMeasuresCtrl', function ($scope, $modal,MetaModel,cubes
$scope.nextPara = {
"type":"column",
"value":"",
- "next_parameter":null
+ "next_parameter":{}
}
if($scope.newMeasure){
$scope.newMeasure.function.parameter.next_parameter = null;
}
}
+ $scope.addNewGroupByColumn = function () {
+ $scope.nextGroupBy = {
+ name:null,
+ encoding:"dict",
+ valueLength:0,
+ }
+ $scope.convertedColumns.push($scope.nextGroupBy);
+
+ };
+
+ $scope.removeColumn = function(arr,index){
+ if (index > -1) {
+ arr.splice(index, 1);
+ }
+ };
+ $scope.refreshGroupBy=function (list,index,item) {
+ var encoding;
+ var name = item.name;
+ if(item.encoding=="dict" || item.encoding=="date"|| item.encoding=="time"){
+ item.valueLength=0;
+ }
+ };
+
+ $scope.groupby= function (next_parameter){
+ if($scope.num<$scope.convertedColumns.length-1){
+ next_parameter.value=$scope.convertedColumns[$scope.num].name;
+ next_parameter.type="column";
+ next_parameter.next_parameter={};
+ $scope.num++;
+ $scope.groupby(next_parameter.next_parameter);
+ }
+ else{
+ next_parameter.value=$scope.convertedColumns[$scope.num].name;
+ next_parameter.type="column";
+ next_parameter.next_parameter=null;
+ $scope.num=0;
+ return false;
+ }
+ }
+ $scope.converted = function (next_parameter) {
+ if (next_parameter != null) {
+ $scope.groupby.push(next_parameter.value);
+ converted(next_parameter.next_parameter)
+ }
+ else {
+ $scope.groupby.push(next_parameter.value);
+ return false;
+ }
+ }
//map right return type for param
$scope.measureReturnTypeUpdate = function(){
if($scope.newMeasure.function.expression == 'TOP_N'){
+ $scope.convertedColumns=[];
$scope.newMeasure.function.parameter.type= 'column';
$scope.newMeasure.function.returntype = "topn(100)";
return;
http://git-wip-us.apache.org/repos/asf/kylin/blob/9e2970bc/webapp/app/js/directives/directives.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/directives/directives.js b/webapp/app/js/directives/directives.js
index 4b83865..f5051e8 100644
--- a/webapp/app/js/directives/directives.js
+++ b/webapp/app/js/directives/directives.js
@@ -295,7 +295,30 @@ KylinApp.directive('kylinPagination', function ($parse, $q) {
},
template:
'<li class="parent_li">Value:<b>{{nextpara.value}}</b>, Type:<b>{{ nextpara.type }}</b></li>' +
- '<parametertree ng-if="nextpara.next_parameter!=null" nextpara="nextpara.next_parameter"></parameterTree>',
+ '<parametertree ng-if="nextpara.next_parameter!=null" nextpara="nextpara.next_parameter"></parameterTree>',
+ compile: function(tElement, tAttr, transclude) {
+ var contents = tElement.contents().remove();
+ var compiledContents;
+ return function(scope, iElement, iAttr) {
+ if(!compiledContents) {
+ compiledContents = $compile(contents, transclude);
+ }
+ compiledContents(scope, function(clone, scope) {
+ iElement.append(clone);
+ });
+ };
+ }
+ };
+ }).directive("groupbytree", function($compile) {
+ return {
+ restrict: "E",
+ transclude: true,
+ scope: {
+ nextpara: '=',
+ },
+ template:
+ '<b>{{nextpara.value}}<b ng-if="nextpara.next_parameter!=null">,</b></b>'+
+ '<groupbytree ng-if="nextpara.next_parameter!=null" nextpara="nextpara.next_parameter"></groupbytree>',
compile: function(tElement, tAttr, transclude) {
var contents = tElement.contents().remove();
var compiledContents;
@@ -318,7 +341,9 @@ KylinApp.directive('kylinPagination', function ($parse, $q) {
},
template:
'<li class="parent_li">SUM|ORDER BY:<b>{{nextpara.value}}</b></b></li>' +
- '<li class="parent_li">GROUP BY:<b>{{nextpara.next_parameter.value}}</b></li>',
+ '<li class="parent_li">Group By:'+
+ '<groupbytree nextpara="nextpara.next_parameter"></groupbytree>'+
+ '</li>',
compile: function(tElement, tAttr, transclude) {
var contents = tElement.contents().remove();
var compiledContents;
http://git-wip-us.apache.org/repos/asf/kylin/blob/9e2970bc/webapp/app/js/model/cubeDescModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/cubeDescModel.js b/webapp/app/js/model/cubeDescModel.js
index 57d7e6e..c981249 100644
--- a/webapp/app/js/model/cubeDescModel.js
+++ b/webapp/app/js/model/cubeDescModel.js
@@ -37,7 +37,8 @@ KylinApp.service('CubeDescModel', function () {
"type": "constant",
"value": "1",
"next_parameter":null
- }
+ },
+ "configuration":{}
}
}
],
@@ -74,7 +75,8 @@ KylinApp.service('CubeDescModel', function () {
"type": "",
"value": "",
"next_parameter":null
- }
+ },
+ "configuration":null
}
};
http://git-wip-us.apache.org/repos/asf/kylin/blob/9e2970bc/webapp/app/partials/cubeDesigner/measures.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/measures.html b/webapp/app/partials/cubeDesigner/measures.html
index 53806b4..065b735 100755
--- a/webapp/app/partials/cubeDesigner/measures.html
+++ b/webapp/app/partials/cubeDesigner/measures.html
@@ -218,19 +218,80 @@
</div>
</div>
</div>
-
- <div class="form-group" ng-if="newMeasure.function.expression == 'TOP_N'">
+ <!--Group by Column-->
+ <div class="form-group" ng-if="newMeasure.function.expression == 'TOP_N'" >
<div class="row">
<label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default">
<b>Group by Column</b>
</label>
- <div class="col-xs-12 col-sm-6">
- <select class="form-control" chosen ng-if="nextPara.type !== 'constant'" required
- ng-model="nextPara.value"
- ng-options="column as column for column in getCommonMetricColumns()" >
- <option value=""></option>
- </select>
+ <div class="form-group large-popover" >
+ <div class="box-body">
+ <table style="margin-left:width:92%"
+ class="table table-hover table-bordered list">
+ <thead>
+ <tr>
+ <th>ID</th>
+ <th>Column</th>
+ <th>Encoding</th>
+ <th>Length</th>
+ <th ng-if="state.mode=='edit'"></th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+ <tr ng-repeat="groupby_column in convertedColumns track by $index"
+ ng-class="state.mode=='edit'?'sort-item':''">
+
+ <td>
+ <!-- ID -->
+ <span class="ng-binding" ng-class="state.mode=='edit'?'badge':''">{{($index + 1)}}</span>
+ </td>
+ <!--Column Name -->
+ <td>
+ <select class="form-control" chosen ng-if="nextPara.type !== 'constant'" required
+ ng-model="groupby_column.name"
+ ng-options="column as column for column in getGroupBYColumns()" style="width:323px;">
+ <option value="">--Select A Column--</option>
+ </select>
+ </td>
+ <!--Column Encoding -->
+ <td>
+ <select ng-if="state.mode=='edit'" style="width:180px;"
+ chosen ng-model="groupby_column.encoding"
+ ng-change="refreshGroupBy(convertedColumns,$index,groupby_column)"
+ ng-options="dt as dt for dt in store.supportedEncoding">
+ <option value=""></option>
+ </select>
+ <span ng-if="state.mode=='view'">{{groupby_column.encoding}}</span>
+
+ </td>
+ <td>
+ <!--Column Length -->
+ <input type="text" class="form-control" placeholder="Column Length.." ng-if="state.mode=='edit'"
+ tooltip="group by column length.." tooltip-trigger="focus"
+ ng-change="refreshGroupBy(convertedColumns,$index,groupby_column);"
+ ng-disabled="groupby_column.encoding=='dict'||groupby_column.encoding=='date'||groupby_column.encoding=='time'"
+ ng-model="groupby_column.valueLength" class="form-control">
+
+ <small class="help-block red" ng-show="state.mode=='edit' && groupby_column.encoding=='int' && (groupby_column.valueLength>8 || groupby_column.valueLength<1)">int encoding column length should between 1 and 8</small>
+ <span ng-if="state.mode=='view'">{{groupby_column.valueLength}}</span>
+ </td>
+ <td ng-if="state.mode=='edit'">
+ <button class="btn btn-xs btn-info"
+ ng-click="removeColumn(convertedColumns, $index)"><i
+ class="fa fa-minus"></i>
+ </button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <button class="btn btn-sm btn-info" style="margin-left:10px"
+ ng-click="addNewGroupByColumn()" ng-show="state.mode=='edit'">New Column<i class="fa fa-plus"></i>
+ </button>
</div>
+
</div>
</div>