Skip to content

Commit

Permalink
Merge pull request #140 from EverythingMe/query_filters
Browse files Browse the repository at this point in the history
Feature: filters for all visualizations and not only tables
  • Loading branch information
arikfr committed Mar 17, 2014
2 parents dd8478f + 9a04535 commit 74d667b
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 53 deletions.
2 changes: 2 additions & 0 deletions rd_ui/app/scripts/controllers/query_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@
return;
}

$scope.filters = $scope.queryResult.getFilters();

if ($scope.queryResult.getId() == null) {
$scope.dataUri = "";
} else {
Expand Down
10 changes: 3 additions & 7 deletions rd_ui/app/scripts/ng_highchart.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,13 @@
}, true);

//Update when charts data changes
scope.$watch(function () {
// TODO: this might be an issue in case the series change, but they stay
// with the same length
return (scope.series && scope.series.length) || 0;
}, function (length) {
if (!length || length == 0) {
scope.$watchCollection('series', function (series) {
if (!series || series.length == 0) {
scope.chart.showLoading();
} else {
drawChart();
};
}, true);
});
});

function initChart(options) {
Expand Down
58 changes: 52 additions & 6 deletions rd_ui/app/scripts/services/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
angular.extend(this, props);
if ('query_result' in props) {
this.status = "done";
this.filters = undefined;
this.filterFreeze = undefined;

_.each(this.query_result.data.rows, function (row) {
_.each(row, function (v, k) {
Expand All @@ -26,6 +28,8 @@
this.job = {};
this.query_result = {};
this.status = "waiting";
this.filters = undefined;
this.filterFreeze = undefined;

this.updatedAt = moment();

Expand Down Expand Up @@ -76,15 +80,51 @@
return this.query_result.runtime;
}

QueryResult.prototype.getData = function() {
QueryResult.prototype.getRawData = function() {
if (!this.query_result.data) {
return null;
}

var data = this.query_result.data.rows;

return data;
}

QueryResult.prototype.getData = function() {
if (!this.query_result.data) {
return null;
}

var filterValues = function(filters) {
if (!filters) {
return null;
}

return _.reduce(filters, function(str, filter) {
return str + filter.current;
}, "")
}

var filters = this.getFilters();
var filterFreeze = filterValues(filters);

if (this.filterFreeze != filterFreeze) {
this.filterFreeze = filterFreeze;

if (filters) {
this.filteredData = _.filter(this.query_result.data.rows, function (row) {
return _.reduce(filters, function (memo, filter) {
return (memo && row[filter.name] == filter.current);
}, true);
});
} else {
this.filteredData = this.query_result.data.rows;
}
}

return this.filteredData;
}

QueryResult.prototype.getChartData = function () {
var series = {};

Expand Down Expand Up @@ -181,6 +221,14 @@
}

QueryResult.prototype.getFilters = function () {
if (!this.filters) {
this.prepareFilters();
}

return this.filters;
};

QueryResult.prototype.prepareFilters = function() {
var filterNames = [];
_.each(this.getColumns(), function (col) {
if (col.split('::')[1] == 'filter') {
Expand All @@ -189,7 +237,7 @@
});

var filterValues = [];
_.each(this.getData(), function (row) {
_.each(this.getRawData(), function (row) {
_.each(filterNames, function (filter, i) {
if (filterValues[i] == undefined) {
filterValues[i] = [];
Expand All @@ -198,7 +246,7 @@
})
});

var filters = _.map(filterNames, function (filter, i) {
this.filters = _.map(filterNames, function (filter, i) {
var f = {
name: filter,
friendlyName: this.getColumnFriendlyName(filter),
Expand All @@ -208,9 +256,7 @@
f.current = f.values[0];
return f;
}, this);

return filters;
};
}

var refreshStatus = function(queryResult, query, ttl) {
Job.get({'id': queryResult.job.id}, function(response) {
Expand Down
17 changes: 15 additions & 2 deletions rd_ui/app/scripts/visualizations/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@
// TODO: using switch here (and in the options editor) might introduce errors and bad
// performance wise. It's better to eventually show the correct template based on the
// visualization type and not make the browser render all of them.
template: Visualization.renderVisualizationsTemplate,
replace: false
template: '<filters></filters>\n' + Visualization.renderVisualizationsTemplate,
replace: false,
link: function(scope) {
scope.filters = scope.queryResult.getFilters();
}
}
};

Expand All @@ -77,6 +80,13 @@
}
};

var Filters = function() {
return {
restrict: 'E',
templateUrl: '/views/visualizations/filters.html'
}
}

var EditVisualizationForm = function(Visualization, growl) {
return {
restrict: 'E',
Expand Down Expand Up @@ -141,9 +151,12 @@
}
};



angular.module('redash.visualization', [])
.provider('Visualization', VisualizationProvider)
.directive('visualizationRenderer', ['Visualization', VisualizationRenderer])
.directive('visualizationOptionsEditor', ['Visualization', VisualizationOptionsEditor])
.directive('filters', Filters)
.directive('editVisulatizationForm', ['Visualization', 'growl', EditVisualizationForm])
})();
40 changes: 16 additions & 24 deletions rd_ui/app/scripts/visualizations/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,32 @@
$scope.gridData = [];
$scope.filters = [];
} else {
$scope.filters = $scope.queryResult.getFilters();

var prepareGridData = function(data) {
var gridData = _.map(data, function (row) {
var newRow = {};
_.each(row, function (val, key) {
newRow[$scope.queryResult.getColumnCleanName(key)] = val;
})
return newRow;
});

$scope.filters = $scope.queryResult.getFilters();
return gridData;
};

var gridData = _.map($scope.queryResult.getData(), function (row) {
var newRow = {};
_.each(row, function (val, key) {
newRow[$scope.queryResult.getColumnCleanName(key)] = val;
})
return newRow;
});
$scope.gridData = prepareGridData($scope.queryResult.getData());

$scope.gridColumns = _.map($scope.queryResult.getColumnCleanNames(), function (col, i) {
var columnDefinition = {
'label': $scope.queryResult.getColumnFriendlyNames()[i],
'map': col
};

if (gridData.length > 0) {
var exampleData = gridData[0][col];
var rawData = $scope.queryResult.getRawData();

if (rawData.length > 0) {
var exampleData = rawData[0][col];
if (angular.isNumber(exampleData)) {
columnDefinition['formatFunction'] = 'number';
columnDefinition['formatParameter'] = 2;
Expand All @@ -76,20 +82,6 @@

return columnDefinition;
});

$scope.gridData = _.clone(gridData);

$scope.$watch('filters', function (filters) {
$scope.gridData = _.filter(gridData, function (row) {
return _.reduce(filters, function (memo, filter) {
if (filter.current == 'All') {
return memo && true;
}

return (memo && row[$scope.queryResult.getColumnCleanName(filter.name)] == filter.current);
}, true);
});
}, true);
}
});
}]
Expand Down
13 changes: 0 additions & 13 deletions rd_ui/app/views/grid_renderer.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,4 @@
<div>
<div class="btn-group pull-right" ng-repeat="filter in filters">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
{{filter.friendlyName}}: {{filter.current}}<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="value in filter.values">
<a href="#" ng-click="filter.current = value">{{value}}</a>
</li>
<li class="divider"></li>
<li><a href="#" ng-click="filter.current = 'All'">All</a></li>
</ul>
</div>

<smart-table rows="gridData" columns="gridColumns"
config="gridConfig"
class="table table-condensed table-hover"></smart-table>
Expand Down
6 changes: 5 additions & 1 deletion rd_ui/app/views/queryview.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ <h2>
</div>
<div class="row">
<div class="col-lg-12">
<grid-renderer ng-show="selectedTab == 'table'" query-result="queryResult" items-per-page="50"></grid-renderer>
<div ng-show="selectedTab == 'table'" >
<filters></filters>
<grid-renderer query-result="queryResult" items-per-page="50"></grid-renderer>
</div>

<pivot-table-renderer ng-show="selectedTab == 'pivot'" query-result="queryResult"></pivot-table-renderer>

<div ng-show="selectedTab == vis.id" ng-repeat="vis in query.visualizations">
Expand Down
12 changes: 12 additions & 0 deletions rd_ui/app/views/visualizations/filters.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div class="well well-sm" ng-show="filters">
<div class="btn-group" ng-repeat="filter in filters">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
{{filter.friendlyName}}: {{filter.current}}<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="value in filter.values">
<a href="" ng-click="filter.current = value">{{value}}</a>
</li>
</ul>
</div>
</div>

0 comments on commit 74d667b

Please sign in to comment.