Repository: kylin Updated Branches: refs/heads/2.x-staging 26c84f737 -> 4d4e743c7
KYLIN-1220 UI CUBE Schema Update Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/4d4e743c Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/4d4e743c Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/4d4e743c Branch: refs/heads/2.x-staging Commit: 4d4e743c727c44a7166b6b160e296e7e791496e2 Parents: 26c84f7 Author: jian <jiazh...@apache.org> Authored: Mon Jan 4 19:51:25 2016 +0800 Committer: jian <jiazh...@apache.org> Committed: Mon Jan 4 19:51:58 2016 +0800 ---------------------------------------------------------------------- webapp/app/index.html | 1 - webapp/app/js/controllers/cubeAdvanceSetting.js | 118 +++++- webapp/app/js/controllers/cubeDimensions.js | 73 ++-- webapp/app/js/controllers/cubeEdit.js | 160 ++------ webapp/app/js/controllers/cubeSchema.js | 4 +- webapp/app/js/model/cubeConfig.js | 2 +- webapp/app/js/model/cubeDescModel.js | 28 +- .../cubeDesigner/advanced_settings.html | 396 ++++++++++++------- .../app/partials/cubeDesigner/dimensions.html | 15 +- webapp/app/partials/cubeDesigner/measures.html | 20 +- 10 files changed, 466 insertions(+), 351 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/4d4e743c/webapp/app/index.html ---------------------------------------------------------------------- diff --git a/webapp/app/index.html b/webapp/app/index.html index 6e5d463..f02c0a7 100644 --- a/webapp/app/index.html +++ b/webapp/app/index.html @@ -161,7 +161,6 @@ <script src="js/controllers/job.js"></script> <script src="js/controllers/cube.js"></script> <script src="js/controllers/cubes.js"></script> -<script src="js/controllers/streaming.js"></script> <script src="js/controllers/projects.js"></script> <script src="js/controllers/cubeEdit.js"></script> <script src="js/controllers/cubeSchema.js"></script> http://git-wip-us.apache.org/repos/asf/kylin/blob/4d4e743c/webapp/app/js/controllers/cubeAdvanceSetting.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeAdvanceSetting.js b/webapp/app/js/controllers/cubeAdvanceSetting.js index fc02c6e..e87935a 100644 --- a/webapp/app/js/controllers/cubeAdvanceSetting.js +++ b/webapp/app/js/controllers/cubeAdvanceSetting.js @@ -18,16 +18,9 @@ 'use strict'; -KylinApp.controller('CubeAdvanceSettingCtrl', function ($scope, $modal,cubeConfig,MetaModel,cubesManager) { +KylinApp.controller('CubeAdvanceSettingCtrl', function ($scope, $modal,cubeConfig,MetaModel,cubesManager,CubeDescModel) { $scope.cubesManager = cubesManager; - //convert some undefined or null value - angular.forEach($scope.cubeMetaFrame.rowkey.rowkey_columns,function(rowkey){ - if(!rowkey.dictionary){ - rowkey.dictionary = "false"; - } - } - ); //edit model if($scope.state.mode==="edit") { $scope.metaModel = MetaModel; @@ -57,13 +50,25 @@ KylinApp.controller('CubeAdvanceSettingCtrl', function ($scope, $modal,cubeConfi }) } + //rowkey + $scope.convertedRowkeys = []; + angular.forEach($scope.cubeMetaFrame.rowkey.rowkey_columns,function(item){ + var _isDictionary = item.encoding === "dict"?"true":"false"; + var _isFixedLength = item.encoding.substring(0,12) === "fixed_length"?"true":"false";//fixed_length:12 + var _fixedLength ; + if(_isFixedLength){ + _fixedLength = item.encoding.substring(12,item.encoding.length); + } + var rowkeyObj = { + column:item.column, + isDictionary:_isDictionary, + isFixedLength:_isFixedLength, + fixedLength:_fixedLength + } - $scope.dictionaryUpdated = function(rowkey_column){ - if(rowkey_column.dictionary==="true"){ - rowkey_column.length=0; - } + $scope.convertedRowkeys.push(rowkeyObj); - } + }) $scope.addNewMergeTimeRange = function(){ $scope._auto_merge_time_ranges.push({ @@ -98,24 +103,86 @@ KylinApp.controller('CubeAdvanceSettingCtrl', function ($scope, $modal,cubeConfi }) } + $scope.refreshRowKey = function(list,index,item){ + var encoding = "dict"; + var column = item.column; + if(item.isDictionary!=="true"){ + if(item.fixedLength){ + encoding = "fixed_length:"+item.fixedLength; + } + } + $scope.cubeMetaFrame.rowkey.rowkey_columns[index].column = column; + $scope.cubeMetaFrame.rowkey.rowkey_columns[index].encoding = encoding; + + } + + $scope.removeRowkey = function(arr,index,item){ + if (index > -1) { + arr.splice(index, 1); + } + $scope.cubeMetaFrame.rowkey.rowkey_columns.splice(index,1); + } + $scope.addNewRowkeyColumn = function () { + var rowkeyObj = { + column:"", + isDictionary:"true", + isFixedLength:"false", + fixedLength:0 + } + + $scope.convertedRowkeys.push(rowkeyObj); $scope.cubeMetaFrame.rowkey.rowkey_columns.push({ - "column": "", - "length": 0, - "dictionary": "true", - "mandatory": false + column:'', + encoding:'dict' }); + }; + $scope.addNewHierarchy = function(grp){ + grp.select_rule.hierarchy_dims.push([]); + } + + $scope.addNewJoint = function(grp){ + grp.select_rule.joint_dims.push([]); + } + //to do, agg update $scope.addNewAggregationGroup = function () { - $scope.cubeMetaFrame.rowkey.aggregation_groups.push([]); + $scope.cubeMetaFrame.aggregation_groups.push(CubeDescModel.createAggGroup()); }; $scope.refreshAggregationGroup = function (list, index, aggregation_groups) { if (aggregation_groups) { list[index] = aggregation_groups; } + console.log($scope.cubeMetaFrame.aggregation_groups); + }; + + $scope.refreshAggregationHierarchy = function (list, index, aggregation_group,hieIndex,hierarchy) { + if(hierarchy){ + aggregation_group.select_rule.hierarchy_dims[hieIndex] = hierarchy; + } + if (aggregation_group) { + list[index] = aggregation_group; + } + console.log($scope.cubeMetaFrame.aggregation_groups); + }; + + $scope.refreshAggregationJoint = function (list, index, aggregation_group,joinIndex,jointDim){ + if(jointDim){ + aggregation_group.select_rule.joint_dims[joinIndex] = jointDim; + } + if (aggregation_group) { + list[index] = aggregation_group; + } + console.log($scope.cubeMetaFrame.aggregation_groups); + }; + + $scope.refreshIncludes = function (list, index, aggregation_groups) { + if (aggregation_groups) { + list[index] = aggregation_groups; + } }; $scope.removeElement = function (arr, element) { @@ -125,5 +192,20 @@ KylinApp.controller('CubeAdvanceSettingCtrl', function ($scope, $modal,cubeConfi } }; + $scope.removeHierarchy = function(arr,element){ + var index = arr.select_rule.hierarchy_dims.indexOf(element); + if(index>-1){ + arr.select_rule.hierarchy_dims.splice(index,1); + } + + } + + $scope.removeJointDims = function(arr,element){ + var index = arr.select_rule.joint_dims.indexOf(element); + if(index>-1){ + arr.select_rule.joint_dims.splice(index,1); + } + + } }); http://git-wip-us.apache.org/repos/asf/kylin/blob/4d4e743c/webapp/app/js/controllers/cubeDimensions.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeDimensions.js b/webapp/app/js/controllers/cubeDimensions.js index 423445b..1c92616 100644 --- a/webapp/app/js/controllers/cubeDimensions.js +++ b/webapp/app/js/controllers/cubeDimensions.js @@ -34,8 +34,7 @@ KylinApp.controller('CubeDimensionsCtrl', function ($scope, $modal,MetaModel,cub /** * Helper func to get columns that dimensions based on, three cases: * 1. normal dimension: column array. - * 2. hierarchy dimension: column array, the array index is the hierarchy level. - * 3. derived dimension: derived columns array. + * 2. derived dimension: derived columns array. * TODO new cube schema change */ var dimCols = function (dim) { @@ -47,12 +46,12 @@ KylinApp.controller('CubeDimensionsCtrl', function ($scope, $modal,MetaModel,cub } // Case 2. - if (dim.hierarchy && dim.column.length) { - referredCols = referredCols.concat(dim.column); - } + //if (dim.hierarchy && dim.column.length) { + // referredCols = referredCols.concat(dim.column); + //} // Case 1. - if (!dim.derived && !dim.hierarchy) { + if (!dim.derived && dim.column) { referredCols.push(dim.column); } @@ -138,7 +137,7 @@ KylinApp.controller('CubeDimensionsCtrl', function ($scope, $modal,MetaModel,cub // Init the dimension, dimension name default as the column key. TODO new cube schema change. var Dimension = function (table, selectedCols, dimType) { - var origin = {name: '', table: table,hierarchy:false,derived:null,column:null}; + var origin = {name: '', table: table,derived:null,column:null}; switch (dimType) { case 'normal': @@ -147,7 +146,7 @@ KylinApp.controller('CubeDimensionsCtrl', function ($scope, $modal,MetaModel,cub origin.name = table + '.' + selectedCols[0]; } - origin.column = selectedCols; + origin.column = selectedCols[0]; break; case 'derived': @@ -158,14 +157,14 @@ KylinApp.controller('CubeDimensionsCtrl', function ($scope, $modal,MetaModel,cub origin.derived = selectedCols; break; - case 'hierarchy': - if (table && selectedCols.length) { - origin.name = table + '_hierarchy'; - } - - origin.hierarchy = true; - origin.column = selectedCols; - break; + //case 'hierarchy': + // if (table && selectedCols.length) { + // origin.name = table + '_hierarchy'; + // } + // + // origin.hierarchy = true; + // origin.column = selectedCols; + // break; } return origin; @@ -179,9 +178,9 @@ KylinApp.controller('CubeDimensionsCtrl', function ($scope, $modal,MetaModel,cub types.push('derived'); } - if (dim.hierarchy && dim.column.length) { - types.push('hierarchy'); - } + //if (dim.hierarchy && dim.column.length) { + // types.push('hierarchy'); + //} if (!types.length) { types.push('normal'); @@ -235,24 +234,24 @@ KylinApp.controller('CubeDimensionsCtrl', function ($scope, $modal,MetaModel,cub var errors = []; // null validate - if($scope.dimType[0]=="hierarchy"){ - if($scope.newDimension.column.length<2){ - errors.push("Please define at least 2 hierarchy columns."); - }else{ - for(var i = 0;i<$scope.newDimension.column.length;i++){ - if($scope.newDimension.column[i]===""){ - errors.push("Hierarchy value can't be null."); - break; - } - } - var _columns = angular.copy($scope.newDimension.column).sort(); - for(var i = 0;i<_columns.length-1;i++){ - if(_columns[i]==_columns[i+1]&&_columns[i]!==""){ - errors.push("Duplicate column "+_columns[i]+"."); - } - } - } - } + //if($scope.dimType[0]=="hierarchy"){ + // if($scope.newDimension.column.length<2){ + // errors.push("Please define at least 2 hierarchy columns."); + // }else{ + // for(var i = 0;i<$scope.newDimension.column.length;i++){ + // if($scope.newDimension.column[i]===""){ + // errors.push("Hierarchy value can't be null."); + // break; + // } + // } + // var _columns = angular.copy($scope.newDimension.column).sort(); + // for(var i = 0;i<_columns.length-1;i++){ + // if(_columns[i]==_columns[i+1]&&_columns[i]!==""){ + // errors.push("Duplicate column "+_columns[i]+"."); + // } + // } + // } + //} if($scope.dimType[0]=="derived"){ if(!$scope.newDimension.derived.length){ http://git-wip-us.apache.org/repos/asf/kylin/blob/4d4e743c/webapp/app/js/controllers/cubeEdit.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeEdit.js b/webapp/app/js/controllers/cubeEdit.js index fd38f04..f397d49 100755 --- a/webapp/app/js/controllers/cubeEdit.js +++ b/webapp/app/js/controllers/cubeEdit.js @@ -241,6 +241,8 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio $scope.state.project = ProjectModel.getSelectedProject(); // delete $scope.cubeMetaFrame.project; + + $scope.state.cubeSchema = angular.toJson($scope.cubeMetaFrame, true); //streaming meta @@ -465,7 +467,7 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio $scope.updateMandatory = function (rowkey_column) { if (!rowkey_column.mandatory) { - angular.forEach($scope.cubeMetaFrame.rowkey.aggregation_groups, function (group, index) { + angular.forEach($scope.cubeMetaFrame.aggregation_groups, function (group, index) { var index = group.indexOf(rowkey_column.column); if (index > -1) { group.splice(index, 1); @@ -476,19 +478,12 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio function reGenerateRowKey() { $log.log("reGen rowkey & agg group"); - var fk_pk = {}; + //var fk_pk = {}; var tmpRowKeyColumns = []; var tmpAggregationItems = [];//put all aggregation item - var hierarchyItemArray = [];//put all hierarchy items + //var hierarchyItemArray = [];//put all hierarchy items angular.forEach($scope.cubeMetaFrame.dimensions, function (dimension, index) { - // build fk_pk map - angular.forEach($scope.metaModel.model.lookups, function (_lookup, index) { - for (var i = 0; i < _lookup.join.foreign_key.length; i++) { - fk_pk[_lookup.join.primary_key[i]] = _lookup.join.foreign_key[i]; - } - }); - //derived column if (dimension.derived && dimension.derived.length) { var lookup = _.find($scope.metaModel.model.lookups, function (lookup) { @@ -503,9 +498,7 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio if (i == tmpRowKeyColumns.length) { tmpRowKeyColumns.push({ "column": fk, - "length": 0, - "dictionary": "true", - "mandatory": false + "encoding": "dict" }); tmpAggregationItems.push(fk); @@ -514,63 +507,20 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio } //normal column - else if (dimension.column && !dimension.hierarchy && dimension.column.length == 1) { + else if (dimension.column && !dimension.derived) { for (var i = 0; i < tmpRowKeyColumns.length; i++) { - if (tmpRowKeyColumns[i].column == dimension.column[0]) + if (tmpRowKeyColumns[i].column == dimension.column) break; } if (i == tmpRowKeyColumns.length) { tmpRowKeyColumns.push({ - "column": dimension.column[0], - "length": 0, - "dictionary": "true", - "mandatory": false + "column": dimension.column, + "encoding": "dict" }); - tmpAggregationItems.push(dimension.column[0]); + tmpAggregationItems.push(dimension.column); } } - // hierarchy - if (dimension.hierarchy && dimension.column.length) { - var hierarchyUnit = []; - angular.forEach(dimension.column, function (hier_column, index) { - - //use fk instead of fk as rowkey and aggregation item in hierarchy - if (hier_column in fk_pk) { - hier_column = fk_pk[hier_column]; - } - - for (var i = 0; i < tmpRowKeyColumns.length; i++) { - if (tmpRowKeyColumns[i].column == hier_column) - break; - } - if (i == tmpRowKeyColumns.length) { - tmpRowKeyColumns.push({ - "column": hier_column, - "length": 0, - "dictionary": "true", - "mandatory": false - }); - tmpAggregationItems.push(hier_column); - } - if (hierarchyUnit.indexOf(hier_column) == -1) { - hierarchyUnit.push(hier_column); - } - }); - if (hierarchyUnit.length) { - hierarchyItemArray.push(hierarchyUnit); - } - } - - }); - - //rm mandatory column from aggregation item - angular.forEach($scope.cubeMetaFrame.rowkey.rowkey_columns, function (value, index) { - if (value.mandatory) { - tmpAggregationItems = _.filter(tmpAggregationItems, function (item) { - return item != value.column; - }); - } }); var rowkeyColumns = $scope.cubeMetaFrame.rowkey.rowkey_columns; @@ -582,27 +532,23 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio $scope.cubeMetaFrame.rowkey.rowkey_columns = newRowKeyColumns; if ($scope.cubeMode === "editExistCube") { - var aggregationGroups = $scope.cubeMetaFrame.rowkey.aggregation_groups; + var aggregationGroups = $scope.cubeMetaFrame.aggregation_groups; // rm unused item from group,will only rm when [edit] dimension angular.forEach(aggregationGroups, function (group, index) { if (group) { - for (var j = 0; j < group.length; j++) { + for (var j = 0; j < group.includes.length; j++) { var elemStillExist = false; for (var k = 0; k < tmpAggregationItems.length; k++) { - if (group[j] == tmpAggregationItems[k]) { + if (group.includes[j] == tmpAggregationItems[k]) { elemStillExist = true; break; } } if (!elemStillExist) { - group.splice(j, 1); + group.includes.splice(j, 1); j--; } } - if (!group.length) { - aggregationGroups.splice(index, 1); - index--; - } } else { aggregationGroups.splice(index, 1); @@ -612,9 +558,14 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio } if ($scope.cubeMode === "addNewCube") { + //only first time will after edit model will generate agg group auto + if($scope.cubeMetaFrame.aggregation_groups.length){ + return; + } + if (!tmpAggregationItems.length) { - $scope.cubeMetaFrame.rowkey.aggregation_groups = []; + $scope.cubeMetaFrame.aggregation_groups = []; return; } @@ -625,70 +576,13 @@ KylinApp.controller('CubeEditCtrl', function ($scope, $q, $routeParams, $locatio } }); - //distinct hierarchyItem - var hierarchyItems = hierarchyItemArray.join().split(","); - var _hierarchyItems = []; - angular.forEach(hierarchyItems, function (item, index) { - if (_hierarchyItems.indexOf(item) == -1) { - _hierarchyItems.push(item); - } - }); - hierarchyItems = _hierarchyItems; - - var unHierarchyItems = increasedData(hierarchyItems, newUniqAggregationItem); - //hierarchyItems - var increasedDataGroups = sliceGroupItemToGroups(unHierarchyItems); - if (!hierarchyItemArray.length) { - $scope.cubeMetaFrame.rowkey.aggregation_groups = increasedDataGroups; - return; - } - ; - - var lastAggregationGroup = increasedDataGroups.length === 0 ? [] : increasedDataGroups[increasedDataGroups.length - 1]; - - if (lastAggregationGroup.length < 10) { - if (lastAggregationGroup.length + hierarchyItemArray.length <= 10) { - lastAggregationGroup = lastAggregationGroup.concat(hierarchyItems); - if (increasedDataGroups.length == 0) { - //case only hierarchy - increasedDataGroups[0] = lastAggregationGroup; - } else { - increasedDataGroups[increasedDataGroups.length - 1] = lastAggregationGroup; - } - } - else { - var cutIndex = 10 - lastAggregationGroup.length; - var partialHierarchy = hierarchyItemArray.slice(0, cutIndex).join().split(","); - //add hierarchy to last group and make sure length less than 10 - lastAggregationGroup = lastAggregationGroup.concat(partialHierarchy); - increasedDataGroups[increasedDataGroups.length - 1] = lastAggregationGroup; - var leftHierarchy = hierarchyItemArray.slice(cutIndex); - - var leftHierarchyLength = leftHierarchy.length; - var grpLength = parseInt(leftHierarchyLength / 10); - if (leftHierarchyLength % 10 == 0 && leftHierarchyLength != 0) { - grpLength--; - } - for (var i = 0; i <= grpLength; i++) { - var hierAggGroupUnit = leftHierarchy.slice(i * 10, (i + 1) * 10).join().split(","); - increasedDataGroups.push(hierAggGroupUnit); - } - } - } - //lastAggregationGroup length >=10 - else { - var hierrachyArrayLength = hierarchyItemArray.length; - var grpLength = parseInt(hierrachyArrayLength / 10); - if (hierrachyArrayLength % 10 == 0 && hierrachyArrayLength != 0) { - grpLength--; - } - for (var i = 0; i <= grpLength; i++) { - var hierAggGroupUnit = hierarchyItemArray.slice(i * 10, (i + 1) * 10).join().split(","); - increasedDataGroups.push(hierAggGroupUnit); - } + $scope.cubeMetaFrame.aggregation_groups = []; + var increasedDataGroups = sliceGroupItemToGroups(newUniqAggregationItem); + for(var i in increasedDataGroups){ + var newGroup = CubeDescModel.createAggGroup(); + newGroup.includes = increasedDataGroups[i]; + $scope.cubeMetaFrame.aggregation_groups.push(newGroup); } - //! here get the latest aggregation groups,only effect when add newCube - $scope.cubeMetaFrame.rowkey.aggregation_groups = increasedDataGroups; } } http://git-wip-us.apache.org/repos/asf/kylin/blob/4d4e743c/webapp/app/js/controllers/cubeSchema.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeSchema.js b/webapp/app/js/controllers/cubeSchema.js index 3501e6d..fc65ea6 100755 --- a/webapp/app/js/controllers/cubeSchema.js +++ b/webapp/app/js/controllers/cubeSchema.js @@ -261,8 +261,8 @@ KylinApp.controller('CubeSchemaCtrl', function ($scope, QueryService, UserServic $scope.check_cube_setting = function(){ var errors = []; - angular.forEach($scope.cubeMetaFrame.rowkey.aggregation_groups,function(group){ - if(!group.length){ + angular.forEach($scope.cubeMetaFrame.aggregation_groups,function(group){ + if(!group&&!group.includes){ errors.push("Each aggregation group can't be empty."); } }) http://git-wip-us.apache.org/repos/asf/kylin/blob/4d4e743c/webapp/app/js/model/cubeConfig.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/model/cubeConfig.js b/webapp/app/js/model/cubeConfig.js index a647b53..cc931d9 100644 --- a/webapp/app/js/model/cubeConfig.js +++ b/webapp/app/js/model/cubeConfig.js @@ -58,7 +58,7 @@ KylinApp.constant('cubeConfig', { queryPriority: {name: 'NORMAL', value: 50}, cubePartitionType: 'APPEND' }, - dictionaries: ["true", "false"], + dictionaries: ["true", "false"], // cubes config theaditems: [ http://git-wip-us.apache.org/repos/asf/kylin/blob/4d4e743c/webapp/app/js/model/cubeDescModel.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/model/cubeDescModel.js b/webapp/app/js/model/cubeDescModel.js index c9dfe56..8f69fcc 100644 --- a/webapp/app/js/model/cubeDescModel.js +++ b/webapp/app/js/model/cubeDescModel.js @@ -29,22 +29,23 @@ KylinApp.service('CubeDescModel', function () { "dimensions": [], "measures": [ { - "id": 1, "name": "_COUNT_", "function": { "expression": "COUNT", "returntype": "bigint", "parameter": { "type": "constant", - "value": "1" + "value": "1", + "next_parameter":null } } } ], "rowkey": { - "rowkey_columns": [], - "aggregation_groups": [] + "rowkey_columns": [] }, + "aggregation_groups": [] + , "notify_list": [], "hbase_mapping": { "column_family": [] @@ -60,14 +61,14 @@ KylinApp.service('CubeDescModel', function () { this.createMeasure = function () { var measure = { - "id": "", "name": "", "function": { "expression": "", "returntype": "", "parameter": { "type": "", - "value": "" + "value": "", + "next_parameter":null } } }; @@ -75,4 +76,19 @@ KylinApp.service('CubeDescModel', function () { return measure; } + this.createAggGroup = function () { + var group = { + "includes" : [], + "select_rule" : { + "hierarchy_dims" : [],//2 dim array + "mandatory_dims" : [], + "joint_dims" : [ ]//2 dim array + } + } + + return group; + } + + + }) http://git-wip-us.apache.org/repos/asf/kylin/blob/4d4e743c/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 222edf2..332d62f 100755 --- a/webapp/app/partials/cubeDesigner/advanced_settings.html +++ b/webapp/app/partials/cubeDesigner/advanced_settings.html @@ -29,49 +29,55 @@ <!--Cube Size--> <div class="form-group"> <div class="row"> - <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Auto Merge Time Ranges(days)</b></label> + <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Auto Merge Time + Ranges(days)</b></label> + <div class="col-xs-12 col-sm-6"> <!--retention range is store in CubeInstance, will convert to cubeMetaFrame for front end--> - <div class="row" ng-if="state.mode=='edit'"> + <div class="row" ng-if="state.mode=='edit'"> <table class="table"> <tbody> - <tr ng-repeat="timeRange in _auto_merge_time_ranges"> - <td class="col-xs-4"> - <select ng-if="timeRange.type=='hours'" - chosen ng-model="timeRange.range" - ng-options="rangeTypes as rangeTypes for rangeTypes in [0.5,1,2,4,8] " - ng-change="refreshAutoMergeTimeRanges(_auto_merge_time_ranges,$index,timeRange)" - style="width: 100% !important;" - data-placeholder="hours range" - class="chosen-select"> - </select> - <input type="text" ng-if="timeRange.type=='days'" ng-change="refreshAutoMergeTimeRanges(_auto_merge_time_ranges,$index,timeRange)" class="form-control input-sm" placeholder="days range" ng-model="timeRange.range"> - </td> - <td class="col-xs-4"> - <select chosen ng-model="timeRange.type" - ng-options="rangeTypes as rangeTypes for rangeTypes in ['hours','days'] " - ng-change="refreshAutoMergeTimeRanges(_auto_merge_time_ranges,$index,timeRange)" - style="width: 200px !important;" - data-placeholder="select a project" - class="chosen-select"> - </select> - </td> - <td> - <button class="btn btn-xs btn-info" ng-show="state.mode=='edit'" ng-click="removeTimeRange(_auto_merge_time_ranges,$index, timeRange)"> - <i class="fa fa-minus"></i> - </button> - </td> - </tr> + <tr ng-repeat="timeRange in _auto_merge_time_ranges track by $index"> + <td class="col-xs-4"> + <select ng-if="timeRange.type=='hours'" + chosen ng-model="timeRange.range" + ng-options="rangeTypes as rangeTypes for rangeTypes in [0.5,1,2,4,8] " + ng-change="refreshAutoMergeTimeRanges(_auto_merge_time_ranges,$index,timeRange)" + style="width: 100% !important;" + data-placeholder="hours range" + class="chosen-select"> + </select> + <input type="text" ng-if="timeRange.type=='days'" + ng-change="refreshAutoMergeTimeRanges(_auto_merge_time_ranges,$index,timeRange)" + class="form-control input-sm" placeholder="days range" ng-model="timeRange.range"> + </td> + <td class="col-xs-4"> + <select chosen ng-model="timeRange.type" + ng-options="rangeTypes as rangeTypes for rangeTypes in ['hours','days'] " + ng-change="refreshAutoMergeTimeRanges(_auto_merge_time_ranges,$index,timeRange)" + style="width: 200px !important;" + data-placeholder="select a project" + class="chosen-select"> + </select> + </td> + <td> + <button class="btn btn-xs btn-info" ng-show="state.mode=='edit'" + ng-click="removeTimeRange(_auto_merge_time_ranges,$index, timeRange)"> + <i class="fa fa-minus"></i> + </button> + </td> + </tr> </tbody> </table> - <button class="btn btn-xs btn-info" ng-show="state.mode=='edit'" ng-click="addNewMergeTimeRange()"> + <button class="btn btn-xs btn-info" ng-show="state.mode=='edit'" + ng-click="addNewMergeTimeRange()"> New Merge Range<i class="fa fa-plus"></i> </button> </div> - <div class="row" ng-if="state.mode=='view'"> + <div class="row" ng-if="state.mode=='view'"> <table class="table"> <tbody> - <tr ng-repeat="timeRange in cubeMetaFrame.auto_merge_time_ranges"> + <tr ng-repeat="timeRange in cubeMetaFrame.auto_merge_time_ranges track by $index"> <td> {{timeRange | timeRangeFormat}} </td> @@ -91,11 +97,17 @@ <!--Cube Size--> <div class="form-group"> <div class="row"> - <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Retention Range(days)</b></label> + <label class="control-label col-xs-12 col-sm-3 no-padding-right font-color-default"><b>Retention + Range(days)</b></label> + <div class="col-xs-12 col-sm-6"> <!--retention range is store in CubeInstance, will convert to cubeMetaFrame for front end--> - <input type="text" retention-format class="form-control ng-scope ng-pristine ng-valid" placeholder="how many days cube retention" ng-model="cubeMetaFrame.retention_range" ng-if="state.mode=='edit'"> - <small class="help-block text-red" ng-show="state.mode=='edit'">(by default it's '0',which will keep all historic cube segments ,or will keep latest [Retention Range] days cube segments )</small> + <input type="text" retention-format class="form-control ng-scope ng-pristine ng-valid" + placeholder="how many days cube retention" ng-model="cubeMetaFrame.retention_range" + ng-if="state.mode=='edit'"> + <small class="help-block text-red" ng-show="state.mode=='edit'">(by default it's '0',which will keep + all historic cube segments ,or will keep latest [Retention Range] days cube segments ) + </small> <span ng-if="state.mode=='view'">{{cubeMetaFrame.retention_range | millisecondsToDay}}</span> </div> </div> @@ -106,132 +118,236 @@ </div> - <div class="form-group"> - <h4 style="margin-left:42px">Aggregation Groups</h4> - <table style="margin-left:42px; width:92%" - ng-if="cubeMetaFrame.rowkey.aggregation_groups.length > 0" - class="table table-hover list"> + <div class="form-group"> + <h4 style="margin-left:42px">Aggregation Groups</h4> + <table style="margin-left:42px; width:92%" + ng-if="cubeMetaFrame.aggregation_groups.length > 0" + class="table table-hover list"> + <tr class="row"> + <th class="col-xs-1">ID</th> + <th class="col-xs-11">Aggregation Groups</th> + <th ng-if="state.mode=='edit'" class="col-xs-1"></th> + </tr> + + <tr ng-repeat="aggregation_group in cubeMetaFrame.aggregation_groups track by $index" ng-init="rowIndex = $index" class="row"> + <td class="col-xs-1"> + <!-- ID --> + <b>{{($index + 1)}}</b> + </td> + <td class="col-xs-11"> + <table class="table"> <tr class="row"> - <th class="col-xs-1">ID</th> - <th class="col-xs-10">Aggregation Groups</th> - <th ng-if="state.mode=='edit'" class="col-xs-1"></th> + <td class="col-xs-3"> + Includes + </td> + <td class="col-xs-8"> + <!-- Dimensions --> + <select ng-if="state.mode=='edit'" style="width: 100%" + ng-model="aggregation_group.includes" chosen multiple + ng-change="refreshAggregationGroup(cubeMetaFrame.aggregation_groups, rowIndex, aggregation_group)" + ng-options="rowkey_column.column as rowkey_column.column for rowkey_column in cubeMetaFrame.rowkey.rowkey_columns"> + <option value=""></option> + </select> + + <p ng-if="state.mode=='view'" style="word-wrap: break-word; word-break: normal;max-width: 1000px "> + {{aggregation_group.includes}}</p> + </td> + <td class="col-xs-1"> + </td> </tr> + <tr class="row"> + <td class="col-xs-3"> + Mandatory Dimensions + </td> + <td class="col-xs-8"> + <!-- Dimensions --> + <select ng-if="state.mode=='edit'" style="width: 100%" + ng-model="aggregation_group.select_rule.mandatory_dims" chosen multiple + ng-change="refreshAggregationGroup(cubeMetaFrame.aggregation_groups, rowIndex, aggregation_group)" + ng-options="column as column for column in aggregation_group.includes"> + <option value=""></option> + </select> + <p ng-if="state.mode=='view'" style="word-wrap: break-word; word-break: normal;max-width: 1000px "> + {{aggregation_group.select_rule.mandatory_dims}}</p> + </td> + <td class="col-xs-1"> + </td> + </tr> + - <tr ng-repeat="aggregation_groups in cubeMetaFrame.rowkey.aggregation_groups" class="row"> - <td class="col-xs-1"> - <!-- ID --> - <b>{{($index + 1)}}</b> - </td> - <td class="col-xs-11"> - <!-- Dimensions --> - <select ng-if="state.mode=='edit'" style="width: 100%" - ng-model="aggregation_groups" chosen multiple - ng-change="refreshAggregationGroup(cubeMetaFrame.rowkey.aggregation_groups, $index, aggregation_groups)" - ng-options="rowkey_column.column as rowkey_column.column for rowkey_column in cubeMetaFrame.rowkey.rowkey_columns"> + <tr class="row"> + <td class="col-xs-3"> + Hierarchy Dimensions + </td> + <td class="col-xs-9"> + <table class="table"> + <tr class="row" ng-repeat="hierarchyDims in aggregation_group.select_rule.hierarchy_dims track by $index"> + <td class="col-xs-10"> + <!-- Dimensions --> + <select ng-if="state.mode=='edit'" style="width: 100%" + ng-model="hierarchyDims" chosen multiple + ng-change="refreshAggregationHierarchy(cubeMetaFrame.aggregation_groups, rowIndex, aggregation_group,$index,hierarchyDims)" + ng-options="column as column for column in aggregation_group.includes"> <option value=""></option> - </select> - <p ng-if="state.mode=='view'" style="word-wrap: break-word; word-break: normal;max-width: 1000px ">{{aggregation_groups}}</p> - </td> - <td ng-if="state.mode=='edit'" class="col-xs-1"> - <button class="btn btn-xs btn-info" - ng-click="removeElement(cubeMetaFrame.rowkey.aggregation_groups, aggregation_groups)"><i - class="fa fa-minus"></i> - </button> - </td> + </select> + <p ng-if="state.mode=='view'" style="word-wrap: break-word; word-break: normal;max-width: 1000px "> + {{hierarchyDims}}</p> + + </td> + <td class="col-xs-2"> + <button class="btn btn-sm btn-info" + ng-click="removeHierarchy(aggregation_group,hierarchyDims)" + ng-show="state.mode=='edit'"><i class="fa fa-minus"></i> + </button> + </td> + </tr> + + <tr class="row"> + <td class="col-xs-12"> + <button class="btn btn-sm btn-info" + ng-click="addNewHierarchy(aggregation_group)" ng-show="state.mode=='edit'">New Hierarchy<i class="fa fa-plus"></i> + </button> + </td> + </tr> + </table> + + </td> </tr> - </table> - <button class="btn btn-sm btn-info" style="margin-left:42px" ng-click="addNewAggregationGroup()" - ng-show="state.mode=='edit'">New Aggregation Group<i class="fa fa-plus"></i> - </button> + <tr class="row"> + <td class="col-xs-3"> + Joint Dimensions + </td> + <td class="col-xs-9"> + <table class="table"> + <tr class="row" ng-repeat="jointDims in aggregation_group.select_rule.joint_dims track by $index"> + <td class="col-xs-10"> + <!-- Dimensions --> + <select ng-if="state.mode=='edit'" style="width: 100%" + ng-model="jointDims" chosen multiple + ng-change="refreshAggregationJoint(cubeMetaFrame.aggregation_groups, rowIndex, aggregation_group,$index,jointDims)" + ng-options="column as column for column in aggregation_group.includes"> + <option value=""></option> + </select> + <p ng-if="state.mode=='view'" style="word-wrap: break-word; word-break: normal;max-width: 1000px "> + {{jointDims}}</p> + </td> + <td class="col-xs-2"> + <button class="btn btn-sm btn-info" + ng-click="removeJointDims(aggregation_group,jointDims)" + ng-show="state.mode=='edit'"><i class="fa fa-minus"></i> + </button> + </td> + </tr> + + <tr class="row"> + <td class="col-xs-12"> + <button class="btn btn-sm btn-info" + ng-click="addNewJoint(aggregation_group)" ng-show="state.mode=='edit'">New Joint<i class="fa fa-plus"></i> + </button> + </td> + </tr> + </table> + + </td> + </tr> + </table> - </div> + </td> + <td ng-if="state.mode=='edit'" class="col-xs-1"> + <button class="btn btn-xs btn-info" + ng-click="removeElement(cubeMetaFrame.aggregation_groups, aggregation_group)"><i + class="fa fa-minus"></i> + </button> + </td> + </tr> + </table> + <button class="btn btn-sm btn-info" style="margin-left:42px" ng-click="addNewAggregationGroup()" + ng-show="state.mode=='edit'">New Aggregation Group<i class="fa fa-plus"></i> + </button> - <div class="form-group"> - <h4 style="margin-left:42px">Rowkeys</h4> - <table style="margin-left:42px; width:92%" - ng-if="cubeMetaFrame.rowkey.rowkey_columns.length > 0" - class="table table-hover list" - > - <thead> - <tr> - <th>ID</th> - <th>Column</th> - <th>Mandatory</th> - <th>Dictionary</th> - <th>Length</th> - <th ng-if="state.mode=='edit'"></th> - </tr> - </thead> - <tbody ui-sortable="state.mode=='edit'" ng-model="cubeMetaFrame.rowkey.rowkey_columns"> + </div> - <tr ng-repeat="rowkey_column in cubeMetaFrame.rowkey.rowkey_columns" ng-class="state.mode=='edit'?'sort-item':''"> - <td> - <!-- ID --> - <span class="ng-binding" ng-class="state.mode=='edit'?'badge':''">{{($index + 1)}}</span> - </td> - <td> - <!--Column Name --> - <input type="text" class="form-control" placeholder="Column Name.." ng-if="state.mode=='edit'" - tooltip="rowkey column name.." tooltip-trigger="focus" - ng-model="rowkey_column.column" class="form-control"> + <div class="form-group"> + <h4 style="margin-left:42px">Rowkeys</h4> + <table style="margin-left:42px; width:92%" + ng-if="cubeMetaFrame.rowkey.rowkey_columns.length > 0" + class="table table-hover table-bordered list" + > + <thead> + <tr> + <th>ID</th> + <th style="width:200px;">Column</th> + <th>Dictionary</th> + <th>Fixed Length</th> + <th ng-if="state.mode=='edit'"></th> + </tr> + </thead> - <span ng-if="state.mode=='view'">{{rowkey_column.column}}</span> - </td> - <td> - <!-- Mandatory --> - <button type="button " ng-if="state.mode=='edit'" - class="btn btn-xs btn-default {{rowkey_column.mandatory? 'active':''}}" - ng-model="rowkey_column.mandatory" - ng-click="updateMandatory(rowkey_column);" - btn-checkbox btn-checkbox-true="true" btn-checkbox-false="false"> - {{rowkey_column.mandatory? 'Y':'N'}} - </button> + <tbody ui-sortable="state.mode=='edit'" ng-model="convertedRowkeys"> - <span ng-if="state.mode=='view'">{{rowkey_column.mandatory? 'Y':'N'}}</span> - </td> + <tr ng-repeat="rowkey_column in convertedRowkeys track by $index" + ng-class="state.mode=='edit'?'sort-item':''"> - <td> - <!--Use Dictionary--> - <div> - <select ng-if="state.mode=='edit'" style="width:80px;" - chosen ng-model="rowkey_column.dictionary" - ng-change="dictionaryUpdated(rowkey_column);" - ng-options="dt as dt for dt in cubeConfig.dictionaries"> - <option value=""></option> - </select> - <span ng-if="state.mode=='view'">{{rowkey_column.dictionary}}</span> - </div> - </td> + <td> + <!-- ID --> + <span class="ng-binding" ng-class="state.mode=='edit'?'badge':''">{{($index + 1)}}</span> + </td> + <td> + <!--Column Name --> + <input type="text" class="form-control" placeholder="Column Name.." ng-if="state.mode=='edit'" + ng-change="refreshRowKey(convertedRowkeys,$index,rowkey_column)" + tooltip="rowkey column name.." tooltip-trigger="focus" + ng-model="rowkey_column.column" class="form-control"> - <td> - <!--Column Length --> - <input type="text" class="form-control" placeholder="Column Length.." ng-if="state.mode=='edit'" - tooltip="rowkey column length.." tooltip-trigger="focus" - ng-disabled="rowkey_column.dictionary=='true'" - ng-model="rowkey_column.length" class="form-control"> + <span ng-if="state.mode=='view'">{{rowkey_column.column}}</span> + </td> + <td> + <select ng-if="state.mode=='edit'" style="width:80px;" + chosen ng-model="rowkey_column.isDictionary" + ng-change="refreshRowKey(convertedRowkeys,$index,rowkey_column);" + ng-options="dt as dt for dt in cubeConfig.dictionaries"> + <option value=""></option> + </select> + <span ng-if="state.mode=='view'">{{rowkey_column.isDictionary}}</span> - <span ng-if="state.mode=='view'">{{rowkey_column.length}}</span> - </td> + <!--Use Dictionary--> + <!--<select ng-if="state.mode=='edit'" style="width:80px;"--> + <!--chosen ng-model="rowkey_column.encoding"--> + <!--ng-change="dictionaryUpdated(rowkey_column);"--> + <!--ng-options="dt.name as dt.value for dt in cubeConfig.dictionaries">--> + <!--<option value=""></option>--> + <!--</select>--> + </td> + <td> + <!--Column Length --> + <input type="text" class="form-control" placeholder="Column Length.." ng-if="state.mode=='edit'" + tooltip="rowkey column length.." tooltip-trigger="focus" + ng-disabled="rowkey_column.isDictionary=='true'" + ng-change="refreshRowKey(convertedRowkeys,$index,rowkey_column);" + ng-model="rowkey_column.fixedLength" class="form-control"> + <span ng-if="state.mode=='view'">{{rowkey_column.fixedLength}}</span> + </td> - <td ng-if="state.mode=='edit'"> - <button class="btn btn-xs btn-info" - ng-click="removeElement(cubeMetaFrame.rowkey.rowkey_columns, rowkey_column)"><i - class="fa fa-minus"></i> - </button> - </td> - </tr> - </tbody> - </table> + <td ng-if="state.mode=='edit'"> + <button class="btn btn-xs btn-info" + ng-click="removeRowkey(convertedRowkeys, $index,rowkey_column)"><i + class="fa fa-minus"></i> + </button> + </td> + </tr> + </tbody> + </table> - <button class="btn btn-sm btn-info" style="margin-left:42px" - ng-click="addNewRowkeyColumn()" ng-show="state.mode=='edit'">New Rowkey Column<i class="fa fa-plus"></i></button> - </div> + <button class="btn btn-sm btn-info" style="margin-left:42px" + ng-click="addNewRowkeyColumn()" ng-show="state.mode=='edit'">New Rowkey Column<i class="fa fa-plus"></i> + </button> + </div> </div> </ng-form> </div> http://git-wip-us.apache.org/repos/asf/kylin/blob/4d4e743c/webapp/app/partials/cubeDesigner/dimensions.html ---------------------------------------------------------------------- diff --git a/webapp/app/partials/cubeDesigner/dimensions.html b/webapp/app/partials/cubeDesigner/dimensions.html index 02c2474..2ddafcd 100644 --- a/webapp/app/partials/cubeDesigner/dimensions.html +++ b/webapp/app/partials/cubeDesigner/dimensions.html @@ -28,7 +28,7 @@ </button> <ul class="dropdown-menu" role="menu"> <li><a ng-click="addDim('normal')">Normal</a></li> - <li><a ng-click="addDim('hierarchy')">Hierarchy</a></li> + <!--<li><a ng-click="addDim('hierarchy')">Hierarchy</a></li>--> <li><a ng-click="addDim('derived')">Derived</a></li> </ul> </div> @@ -59,7 +59,7 @@ <tr ng-repeat="dimension in cubeMetaFrame.dimensions | filter:dimState.filter track by $index"> <!--ID --> <td> - <b>{{dimension.id = ($index + 1)}}</b> + <b>{{($index + 1)}}</b> </td> <!--Name --> <td> @@ -77,10 +77,10 @@ <td> <div ng-repeat="t in getDimType(dimension)"> <div ng-switch="t"> - <dl class="dl-horizontal" ng-switch-when="hierarchy"> - <dt>Hierarchy</dt> - <dd>{{dimension.column}}</dd> - </dl> + <!--<dl class="dl-horizontal" ng-switch-when="hierarchy">--> + <!--<dt>Hierarchy</dt>--> + <!--<dd>{{dimension.column}}</dd>--> + <!--</dl>--> <dl class="dl-horizontal" ng-switch-when="derived"> <dt>Derived</dt> <dd>{{dimension.derived}}</dd> @@ -116,7 +116,7 @@ </div> <div class="col-xs-3"> <ul class="list-unstyled"> - <li ng-repeat="d in c.dims">{{d.id}} - {{d.name}}</li> + <li ng-repeat="d in c.dims">{{$index +1}} - {{d.name}}</li> </ul> </div> </div> @@ -273,7 +273,6 @@ <li>Pick up Fact Table from Star Schema Tables first</li> <li>Data Type should match with Hive Table's Data Type</li> <li>Join Type have to be same as will be used in query</li> - <li>Using Hierarchy to inherit one dimension another</li> <li>Using Derived for One-One relationship between columns, like ID and Name</li> </ol> </div> http://git-wip-us.apache.org/repos/asf/kylin/blob/4d4e743c/webapp/app/partials/cubeDesigner/measures.html ---------------------------------------------------------------------- diff --git a/webapp/app/partials/cubeDesigner/measures.html b/webapp/app/partials/cubeDesigner/measures.html index 73ff35e..7ee502c 100755 --- a/webapp/app/partials/cubeDesigner/measures.html +++ b/webapp/app/partials/cubeDesigner/measures.html @@ -23,22 +23,18 @@ <table class="table table-striped table-hover"> <thead> <tr> - <th>ID</th> <th>Name</th> <th>Expression</th> <th>Param Type</th> <th>Param Value</th> <th>Return Type</th> + <th>Next Parameter</th> <th ng-if="state.mode=='edit'">Actions</th> </tr> </thead> <tbody> <tr ng-repeat="measure in cubeMetaFrame.measures | filter: state.measureFilter track by $index"> <td> - <!--ID --> - <b>{{measure.id = ($index + 1)}}</b> - </td> - <td> <!--Name --> <span tooltip="measure name..">{{measure.name}}</span> </td> @@ -57,6 +53,9 @@ <td> <!--Return Type --> <span>{{measure.function.returntype}}</span> + </td> <td> + <!--Return Type --> + <span>{{measure.function.parameter.next_parameter}}</span> </td> <td ng-if="state.mode=='edit'"> <!--Edit Button --> @@ -180,6 +179,17 @@ </div> </div> </div> + <!--Name--> + <div class="form-group"> + <div class="row"> + <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Next Parameter</b></label> + <div class="col-xs-12 col-sm-6"> + <input type="text" placeholder="Next parameter.." class="form-control" + tooltip="next parameter.." tooltip-trigger="focus" + ng-model="newMeasure.function.parameter.next_parameter" required /> + </div> + </div> + </div> </div> <!--Tips-->