mirror of
https://github.com/valitydev/redash.git
synced 2024-11-06 17:15:17 +00:00
Pivot table visualization
This commit is contained in:
parent
c67828f48d
commit
8952919f41
@ -2,10 +2,7 @@
|
|||||||
"name": "redash",
|
"name": "redash",
|
||||||
"version": "0.11.0",
|
"version": "0.11.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pivottable": "2.0.2",
|
|
||||||
"pace": "~0.5.1",
|
"pace": "~0.5.1",
|
||||||
"canvg": "gabelerner/canvg",
|
"canvg": "gabelerner/canvg",
|
||||||
"leaflet": "~0.7.3",
|
|
||||||
"leaflet.markercluster": "^0.5.0"
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import wordCloudVisualization from './word-cloud';
|
|||||||
import boxPlotVisualization from './box-plot';
|
import boxPlotVisualization from './box-plot';
|
||||||
import cohortVisualization from './cohort';
|
import cohortVisualization from './cohort';
|
||||||
import mapVisualization from './map';
|
import mapVisualization from './map';
|
||||||
|
import pivotVisualization from './pivot';
|
||||||
|
|
||||||
function VisualizationProvider() {
|
function VisualizationProvider() {
|
||||||
this.visualizations = {};
|
this.visualizations = {};
|
||||||
@ -168,5 +169,6 @@ export default function (ngModule) {
|
|||||||
boxPlotVisualization(ngModule);
|
boxPlotVisualization(ngModule);
|
||||||
cohortVisualization(ngModule);
|
cohortVisualization(ngModule);
|
||||||
mapVisualization(ngModule);
|
mapVisualization(ngModule);
|
||||||
|
pivotVisualization(ngModule);
|
||||||
tableVisualization(ngModule);
|
tableVisualization(ngModule);
|
||||||
}
|
}
|
||||||
|
68
frontend/app/visualizations/pivot/index.js
Normal file
68
frontend/app/visualizations/pivot/index.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import $ from 'jquery';
|
||||||
|
import 'pivottable';
|
||||||
|
import 'pivottable/dist/pivot.css';
|
||||||
|
|
||||||
|
function pivotTableRenderer() {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
scope: {
|
||||||
|
queryResult: '=',
|
||||||
|
visualization: '=',
|
||||||
|
},
|
||||||
|
template: '',
|
||||||
|
replace: false,
|
||||||
|
link($scope, element) {
|
||||||
|
$scope.$watch('queryResult && queryResult.getData()', (data) => {
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($scope.queryResult.getData() !== null) {
|
||||||
|
// We need to give the pivot table its own copy of the data, because it changes
|
||||||
|
// it which interferes with other visualizations.
|
||||||
|
data = $.extend(true, [], $scope.queryResult.getRawData());
|
||||||
|
const options = {
|
||||||
|
renderers: $.pivotUtilities.renderers,
|
||||||
|
onRefresh(config) {
|
||||||
|
const configCopy = Object.assign({}, config);
|
||||||
|
// delete some values which are functions
|
||||||
|
delete configCopy.aggregators;
|
||||||
|
delete configCopy.renderers;
|
||||||
|
delete configCopy.onRefresh;
|
||||||
|
// delete some bulky default values
|
||||||
|
delete configCopy.rendererOptions;
|
||||||
|
delete configCopy.localeStrings;
|
||||||
|
|
||||||
|
if ($scope.visualization) {
|
||||||
|
$scope.visualization.options = configCopy;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($scope.visualization) {
|
||||||
|
Object.assign(options, $scope.visualization.options);
|
||||||
|
}
|
||||||
|
$(element).pivotUI(data, options, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function (ngModule) {
|
||||||
|
ngModule.directive('pivotTableRenderer', pivotTableRenderer);
|
||||||
|
|
||||||
|
ngModule.config((VisualizationProvider) => {
|
||||||
|
const editTemplate = '<div/>';
|
||||||
|
const defaultOptions = {
|
||||||
|
};
|
||||||
|
|
||||||
|
VisualizationProvider.registerVisualization({
|
||||||
|
type: 'PIVOT',
|
||||||
|
name: 'Pivot Table',
|
||||||
|
renderTemplate: '<pivot-table-renderer visualization="visualization" query-result="queryResult"></pivot-table-renderer>',
|
||||||
|
editorTemplate: editTemplate,
|
||||||
|
defaultOptions,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -58,6 +58,7 @@
|
|||||||
"ng-annotate": "^1.2.1",
|
"ng-annotate": "^1.2.1",
|
||||||
"ng-annotate-loader": "^0.2.0",
|
"ng-annotate-loader": "^0.2.0",
|
||||||
"ng-table": "^2.1.0",
|
"ng-table": "^2.1.0",
|
||||||
|
"pivottable": "^2.3.0",
|
||||||
"plotly.js": "^1.16.0",
|
"plotly.js": "^1.16.0",
|
||||||
"raw-loader": "^0.5.1",
|
"raw-loader": "^0.5.1",
|
||||||
"ui-select": "^0.19.6",
|
"ui-select": "^0.19.6",
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
|
||||||
<!-- build:css /styles/main.css -->
|
<!-- build:css /styles/main.css -->
|
||||||
<link rel="stylesheet" href="/bower_components/pivottable/dist/pivot.css">
|
|
||||||
<link rel="stylesheet" href="/bower_components/pace/themes/pace-theme-minimal.css">
|
<link rel="stylesheet" href="/bower_components/pace/themes/pace-theme-minimal.css">
|
||||||
<link rel="stylesheet" href="/styles/redash.css">
|
<link rel="stylesheet" href="/styles/redash.css">
|
||||||
<!-- endbuild -->
|
<!-- endbuild -->
|
||||||
@ -55,8 +54,6 @@
|
|||||||
{% include 'vendor_scripts.html' %}
|
{% include 'vendor_scripts.html' %}
|
||||||
|
|
||||||
<!-- build:js({.tmp,rd_ui/app}) /scripts/scripts.js -->
|
<!-- build:js({.tmp,rd_ui/app}) /scripts/scripts.js -->
|
||||||
<script src="/scripts/vendor/cloud.js"></script>
|
|
||||||
<script src="/scripts/vendor/d3.sankey.js"></script>
|
|
||||||
<script src="/scripts/app.js"></script>
|
<script src="/scripts/app.js"></script>
|
||||||
<script src="/scripts/services/services.js"></script>
|
<script src="/scripts/services/services.js"></script>
|
||||||
<script src="/scripts/services/resources.js"></script>
|
<script src="/scripts/services/resources.js"></script>
|
||||||
@ -71,23 +68,6 @@
|
|||||||
<script src="/scripts/controllers/query_source.js"></script>
|
<script src="/scripts/controllers/query_source.js"></script>
|
||||||
<script src="/scripts/controllers/users.js"></script>
|
<script src="/scripts/controllers/users.js"></script>
|
||||||
<script src="/scripts/controllers/snippets.js"></script>
|
<script src="/scripts/controllers/snippets.js"></script>
|
||||||
<script src="/scripts/visualizations/base.js"></script>
|
|
||||||
<script src="/scripts/visualizations/chart.js"></script>
|
|
||||||
<script src="/scripts/visualizations/cohort.js"></script>
|
|
||||||
<script src="/scripts/visualizations/map.js"></script>
|
|
||||||
<script src="/scripts/visualizations/counter.js"></script>
|
|
||||||
<script src="/scripts/visualizations/boxplot.js"></script>
|
|
||||||
<script src="/scripts/visualizations/box.js"></script>
|
|
||||||
<script src="/scripts/visualizations/table.js"></script>
|
|
||||||
<script src="/scripts/visualizations/pivot.js"></script>
|
|
||||||
<script src="/scripts/visualizations/wordcloud.js"></script>
|
|
||||||
<script src="/scripts/visualizations/sunburst_sequence.js"></script>
|
|
||||||
<script src="/scripts/visualizations/sankey.js"></script>
|
|
||||||
<script src="/scripts/directives/directives.js"></script>
|
|
||||||
<script src="/scripts/directives/query_directives.js"></script>
|
|
||||||
<script src="/scripts/directives/dashboard_directives.js"></script>
|
|
||||||
<script src="/scripts/filters.js"></script>
|
|
||||||
<script src="/scripts/controllers/alerts.js"></script>
|
|
||||||
<!-- endbuild -->
|
<!-- endbuild -->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
(function() {
|
|
||||||
var module = angular.module('redash.visualization');
|
|
||||||
|
|
||||||
module.directive('pivotTableRenderer', function () {
|
|
||||||
return {
|
|
||||||
restrict: 'E',
|
|
||||||
scope: {
|
|
||||||
queryResult: '=',
|
|
||||||
visualization: '='
|
|
||||||
},
|
|
||||||
template: "",
|
|
||||||
replace: false,
|
|
||||||
link: function($scope, element) {
|
|
||||||
$scope.$watch('queryResult && queryResult.getData()', function (data) {
|
|
||||||
if (!data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($scope.queryResult.getData() === null) {
|
|
||||||
} else {
|
|
||||||
// We need to give the pivot table its own copy of the data, because it changes
|
|
||||||
// it which interferes with other visualizations.
|
|
||||||
data = $.extend(true, [], $scope.queryResult.getRawData());
|
|
||||||
var options = {
|
|
||||||
renderers: $.pivotUtilities.renderers,
|
|
||||||
onRefresh: function(config) {
|
|
||||||
var configCopy = $.extend(true, {}, config);
|
|
||||||
//delete some values which are functions
|
|
||||||
delete configCopy.aggregators;
|
|
||||||
delete configCopy.renderers;
|
|
||||||
delete configCopy.onRefresh;
|
|
||||||
//delete some bulky default values
|
|
||||||
delete configCopy.rendererOptions;
|
|
||||||
delete configCopy.localeStrings;
|
|
||||||
|
|
||||||
if ($scope.visualization) {
|
|
||||||
$scope.visualization.options = configCopy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ($scope.visualization) {
|
|
||||||
$.extend(options, $scope.visualization.options);
|
|
||||||
}
|
|
||||||
$(element).pivotUI(data, options, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
module.config(['VisualizationProvider', function (VisualizationProvider) {
|
|
||||||
var editTemplate = '<div/>';
|
|
||||||
var defaultOptions = {
|
|
||||||
};
|
|
||||||
|
|
||||||
VisualizationProvider.registerVisualization({
|
|
||||||
type: 'PIVOT',
|
|
||||||
name: 'Pivot Table',
|
|
||||||
renderTemplate: '<pivot-table-renderer visualization="visualization" query-result="queryResult"></pivot-table-renderer>',
|
|
||||||
editorTemplate: editTemplate,
|
|
||||||
defaultOptions: defaultOptions
|
|
||||||
});
|
|
||||||
}]);
|
|
||||||
})();
|
|
Loading…
Reference in New Issue
Block a user