KYLIN-2308 Allow user to set more columnFamily in web Signed-off-by: zhongjian <jiat...@163.com>
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/8331d8d0 Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/8331d8d0 Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/8331d8d0 Branch: refs/heads/master-hbase1.x Commit: 8331d8d0ad37d24bdbfa90d1032bcdd063aa0a59 Parents: a853a7c Author: kangkaisen <kangkai...@live.com> Authored: Sat Jan 7 15:34:57 2017 +0800 Committer: zhongjian <jiat...@163.com> Committed: Fri Jan 20 17:25:28 2017 +0800 ---------------------------------------------------------------------- webapp/app/js/controllers/cubeAdvanceSetting.js | 75 +++++++++++++++- webapp/app/js/controllers/cubeEdit.js | 51 ----------- webapp/app/js/controllers/cubeSchema.js | 13 +++ webapp/app/js/filters/filter.js | 22 +++-- .../cubeDesigner/advanced_settings.html | 92 +++++++++++++++++++- 5 files changed, 194 insertions(+), 59 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/8331d8d0/webapp/app/js/controllers/cubeAdvanceSetting.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeAdvanceSetting.js b/webapp/app/js/controllers/cubeAdvanceSetting.js index 760133a..39d36b0 100644 --- a/webapp/app/js/controllers/cubeAdvanceSetting.js +++ b/webapp/app/js/controllers/cubeAdvanceSetting.js @@ -278,11 +278,84 @@ KylinApp.controller('CubeAdvanceSettingCtrl', function ($scope, $modal,cubeConfi $scope.isReuse=!$scope.isReuse; } - $scope.removeDictionaries = function(arr,element){ + $scope.removeElement = function(arr,element){ var index = arr.indexOf(element); if (index > -1) { arr.splice(index, 1); } }; + $scope.newColFamily = function (index) { + return { + "name": "F" + index, + "columns": [ + { + "qualifier": "M", + "measure_refs": [] + } + ] + }; + }; + + $scope.initColumnFamily = function () { + $scope.cubeMetaFrame.hbase_mapping.column_family = []; + var normalMeasures = [], distinctCountMeasures = []; + angular.forEach($scope.cubeMetaFrame.measures, function (measure, index) { + if (measure.function.expression === 'COUNT_DISTINCT') { + distinctCountMeasures.push(measure); + } else { + normalMeasures.push(measure); + } + }); + if (normalMeasures.length > 0) { + var nmcf = $scope.newColFamily(1); + angular.forEach(normalMeasures, function (normalM, index) { + nmcf.columns[0].measure_refs.push(normalM.name); + }); + $scope.cubeMetaFrame.hbase_mapping.column_family.push(nmcf); + } + + if (distinctCountMeasures.length > 0) { + var dccf = $scope.newColFamily(2); + angular.forEach(distinctCountMeasures, function (dcm, index) { + dccf.columns[0].measure_refs.push(dcm.name); + }); + $scope.cubeMetaFrame.hbase_mapping.column_family.push(dccf); + } + }; + + $scope.getAllMeasureNames = function () { + var measures = []; + angular.forEach($scope.cubeMetaFrame.measures, function (measure, index) { + measures.push(measure.name); + }); + return measures; + }; + + $scope.getAssignedMeasureNames = function () { + var assignedMeasures = []; + angular.forEach($scope.cubeMetaFrame.hbase_mapping.column_family, function (colFamily, index) { + angular.forEach(colFamily.columns[0].measure_refs, function (measure, index) { + assignedMeasures.push(measure); + }); + }); + return assignedMeasures; + }; + + if ($scope.getAllMeasureNames().length != $scope.getAssignedMeasureNames().length) { + $scope.initColumnFamily(); + } + + + $scope.addColumnFamily = function () { + var colFamily = $scope.newColFamily($scope.cubeMetaFrame.hbase_mapping.column_family.length + 1); + $scope.cubeMetaFrame.hbase_mapping.column_family.push(colFamily); + }; + + $scope.refreshColumnFamily = function (column_familys, index, colFamily) { + if (column_familys) { + column_familys[index] = colFamily; + } + }; + }); http://git-wip-us.apache.org/repos/asf/kylin/blob/8331d8d0/webapp/app/js/controllers/cubeEdit.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeEdit.js b/webapp/app/js/controllers/cubeEdit.js index edbb421..da19b22 100755 --- a/webapp/app/js/controllers/cubeEdit.js +++ b/webapp/app/js/controllers/cubeEdit.js @@ -284,25 +284,6 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio return type; }; - var ColFamily = function () { - var index = 1; - return function () { - var newColFamily = - { - "name": "f" + index, - "columns": [ - { - "qualifier": "m", - "measure_refs": [] - } - ] - }; - index += 1; - - return newColFamily; - } - }; - // ~ Define data $scope.state = { @@ -380,8 +361,6 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio $scope.prepareCube = function () { - //generate column family - generateColumnFamily(); //generate rowkey reGenerateRowKey(); @@ -793,36 +772,6 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio return groups; } - - // ~ private methods - function generateColumnFamily() { - $scope.cubeMetaFrame.hbase_mapping.column_family = []; - var colFamily = ColFamily(); - var normalMeasures = [], distinctCountMeasures = []; - angular.forEach($scope.cubeMetaFrame.measures, function (measure, index) { - if (measure.function.expression === 'COUNT_DISTINCT') { - distinctCountMeasures.push(measure); - } else { - normalMeasures.push(measure); - } - }); - if (normalMeasures.length > 0) { - var nmcf = colFamily(); - angular.forEach(normalMeasures, function (normalM, index) { - nmcf.columns[0].measure_refs.push(normalM.name); - }); - $scope.cubeMetaFrame.hbase_mapping.column_family.push(nmcf); - } - - if (distinctCountMeasures.length > 0) { - var dccf = colFamily(); - angular.forEach(distinctCountMeasures, function (dcm, index) { - dccf.columns[0].measure_refs.push(dcm.name); - }); - $scope.cubeMetaFrame.hbase_mapping.column_family.push(dccf); - } - } - $scope.$watch('projectModel.selectedProject', function (newValue, oldValue) { if(!$scope.projectModel.getSelectedProject()) { return; http://git-wip-us.apache.org/repos/asf/kylin/blob/8331d8d0/webapp/app/js/controllers/cubeSchema.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeSchema.js b/webapp/app/js/controllers/cubeSchema.js index af8ee7c..17371f2 100755 --- a/webapp/app/js/controllers/cubeSchema.js +++ b/webapp/app/js/controllers/cubeSchema.js @@ -275,6 +275,19 @@ KylinApp.controller('CubeSchemaCtrl', function ($scope, QueryService, UserServic errors.push("At most one 'shard by' column is allowed."); } + var cfMeasures = []; + angular.forEach($scope.cubeMetaFrame.hbase_mapping.column_family,function(cf){ + angular.forEach(cf.columns[0].measure_refs, function (measure, index) { + cfMeasures.push(measure); + }); + }); + + var uniqCfMeasures = _.uniq(cfMeasures); + if(uniqCfMeasures.length != $scope.cubeMetaFrame.measures.length) { + errors.push("All measures need to be assigned to column family"); + } + + var errorInfo = ""; angular.forEach(errors,function(item){ errorInfo+="\n"+item; http://git-wip-us.apache.org/repos/asf/kylin/blob/8331d8d0/webapp/app/js/filters/filter.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/filters/filter.js b/webapp/app/js/filters/filter.js index aff4e3a..d097075 100755 --- a/webapp/app/js/filters/filter.js +++ b/webapp/app/js/filters/filter.js @@ -193,16 +193,26 @@ KylinApp }).filter('inDimNotInMea', function ($filter) { return function (inputArr, table, arr) { var out=[]; - angular.forEach(arr,function(item){ - if(item.table==table){ - angular.forEach(inputArr,function(inputItem){ - if(item.columns.indexOf(inputItem.name)==-1){ + angular.forEach(arr,function(item) { + if (item.table == table) { + angular.forEach(inputArr, function (inputItem) { + if (item.columns.indexOf(inputItem.name) == -1) { out.push(inputItem); } }); } }); + } + }).filter('assignedMeasureNames', function ($filter) { + //return the measures that haven't assign to column family + return function (inputArr, assignedArr) { + var out = []; + angular.forEach(inputArr, function (inputItem) { + if (assignedArr.indexOf(inputItem) == -1) { + out.push(inputItem); + } + }); return out; } - }) - ; + }); + http://git-wip-us.apache.org/repos/asf/kylin/blob/8331d8d0/webapp/app/partials/cubeDesigner/advanced_settings.html ---------------------------------------------------------------------- diff --git a/webapp/app/partials/cubeDesigner/advanced_settings.html b/webapp/app/partials/cubeDesigner/advanced_settings.html index f9e422c..bf95256 100755 --- a/webapp/app/partials/cubeDesigner/advanced_settings.html +++ b/webapp/app/partials/cubeDesigner/advanced_settings.html @@ -302,7 +302,7 @@ <i class="fa fa-pencil"></i> </button> <!--Remove Button --> - <button class="btn btn-xs btn-danger" ng-click="removeDictionaries(cubeMetaFrame.dictionaries, dictionaries)" ng-disabled="instance.status=='READY'"> + <button class="btn btn-xs btn-danger" ng-click="removeElement(cubeMetaFrame.dictionaries, dictionaries)" ng-disabled="instance.status=='READY'"> <i class="fa fa-trash-o"></i> </button> </td> @@ -388,6 +388,89 @@ <button class="btn btn-link" ng-click="clearNewDictionaries()">Cancel</button> </div> </div> + + <!--Edit ColumnFamily--> + <div class="form-group large-popover" style="overflow:auto"> + <h3 style="margin-left:42px">Advanced ColumnFamily <i kylinpopover placement="right" title="Advanced ColumnFamily" template="AdvancedColumnFamilyTip.html" class="fa fa-info-circle"></i></h3> + <div style="margin-left:42px"> + <div class="box-body"> + <!-- VIEW MODE --> + <div class="row" ng-if="state.mode=='view'&& cubeMetaFrame.hbase_mapping.column_family.length > 0"> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th class="col-xs-1">CF</th> + <th class="col-xs-11">Measures</th> + </tr> + </thead> + <tbody class="cube-dimension"> + <tr ng-repeat="colFamily in cubeMetaFrame.hbase_mapping.column_family | filter:dimState.filter track by $index"> + <!--ID --> + <td class="col-xs-1"> + <b>{{colFamily.name}}</b> + </td> + <!--Name --> + <td class="col-xs-11"> + <span>{{colFamily.columns[0].measure_refs}}</span> + </td> + </tr> + </tbody> + </table> + </div> + + <!-- EDIT MODE --> + <div ng-if="state.mode=='edit'" class="form-group " style="width: 100%"> + <table ng-if="cubeMetaFrame.hbase_mapping.column_family.length > 0" + class="table table-hover"> + + <tr class="row"> + <th class="col-xs-1">CF</th> + <th class="col-xs-10">Measures</th> + <th class="col-xs-1">Actions</th> + </tr> + + <tr ng-repeat="colFamily in cubeMetaFrame.hbase_mapping.column_family" ng-init="rowIndex = $index" class="row"> + <td class="col-xs-1"> + <b>{{colFamily.name}}</b> + </td> + + <td class="col-xs-10"> + <ui-select + ng-if="state.mode=='edit'" + style="width: 100%" + autofocus="true" + close-on-select="false" + on-select="refreshColumnFamily(cubeMetaFrame.hbase_mapping.column_family, rowIndex, colFamily)" + on-remove="refreshColumnFamily(cubeMetaFrame.hbase_mapping.column_family, rowIndex, colFamily)" + ng-model="colFamily.columns[0].measure_refs" + multiple> + <ui-select-match placeholder="Select Measure...">{{$item}}</ui-select-match> + <ui-select-choices repeat="measure in getAllMeasureNames() | filter:$select.search |assignedMeasureNames:getAssignedMeasureNames()"> + {{measure}} + </ui-select-choices> + </ui-select> + </td> + + <td class="col-xs-1"> + <!--Remove Button --> + <button class="btn btn-xs btn-info" ng-click="removeElement(cubeMetaFrame.hbase_mapping.column_family, colFamily)"> + <i class="fa fa-minus"></i> + </button> + </td> + + </tr> + </table> + </div> + + <div class="form-group" > + <button class="btn btn-sm btn-info" ng-click="addColumnFamily()" ng-show="state.mode=='edit'"> + <i class="fa fa-plus"></i> ColumnFamily + </button> + </div> + + </div> + </div> + </div> </ng-form> </div> </ng-form> @@ -419,3 +502,10 @@ <h4>Special settings for dictionaries. Leave blank by default.</h4> </div> </script> + +<script type="text/ng-template" id="AdvancedColumnFamilyTip.html"> + <div> + <h4>If there are more than one ultrahigh cardinality precise count distinct measures, + you could assign these measures to more column family.</h4> + </div> +</script>