Navigation Menu

Skip to content

Commit

Permalink
table search: implement by slider
Browse files Browse the repository at this point in the history
TODO:

  * Support incremental search
  • Loading branch information
kou committed Jan 3, 2015
1 parent 9a48e4e commit 1b64442
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 49 deletions.
9 changes: 6 additions & 3 deletions app/index.html
Expand Up @@ -10,7 +10,8 @@
<!-- Place apple-touch-icon.png in the root directory -->
<!-- build:css(.) styles/vendor.css -->
<!-- bower:css -->
<link rel="stylesheet" href="bower_components/angular-bootstrap-datetimepicker/src/css/datetimepicker.css" />
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="bower_components/seiyria-bootstrap-slider/dist/css/bootstrap-slider.css" />
<!-- endbower -->
<!-- endbuild -->
<!-- build:css(.tmp) styles/main.css -->
Expand Down Expand Up @@ -47,6 +48,7 @@

<!-- build:js(.) scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/modernizr/modernizr.js"></script>
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/bootstrap-sass-official/assets/javascripts/bootstrap/affix.js"></script>
Expand All @@ -68,8 +70,9 @@
<script src="bower_components/angular-touch/angular-touch.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.js"></script>
<script src="bower_components/moment/moment.js"></script>
<script src="bower_components/angular-bootstrap-datetimepicker/src/js/datetimepicker.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/seiyria-bootstrap-slider/js/bootstrap-slider.js"></script>
<script src="bower_components/angular-bootstrap-slider/slider.js"></script>
<!-- endbower -->
<!-- endbuild -->

Expand Down
2 changes: 1 addition & 1 deletion app/scripts/app.js
Expand Up @@ -17,7 +17,7 @@ angular
'ngSanitize',
'ngTouch',
'ui.bootstrap',
'ui.bootstrap.datetimepicker'
'ui.bootstrap-slider'
])
.config(function ($routeProvider) {
$routeProvider
Expand Down
162 changes: 161 additions & 1 deletion app/scripts/controllers/table-search-controller.js
Expand Up @@ -13,6 +13,8 @@ angular.module('groongaAdminApp')
function ($scope, $routeParams, $location, $http, $filter, schemaLoader) {
var schema;
var client = new GroongaClient($http);
var timeColumnUnits;
var orderedTimeColumnUnits;

function findElement(array, finder) {
var i, length;
Expand All @@ -31,6 +33,8 @@ angular.module('groongaAdminApp')
}

function initialize() {
$scope.orderedTimeColumnUnits = orderedTimeColumnUnits;

$scope.table = {
name: $routeParams.table,
allColumns: [],
Expand Down Expand Up @@ -114,6 +118,9 @@ angular.module('groongaAdminApp')
}

function buildFilter() {
$scope.table.timeColumns.forEach(function(column) {
column.syncFromRange();
});
var timeQueries = $scope.table.timeColumns.filter(function(column) {
return column.start || column.end;
}).map(function(column) {
Expand Down Expand Up @@ -300,6 +307,123 @@ angular.module('groongaAdminApp')
};
}

timeColumnUnits = {
hour: {
label: 'Hour',
baseTimeInMilliseconds: 60 * 60 * 1000,
baseDate: function() {
var now = new Date();
return new Date(now.getFullYear(),
now.getMonth(),
now.getDate(),
now.getHours());
}
},
day: {
label: 'Day',
baseTimeInMilliseconds: 24 * 60 * 60 * 1000,
baseDate: function() {
var now = new Date();
return new Date(now.getFullYear(),
now.getMonth(),
now.getDate());
}
},
week: {
label: 'Week',
baseTimeInMilliseconds: 7 * 24 * 60 * 60 * 1000,
baseDate: function() {
var now = new Date();
return new Date(now.getFullYear(),
now.getMonth(),
now.getDate() - 4);
}
},
month: {
label: 'Month',
baseTimeInMilliseconds: 12 * 24 * 60 * 60 * 1000,
baseDate: function() {
var now = new Date();
return new Date(now.getFullYear(),
now.getMonth());
}
},
year: {
label: 'Year',
baseTimeInMilliseconds: 365 * 24 * 60 * 60 * 1000,
baseDate: function() {
var now = new Date();
return new Date(now.getFullYear());
}
},
decade: {
label: 'Decade',
baseTimeInMilliseconds: 10 * 365 * 24 * 60 * 60 * 1000,
baseDate: function() {
var now = new Date();
return new Date(now.getFullYear() - 10);
}
}
};

orderedTimeColumnUnits = [];
angular.forEach(timeColumnUnits, function(unit) {
orderedTimeColumnUnits.push(unit);
});
orderedTimeColumnUnits.sort(function(unit1, unit2) {
return unit1.baseTimeInMilliseconds - unit2.baseTimeInMilliseconds;
});

function dateInUnit(date, unit) {
var baseDate = unit.baseDate();
var baseTime = baseDate.getTime();
var time = date.getTime();
return (baseTime <= time &&
time <= (baseTime * unit.baseTimeInMilliseconds));
}

function dateRangeToUnit(start, end) {
if (!start && !end) {
return timeColumnUnits.day;
}

var unit = findElement(orderedTimeColumnUnits, function(unit) {
if (start) {
if (!dateInUnit(start, unit)) {
return false;
}
}
if (end) {
if (!dateInUnit(end, unit)) {
return false;
}
}
return true;
});
if (!unit) {
unit = timeColumnUnits.decade;
}
return unit;
}

function timeRangeValueToDate(value, unit) {
var baseDate = unit.baseDate();
var date;
if (value === 0) {
date = baseDate;
} else {
date = new Date();
date.setTime(baseDate.getTime() +
unit.baseTimeInMilliseconds * (value / 100.0));
}
return date;
}

function dateToTimeRangeValue(date, unit) {
var diffTime = date.getTime() - unit.baseDate().getTime();
return (diffTime / unit.baseTimeInMilliseconds) * 100;
}

function addTimeColumn(columnInfo) {
if (columnInfo.type !== 'Time') {
return;
Expand All @@ -310,7 +434,41 @@ angular.module('groongaAdminApp')
start: null,
startIncluded: true,
end: null,
endIncluded: true
endIncluded: true,
unit: timeColumnUnits.day,
range: [0, 0],
syncFromRange: function() {
if (this.range[0] === 0 && this.range[1] === 0) {
return;
}
this.start = timeRangeValueToDate(this.range[0], this.unit);
this.end = timeRangeValueToDate(this.range[1], this.unit);
},
syncToRange: function() {
this.unit = dateRangeToUnit(this.start, this.end);
if (this.start && this.end) {
this.range = [
dateToTimeRangeValue(this.start, this.unit),
dateToTimeRangeValue(this.end, this.unit)
];
} else if (this.start) {
this.range = [
dateToTimeRangeValue(this.start, this.unit),
100
];
} else if (this.end) {
this.range = [
0,
dateToTimeRangeValue(this.end, this.unit)
];
} else {
this.range = [0, 0];
}
},
formater: function(value) {
var date = timeRangeValueToDate(value, timeColumnInfo.unit);
return date.toLocaleString();
}
};
$scope.table.timeColumns.push(timeColumnInfo);
}
Expand Down Expand Up @@ -395,6 +553,7 @@ angular.module('groongaAdminApp')
timeColumn.startBorder = fromBetweenBorder(startBorder);
timeColumn.end = fromGroongaTime(end);
timeColumn.endBorder = fromBetweenBorder(endBorder);
timeColumn.syncToRange();
} else if (/(<=|<|>|=>)/.test(condition)) {
parts = condition.split(/(<=|<|>|=>)/);
columnName = parts[0];
Expand Down Expand Up @@ -424,6 +583,7 @@ angular.module('groongaAdminApp')
timeColumn.startBorder = 'include';
break;
}
timeColumn.syncToRange();
}
});
}
Expand Down
55 changes: 12 additions & 43 deletions app/views/tables/search.html
Expand Up @@ -108,49 +108,18 @@ <h2 class="panel-title">
</div>
<div class="form-group time-query"
ng-repeat="timeColumn in table.timeColumns track by $index">
{{timeColumn.name}}:
<div class="dropdown">
<div class="input-group">
<div class="input-group-btn">
<button class="btn btn-default dropdown-toggle"
type="button"
role="button"
data-toggle="dropdown"
aria-expanded="true">
<span class="glyphicon glyphicon-calendar"></span>
</button>
<div class="dropdown-menu" role="menu">
<datetimepicker ng-model="timeColumn.start"
ng-change="incrementalSearch()"/>
</div>
</div>
<input type="datetime-local"
class="form-control"
ng-model="timeColumn.start"
ng-change="incrementalSearch()">
</div>
</div>
-
<div class="dropdown">
<div class="input-group">
<div class="input-group-btn">
<button class="btn btn-default dropdown-toggle"
type="button"
role="button"
data-toggle="dropdown"
aria-expanded="true">
<span class="glyphicon glyphicon-calendar"></span>
</button>
<div class="dropdown-menu" role="menu">
<datetimepicker ng-model="timeColumn.end"
ng-change="incrementalSearch()"/>
</div>
</div>
<input type="datetime-local"
class="form-control"
ng-model="timeColumn.end"
ng-change="incrementalSearch()">
</div>
<div class="input-group">
{{timeColumn.name}}:
<slider ng-model="timeColumn.range"
min="0"
step="1"
max="100"
formater="timeColumn.formater"
range="true"
tooltip="always"
tooltipsplit="true"></slider>
<select ng-options="unit.label for unit in orderedTimeColumnUnits"
ng-model="timeColumn.unit"></select>
</div>
</div>
</form>
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Expand Up @@ -28,7 +28,7 @@
"angular-touch": "~1.3.0",
"angular-route": "~1.3.0",
"angular-ui-bootstrap-bower": "~0.12.0",
"angular-bootstrap-datetimepicker": "~0.3.7"
"angular-bootstrap-slider": "~0.0.8"
},
"devDependencies": {
"angular-mocks": "~1.3.0",
Expand Down

0 comments on commit 1b64442

Please sign in to comment.