You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by zh...@apache.org on 2016/07/12 12:39:27 UTC
kylin git commit: KYLIN-1786 UI for extended columns as measure
Repository: kylin
Updated Branches:
refs/heads/v1.5.3-release 6747b2a80 -> 469aa4003
KYLIN-1786 UI for extended columns as measure
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/469aa400
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/469aa400
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/469aa400
Branch: refs/heads/v1.5.3-release
Commit: 469aa40030c930e64c7a6af5f6d011e3080dfa84
Parents: 6747b2a
Author: Jason <ji...@163.com>
Authored: Tue Jul 12 20:38:46 2016 +0800
Committer: Jason <ji...@163.com>
Committed: Tue Jul 12 20:38:46 2016 +0800
----------------------------------------------------------------------
webapp/app/js/controllers/cubeEdit.js | 52 ++++++++
webapp/app/js/controllers/cubeMeasures.js | 60 +++++----
webapp/app/js/directives/directives.js | 43 +++++++
webapp/app/js/model/cubeConfig.js | 2 +-
webapp/app/partials/cubeDesigner/measures.html | 132 +++++++++++++++-----
5 files changed, 237 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/469aa400/webapp/app/js/controllers/cubeEdit.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubeEdit.js b/webapp/app/js/controllers/cubeEdit.js
index b6fc875..8475025 100755
--- a/webapp/app/js/controllers/cubeEdit.js
+++ b/webapp/app/js/controllers/cubeEdit.js
@@ -119,6 +119,58 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio
};
+ $scope.getExtendedColumns = function (measure) {
+ //metric from model
+ var me_columns = [];
+ if($scope.metaModel.model.metrics){
+ angular.forEach($scope.metaModel.model.metrics,function(metric,index){
+ me_columns.push(metric);
+ })
+ }
+ angular.forEach($scope.metaModel.model.dimensions,function(dimension,index){
+ if(dimension.columns){
+ me_columns = me_columns.concat(dimension.columns);
+ }
+ })
+
+ return me_columns;
+
+ };
+
+ $scope.getExtendedFactColumns = function (measure) {
+ var me_columns = [];
+ angular.forEach($scope.metaModel.model.dimensions,function(dimension,index){
+ if($scope.metaModel.model.fact_table !== dimension.table){
+ return;
+ }
+
+ if(dimension.columns){
+ me_columns = me_columns.concat(dimension.columns);
+ }
+ })
+
+ return me_columns;
+
+ };
+
+
+ $scope.getFactColumns = function () {
+ var me_columns = [];
+ angular.forEach($scope.cubeMetaFrame.dimensions,function(dimension,index){
+ if($scope.metaModel.model.fact_table !== dimension.table){
+ return;
+ }
+ if(dimension.column && dimension.derived == null){
+ me_columns.push(dimension.column);
+ }
+
+ });
+
+ return me_columns;
+
+ };
+
+
$scope.getColumnType = function (_column, table) {
var columns = $scope.getColumnsByTable(table);
http://git-wip-us.apache.org/repos/asf/kylin/blob/469aa400/webapp/app/js/controllers/cubeMeasures.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubeMeasures.js b/webapp/app/js/controllers/cubeMeasures.js
index fb9d292..bb22a42 100644
--- a/webapp/app/js/controllers/cubeMeasures.js
+++ b/webapp/app/js/controllers/cubeMeasures.js
@@ -24,27 +24,30 @@ KylinApp.controller('CubeMeasuresCtrl', function ($scope, $modal,MetaModel,cubes
$scope.addNewMeasure = function (measure) {
$scope.nextParameters = [];
$scope.newMeasure = (!!measure)? measure:CubeDescModel.createMeasure();
- if(!!measure){
- $scope.convertNextParameters();
+ //if(!!measure){
+ // $scope.convertNextParameters();
+ //}
+ if(!!measure && measure.function.parameter.next_parameter){
+ $scope.nextPara.value = measure.function.parameter.next_parameter.value;
}
};
- $scope.convertNextParameters = function(){
- $scope.nextParameters = [];
- var paramater = jQuery.extend(true, {}, $scope.newMeasure.function.parameter);
- while(paramater.next_parameter){
- var paraMeter =
- {
- "type": paramater.next_parameter.type,
- "value":paramater.next_parameter.value,
- "next_parameter":null
- }
- $scope.nextParameters.push(paraMeter);
-
- paramater = paramater.next_parameter;
-
- }
-
- }
+ //$scope.convertNextParameters = function(){
+ // $scope.nextParameters = [];
+ // var paramater = jQuery.extend(true, {}, $scope.newMeasure.function.parameter);
+ // while(paramater.next_parameter){
+ // var paraMeter =
+ // {
+ // "type": paramater.next_parameter.type,
+ // "value":paramater.next_parameter.value,
+ // "next_parameter":null
+ // }
+ // $scope.nextParameters.push(paraMeter);
+ //
+ // paramater = paramater.next_parameter;
+ //
+ // }
+ //
+ //}
$scope.updateNextParameter = function(){
//jQuery.extend(true, {},$scope.newMeasure.function.parameter.next_parameter)
@@ -70,6 +73,14 @@ KylinApp.controller('CubeMeasuresCtrl', function ($scope, $modal,MetaModel,cubes
}
$scope.updateNextParameter();
}
+
+
+ $scope.nextPara = {
+ "type":"column",
+ "value":"",
+ "next_parameter":null
+ }
+
$scope.openParameterModal = function (parameter) {
$modal.open({
templateUrl: 'nextParameter.html',
@@ -95,13 +106,19 @@ KylinApp.controller('CubeMeasuresCtrl', function ($scope, $modal,MetaModel,cubes
$scope.clearNewMeasure = function () {
$scope.newMeasure = null;
+ $scope.nextPara.value = "";
};
$scope.saveNewMeasure = function () {
- if ($scope.newMeasure.function.expression === 'TOP_N' && $scope.nextParameters.length == 0) {
+
+ if ($scope.newMeasure.function.expression === 'TOP_N' && $scope.nextPara.value == "") {
SweetAlert.swal('', '[TOP_N] Group by Column is required', 'warning');
return false;
}
+ if($scope.nextPara.value!=="" && ($scope.newMeasure.function.expression == 'EXTENDED_COLUMN' || $scope.newMeasure.function.expression == 'TOP_N')){
+ $scope.newMeasure.function.parameter.next_parameter = $scope.nextPara;
+ }
+
if ($scope.cubeMetaFrame.measures.indexOf($scope.newMeasure) === -1) {
$scope.cubeMetaFrame.measures.push($scope.newMeasure);
}
@@ -112,7 +129,8 @@ KylinApp.controller('CubeMeasuresCtrl', function ($scope, $modal,MetaModel,cubes
//map right return type for param
$scope.measureReturnTypeUpdate = function(){
- if($scope.newMeasure.function.expression == 'TOP_N'){
+ if($scope.newMeasure.function.expression == 'TOP_N'||$scope.newMeasure.function.expression == 'EXTENDED_COLUMN'){
+ $scope.newMeasure.function.parameter.type= 'column';
return;
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/469aa400/webapp/app/js/directives/directives.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/directives/directives.js b/webapp/app/js/directives/directives.js
index ae90c82..4b83865 100644
--- a/webapp/app/js/directives/directives.js
+++ b/webapp/app/js/directives/directives.js
@@ -332,6 +332,29 @@ KylinApp.directive('kylinPagination', function ($parse, $q) {
};
}
};
+}).directive("extendedcolumntree", function($compile) {
+ return {
+ restrict: "E",
+ transclude: true,
+ scope: {
+ nextpara: '='
+ },
+ template:
+ '<li class="parent_li">Host Column:<b>{{nextpara.value}}</b></b></li>' +
+ '<li class="parent_li">Extended Column:<b>{{nextpara.next_parameter.value}}</b></li>',
+ 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('kylinpopover', function ($compile,$templateCache) {
return {
restrict: "A",
@@ -355,4 +378,24 @@ KylinApp.directive('kylinPagination', function ($parse, $q) {
$(element).popover(options);
}
};
+}).directive('extendedColumnReturn', function() {
+ return {
+ require: 'ngModel',
+ link: function(scope, element, attrs, ngModelController) {
+
+ var prefix = "extendedcolumn(";
+ var suffix = ")";
+ ngModelController.$parsers.push(function(data) {
+ //convert data from view format to model format
+ return prefix +data+suffix; //converted
+ });
+
+ ngModelController.$formatters.push(function(data) {
+ //convert data from model format to view format
+ var prefixIndex = data.indexOf("(")+1;
+ var suffixIndex = data.indexOf(")");
+ return data.substring(prefixIndex,suffixIndex); //converted
+ });
+ }
+ }
});
http://git-wip-us.apache.org/repos/asf/kylin/blob/469aa400/webapp/app/js/model/cubeConfig.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/cubeConfig.js b/webapp/app/js/model/cubeConfig.js
index 82dfca4..88e2133 100644
--- a/webapp/app/js/model/cubeConfig.js
+++ b/webapp/app/js/model/cubeConfig.js
@@ -20,7 +20,7 @@ KylinApp.constant('cubeConfig', {
//~ Define metadata & class
measureParamType: ['column', 'constant'],
- measureExpressions: ['SUM', 'MIN', 'MAX', 'COUNT', 'COUNT_DISTINCT',"TOP_N", 'RAW'],
+ measureExpressions: ['SUM', 'MIN', 'MAX', 'COUNT', 'COUNT_DISTINCT',"TOP_N", 'RAW','EXTENDED_COLUMN'],
dimensionDataTypes: ["string", "tinyint", "int", "bigint", "date"],
cubePartitionTypes: ['APPEND'],
joinTypes: [
http://git-wip-us.apache.org/repos/asf/kylin/blob/469aa400/webapp/app/partials/cubeDesigner/measures.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/measures.html b/webapp/app/partials/cubeDesigner/measures.html
index 5778003..0a39210 100755
--- a/webapp/app/partials/cubeDesigner/measures.html
+++ b/webapp/app/partials/cubeDesigner/measures.html
@@ -43,8 +43,9 @@
<td>
<div class="paraTree">
<ul>
- <parametertree ng-if="measure.function.parameter!=null && measure.function.expression!=='TOP_N'" nextpara="measure.function.parameter"></parametertree>
+ <parametertree ng-if="measure.function.parameter!=null && measure.function.expression!=='TOP_N' && measure.function.expression!=='EXTENDED_COLUMN'" nextpara="measure.function.parameter"></parametertree>
<topntree ng-if="measure.function.parameter!=null && measure.function.expression=='TOP_N'" nextpara="measure.function.parameter"></topntree>
+ <extendedcolumntree ng-if="measure.function.parameter!=null && measure.function.expression=='EXTENDED_COLUMN'" nextpara="measure.function.parameter"></extendedcolumntree>
</ul>
</div>
<!--<span ng-if="measure.function.parameter.next_parameter!=null">{{measure.function.parameter.next_parameter |json}}</span>-->
@@ -111,7 +112,7 @@
</div>
</div>
<!--Param Type-->
- <div class="form-group">
+ <div class="form-group" ng-if="newMeasure.function.expression !== 'EXTENDED_COLUMN' && 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>Param Type</b></label>
<div class="col-xs-12 col-sm-6">
@@ -133,9 +134,11 @@
<div class="form-group middle-popover">
<div class="row">
<label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default">
- <b>Param Value</b> <i class="fa fa-info-circle" kylinpopover placement="right" title="Param Value" template="paramvalueTip.html"></i>
+ <b ng-if="newMeasure.function.expression == 'EXTENDED_COLUMN'">Host column On Fact Table</b> <i ng-if="newMeasure.function.expression == 'EXTENDED_COLUMN'" title="Host Column" class="fa fa-info-circle" kylinpopover placement="right" template="hostTableTip.html"></i>
+ <b ng-if="newMeasure.function.expression == 'TOP_N'">ORDER|SUM by Column</b> <i ng-if="newMeasure.function.expression == 'TOP_N'" class="fa fa-info-circle" title="ORDER|SUM by Column" kylinpopover placement="right" template="topnTip.html"></i>
+ <b ng-if="newMeasure.function.expression !== 'EXTENDED_COLUMN' && newMeasure.function.expression !== 'TOP_N' ">Param Value</b> <i ng-if="newMeasure.function.expression !== 'EXTENDED_COLUMN' && newMeasure.function.expression !== 'TOP_N' " class="fa fa-info-circle" kylinpopover placement="right" title="Param Value" template="paramvalueTip.html"></i>
<!--tip for top_n-->
- <small ng-if="newMeasure.function.expression == 'TOP_N'" class="help-block" style="color:#3a87ad">(SUM|ORDER BY Column for TOP_N)</small>
+ <!--<small ng-if="newMeasure.function.expression == 'TOP_N'" class="help-block" style="color:#3a87ad">(SUM|ORDER BY Column for TOP_N)</small>-->
</label>
@@ -146,19 +149,29 @@
ng-init="newMeasure.function.parameter.value = 1"><b> 1</b></span>
<!--!COUNT_DISTINCT-->
<select class="form-control" chosen
- ng-if="newMeasure.function.parameter.type == 'column'"
+ ng-if="newMeasure.function.parameter.type == 'column' && newMeasure.function.expression !== 'EXTENDED_COLUMN'"
ng-model="newMeasure.function.parameter.value"
ng-change="measureReturnTypeUpdate();"
ng-options="column as column for column in getCommonMetricColumns(newMeasure)" >
<option value="">-- Select a Column --</option>
</select>
+ <select class="form-control" chosen
+ ng-if="newMeasure.function.expression == 'EXTENDED_COLUMN'"
+ ng-model="newMeasure.function.parameter.value"
+ ng-change="measureReturnTypeUpdate();"
+ ng-options="column as column for column in getFactColumns()" >
+ <option value="">-- Select a Column --</option>
+ </select>
</div>
</div>
</div>
<!--Return Type-->
- <div class="form-group">
+ <div class="form-group middle-popover">
<div class="row">
- <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Return Type</b></label>
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default">
+ <b ng-if="newMeasure.function.expression !== 'EXTENDED_COLUMN'">Return Type</b>
+ <b ng-if="newMeasure.function.expression == 'EXTENDED_COLUMN'">Maximum length of extended column</b> <i ng-if="newMeasure.function.expression == 'EXTENDED_COLUMN'" title="Maximum Length" class="fa fa-info-circle" kylinpopover placement="right" template="extendedTypeTip.html"></i>
+ </label>
<div class="col-xs-12 col-sm-6">
<select class="form-control"
ng-if="newMeasure.function.expression == 'COUNT_DISTINCT'"
@@ -174,13 +187,53 @@
ng-options="ddt.value as ddt.name for ddt in cubeConfig.topNTypes">
<option value=""></option>
</select>
+
+ <input extended-column-return
+ ng-if="newMeasure.function.expression == 'EXTENDED_COLUMN'"
+ type="text" placeholder="Kylin won\u2019t save more than this number of bytes" class="form-control"
+ tooltip-trigger="focus"
+ ng-init="newMeasure.function.returntype=newMeasure.function.returntype?newMeasure.function.returntype:'extendedcolumn(100)'"
+ ng-model="newMeasure.function.returntype" required />
+
<span class="font-color-default"
- ng-if="newMeasure.function.expression != 'COUNT_DISTINCT' && newMeasure.function.expression != 'TOP_N'"
+ ng-if="newMeasure.function.expression != 'COUNT_DISTINCT' && newMeasure.function.expression != 'TOP_N' && newMeasure.function.expression != 'EXTENDED_COLUMN' "
><b> {{newMeasure.function.returntype | uppercase}}</b>
</span>
</div>
</div>
</div>
+
+
+ <div class="form-group middle-popover" ng-if="newMeasure.function.expression == 'EXTENDED_COLUMN'">
+ <div class="row">
+ <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default">
+ <b>Extended column on fact table</b> <i ng-if="newMeasure.function.expression == 'EXTENDED_COLUMN'" title="Extended Column" class="fa fa-info-circle" kylinpopover placement="right" template="extendedColumnTip.html"></i>
+ </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 getExtendedFactColumns()" >
+ <option value=""></option>
+ </select>
+ </div>
+ </div>
+ </div>
+
+ <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 getExtendedColumns(newMeasure)" >
+ <option value=""></option>
+ </select>
+ </div>
+ </div>
+ </div>
+
<!--Name-->
<div class="form-group">
<div class="row">
@@ -207,26 +260,14 @@
</tr>
</table>
- <table class="table table-hover table-bordered list" ng-if="nextParameters.length" ng-show="newMeasure.function.expression == 'TOP_N'">
- <tr ng-repeat="n_parameter in nextParameters track by $index">
- <td><b>Group By Column</b></td>
- <td>{{n_parameter.value}}</td>
- <td>
- <button class="btn btn-xs btn-info" ng-click="editNextParameter(n_parameter)">
- <i class="fa fa-pencil"></i>
- </button>
- <button class="btn btn-xs btn-info" ng-click="removeParameter(nextParameters, $index)"><i class="fa fa-minus"></i>
- </button>
-
- </td>
-
- </tr>
- </table>
- <button class="btn btn-sm btn-info" ng-click="addNextParameter()" ng-show="newMeasure.function.expression == 'TOP_N' && nextParameters.length==0"
- ng-show="state.mode=='edit'"><i class="fa fa-plus"> Group by Column</i>
- </button>
+ <!--<button class="btn btn-sm btn-info" ng-click="addNextParameter()" ng-show="newMeasure.function.expression == 'TOP_N' && nextParameters.length==0"-->
+ <!--ng-show="state.mode=='edit'"><i class="fa fa-plus"> Group by Column</i>-->
+ <!--</button>-->
+ <!--<button class="btn btn-sm btn-info" ng-click="addNextParameter()" ng-show="newMeasure.function.expression == 'EXTENDED_COLUMN' && nextParameters.length==0"-->
+ <!--ng-show="state.mode=='edit'"><i class="fa fa-plus"> Extended Column On Fact Table</i>-->
+ <!--</button>-->
</div>
</div>
</div>
@@ -248,7 +289,7 @@
<script type="text/ng-template" id="nextParameter.html">
<div class="modal-header">
- <h4 tooltip="submit" ng-if="newmea.measure&&newmea.measure.function.expression !== 'TOP_N'">Add Parameter</h4>
+ <h4 tooltip="submit" ng-if="newmea.measure&&newmea.measure.function.expression == 'EXTENDED_COLUMN'">Add Extended Column</h4>
<h4 tooltip="submit" ng-if="newmea.measure&&newmea.measure.function.expression == 'TOP_N'">Select Group By Column</h4>
</div>
<div class="modal-body" style="background-color: white">
@@ -258,7 +299,7 @@
<div class="col-md-8">
<div class="row">
<div class="form-group">
- <div class="row" ng-if="newmea.measure&&newmea.measure.function.expression !== 'TOP_N'">
+ <div class="row" ng-if="newmea.measure&&newmea.measure.function.expression !== 'TOP_N' && newmea.measure.function.expression !== 'EXTENDED_COLUMN'">
<label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Param Type</b></label>
<div class="col-xs-12 col-sm-6">
<select class="form-control"
@@ -280,7 +321,7 @@
<div class="row">
<div class="form-group">
- <div ng-if="newmea.measure&&newmea.measure.function.expression !== 'TOP_N'" class="row">
+ <div ng-if="newmea.measure&&newmea.measure.function.expression !== 'TOP_N' && newmea.measure.function.expression !== 'EXTENDED_COLUMN" class="row">
<label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Param Value</b></label>
<!--COUNT_DISTINCT-->
<div class="col-xs-12 col-sm-6">
@@ -301,12 +342,23 @@
<div class="col-xs-12 col-sm-6">
<select class="form-control" chosen
ng-model="nextPara.value"
- ng-options="column as column for column in getCommonMetricColumns(newmea.measure)" >
+ ng-options="column as column for column in getExtendedColumns(newmea.measure)" >
<option value=""></option>
</select>
</div>
</div>
+ <div ng-if="newmea.measure&&newmea.measure.function.expression == 'EXTENDED_COLUMN'" ng-init="nextPara.type='column'" class="row">
+ <label class="col-xs-12 col-sm-4 control-label no-padding-right font-color-default"><b>Extended Column On Fact Table</b></label>
+ <!--COUNT_DISTINCT-->
+ <div class="col-xs-12 col-sm-6">
+ <select class="form-control" chosen
+ ng-model="nextPara.value"
+ ng-options="column as column for column in getExtendedColumns(newmea.measure)" >
+ <option value=""></option>
+ </select>
+ </div>
+ </div>
</div>
</div>
@@ -329,3 +381,23 @@
<li>Distinct Count is approximate, please indicate Error Rate, higher accuracy degree accompanied with larger storage size and longer build time</li>
</ol>
</script>
+
+<script type="text/ng-template" id="extendedTypeTip.html">
+ <p>
+ Kylin won\u2019t save more than this number of bytes for each extended column. If exceeded it will be truncated.
+ </p>
+</script>
+
+<script type="text/ng-template" id="topnTip.html">
+ <p>Will use this column for SUM and Order by</p>
+</script>
+
+<script type="text/ng-template" id="hostTableTip.html">
+ <p>Host column is the dimension to derive from, e.g. page_id</p>
+</script>
+<script type="text/ng-template" id="extendedColumnTip.html">
+ <p>
+ Extended column is derived from host, e.g. page_url. No filters on extended column!
+ </p>
+</script>
+