mirror of
https://github.com/valitydev/redash.git
synced 2024-11-07 17:38:54 +00:00
Dashboard visualizations
This commit is contained in:
parent
5c7baf9e05
commit
c2cbcd3727
@ -201,7 +201,7 @@ class Widget(models.Model):
|
|||||||
'type': self.type,
|
'type': self.type,
|
||||||
'width': self.width,
|
'width': self.width,
|
||||||
'options': json.loads(self.options),
|
'options': json.loads(self.options),
|
||||||
'visualization_id': self.visualization_id,
|
'visualization': self.visualization.to_dict(),
|
||||||
'dashboard_id': self.dashboard_id
|
'dashboard_id': self.dashboard_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
var WidgetCtrl = function ($scope, $http, $location, Query) {
|
var WidgetCtrl = function ($scope, $http, $location, Query) {
|
||||||
$scope.deleteWidget = function() {
|
$scope.deleteWidget = function() {
|
||||||
if (!confirm('Are you sure you want to remove "' + $scope.widget.query.name + '" from the dashboard?')) {
|
if (!confirm('Are you sure you want to remove "' + $scope.widget.visualization.name + '" from the dashboard?')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,7 +24,7 @@
|
|||||||
$location.path('/queries/' + query.id);
|
$location.path('/queries/' + query.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.query = new Query($scope.widget.query);
|
$scope.query = new Query($scope.widget.visualization.query);
|
||||||
$scope.queryResult = $scope.query.getQueryResult();
|
$scope.queryResult = $scope.query.getQueryResult();
|
||||||
|
|
||||||
$scope.updateTime = (new Date($scope.queryResult.getUpdatedAt())).toISOString();
|
$scope.updateTime = (new Date($scope.queryResult.getUpdatedAt())).toISOString();
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
// create new visualization
|
// create new visualization
|
||||||
// wait for query to load to populate with defaults
|
// wait for query to load to populate with defaults
|
||||||
var unwatch = scope.$watch('query', function(q) {
|
var unwatch = scope.$watch('query', function(q) {
|
||||||
if (q.id) {
|
if (q && q.id) {
|
||||||
unwatch();
|
unwatch();
|
||||||
scope.vis = {
|
scope.vis = {
|
||||||
'query_id': q.id,
|
'query_id': q.id,
|
||||||
@ -168,7 +168,7 @@
|
|||||||
row: rowIndex+1,
|
row: rowIndex+1,
|
||||||
ySize: 1,
|
ySize: 1,
|
||||||
xSize: widget.width,
|
xSize: widget.width,
|
||||||
name: widget.query.name
|
name: widget.visualization.name
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -230,14 +230,14 @@
|
|||||||
templateUrl: '/views/new_widget_form.html',
|
templateUrl: '/views/new_widget_form.html',
|
||||||
replace: true,
|
replace: true,
|
||||||
link: function($scope, element, attrs) {
|
link: function($scope, element, attrs) {
|
||||||
$scope.visReady = false;
|
|
||||||
$scope.currentView = 'existing';
|
|
||||||
$scope.widgetSizes = [{name: 'Regular', value: 1}, {name: 'Double', value: 2}];
|
$scope.widgetSizes = [{name: 'Regular', value: 1}, {name: 'Double', value: 2}];
|
||||||
|
|
||||||
var reset = function() {
|
var reset = function() {
|
||||||
$scope.saveInProgress = false;
|
$scope.saveInProgress = false;
|
||||||
$scope.widgetSize = 1;
|
$scope.widgetSize = 1;
|
||||||
$scope.queryId = null;
|
$scope.queryId = null;
|
||||||
|
$scope.selectedVis = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
@ -247,18 +247,18 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.loadVisualizations = function() {
|
$scope.loadVisualizations = function() {
|
||||||
|
if (!$scope.queryId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Query.get({
|
Query.get({
|
||||||
id: $scope.queryId
|
id: $scope.queryId
|
||||||
}, function(query) {
|
}, function(query) {
|
||||||
if (query) {
|
if (query) {
|
||||||
// TODO
|
$scope.query = query;
|
||||||
$scope.visReady = true;
|
if(query.visualizations.length) {
|
||||||
var visualizations = query.getVisualizations();
|
$scope.selectedVis = query.visualizations[0];
|
||||||
$scope.existing = visualizations = [
|
}
|
||||||
{'name': 'vis1', 'type': 'Cohort'},
|
|
||||||
{'name': 'vis2', 'type': 'Pivot Table'}
|
|
||||||
];
|
|
||||||
$scope.currentView = (visualizations.length) ? 'existing' : 'addNew';
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -267,7 +267,7 @@
|
|||||||
$scope.saveInProgress = true;
|
$scope.saveInProgress = true;
|
||||||
|
|
||||||
var widget = {
|
var widget = {
|
||||||
'query_id': $scope.queryId,
|
'visualization_id': $scope.selectedVis.id,
|
||||||
'dashboard_id': $scope.dashboard.id,
|
'dashboard_id': $scope.dashboard.id,
|
||||||
'options': {},
|
'options': {},
|
||||||
'width': $scope.widgetSize
|
'width': $scope.widgetSize
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
var renderers = angular.module('redash.renderers', []);
|
var renderers = angular.module('redash.renderers', []);
|
||||||
|
|
||||||
|
renderers.directive('visualizationRenderer', function() {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
scope: {
|
||||||
|
visualization: '=',
|
||||||
|
queryResult: '='
|
||||||
|
},
|
||||||
|
template: '<div ng-switch on="visualization.type">' +
|
||||||
|
'<chart-renderer ng-switch-when="CHART" options="visualization.options" query-result="queryResult"></chart-renderer>' +
|
||||||
|
'<grid-renderer ng-switch-when="GRID" options="visualization.options" query-result="queryResult"></grid-renderer>' +
|
||||||
|
'<cohort-renderer ng-switch-when="COHORT" options="visualization.options" query-result="queryResult"></cohort-renderer>' +
|
||||||
|
'</div>',
|
||||||
|
replace: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
renderers.directive('chartRenderer', function () {
|
renderers.directive('chartRenderer', function () {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
|
@ -280,12 +280,6 @@
|
|||||||
return [this.name, this.description, this.query].join('!#');
|
return [this.name, this.description, this.query].join('!#');
|
||||||
};
|
};
|
||||||
|
|
||||||
Query.prototype.getVisualizations = function() {
|
|
||||||
// TODO
|
|
||||||
// not implemented
|
|
||||||
return [];
|
|
||||||
};
|
|
||||||
|
|
||||||
return Query;
|
return Query;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,11 +29,8 @@
|
|||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-switch on="widget.type" class="panel-body">
|
<visualization-renderer visualization="widget.visualization" query-result="queryResult"></visualization-renderer class="panel-body">
|
||||||
<chart-renderer ng-switch-when="chart" query-result="queryResult"></chart-renderer>
|
|
||||||
<grid-renderer ng-switch-when="grid" query-result="queryResult"></grid-renderer>
|
|
||||||
<cohort-renderer ng-switch-when="cohort" query-result="queryResult"></cohort-renderer>
|
|
||||||
</div>
|
|
||||||
<div class="panel-footer">
|
<div class="panel-footer">
|
||||||
<span class="label label-default"
|
<span class="label label-default"
|
||||||
tooltip="next update {{nextUpdateTime}} (query runtime: {{queryResult.getRuntime() | durationHumanize}})"
|
tooltip="next update {{nextUpdateTime}} (query runtime: {{queryResult.getRuntime() | durationHumanize}})"
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<a class="link" ng-click="toggleAdvancedMode()">Advanced Mode</a>
|
<a class="link" ng-click="toggleAdvancedMode()">Advanced</a>
|
||||||
<textarea json-text class="form-control" rows="5" ng-model="vis.options" ng-show="advancedMode"></textarea>
|
<textarea json-text class="form-control" rows="5" ng-model="vis.options" ng-show="advancedMode"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -9,50 +9,25 @@
|
|||||||
<p>
|
<p>
|
||||||
<form class="form-inline" role="form" ng-submit="loadVisualizations()">
|
<form class="form-inline" role="form" ng-submit="loadVisualizations()">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="number" class="form-control" placeholder="Query Id" ng-model="queryId">
|
<input class="form-control" placeholder="Query Id" ng-model="queryId">
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary" ng-disabled="!queryId">
|
<button type="submit" class="btn btn-primary" ng-disabled="!queryId">
|
||||||
Load
|
<span class="glyphicon glyphicon-refresh"></span> Load
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div ng-show="visReady">
|
<div ng-show="query">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="">Choose Visualation</label>
|
<label for="">Choose Visualation</label>
|
||||||
<div class="panel-group">
|
<select ng-model="selectedVis" ng-options="vis as vis.name group by vis.type for vis in query.visualizations" class="form-control"></select>
|
||||||
<!-- Existing visualizations panel -->
|
</div>
|
||||||
<div class="panel panel-default" ng-show="existing.length">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<a ng-click="toggleView('existing')" href="#">
|
|
||||||
Existing
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="panel-collapse collapse" ng-class="{in: currentView=='existing'}">
|
|
||||||
<div class="panel-body">
|
|
||||||
<ul>
|
|
||||||
<li ng-repeat="item in existing">
|
|
||||||
{{item.name}} <span class="label label-info">{{item.type}}</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- add new visualizations panel -->
|
<div class="form-group">
|
||||||
<div class="panel panel-default">
|
<a ng-click="toggleView('addNew')" class="link">+ Add New</a>
|
||||||
<div class="panel-heading">
|
<div class="well" ng-show="currentView=='addNew'">
|
||||||
<a ng-click="toggleView('addNew')" href="#">
|
<edit-visulatization-form query="query"></edit-visulatization-form>
|
||||||
Add New
|
</div>
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="panel-collapse collapse" ng-class="{in: currentView=='addNew'}">
|
|
||||||
<div class="panel-body">
|
|
||||||
<add-visulatization-form></add-visulatization-form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -74,9 +74,8 @@
|
|||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
<edit-visulatization-form vis="vis" query="query"></edit-visulatization-form>
|
<edit-visulatization-form vis="vis" query="query"></edit-visulatization-form>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6" ng-switch="vis.type">
|
<div class="col-lg-6">
|
||||||
<chart-renderer options="vis.options" query-result="queryResult" ng-switch-when="CHART"></chart-renderer>
|
<visualization-renderer visualization="vis" query-result="queryResult"></visualization-renderer>
|
||||||
<cohort-renderer options="vis.options" query-result="queryResult" ng-switch-when="COHORT"></cohort-renderer>
|
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -88,9 +87,8 @@
|
|||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
<edit-visulatization-form vis="newVisualization" query="query"></edit-visulatization-form>
|
<edit-visulatization-form vis="newVisualization" query="query"></edit-visulatization-form>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6" ng-switch="newVisualization.type">
|
<div class="col-lg-6">
|
||||||
<chart-renderer options="newVisualization.options" query-result="queryResult" ng-switch-when="CHART"></chart-renderer>
|
<visualization-renderer visualization="newVisualization" query-result="queryResult"></visualization-renderer>
|
||||||
<cohort-renderer options="newVisualization.options" query-result="queryResult" ng-switch-when="COHORT"></cohort-renderer>
|
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user