From 77fcbdf39e692daa5801f46a60a0ec30d35c058a Mon Sep 17 00:00:00 2001
From: RPS <26383032+rps-v@users.noreply.github.com>
Date: Sat, 28 Sep 2019 19:43:10 +0300
Subject: [PATCH 1/2] Initial implementation
---
app/scripts/controllers/console.js | 112 ++++++++++++++++++++++++++++-
app/styles/views/_console.scss | 7 +-
app/views/console.html | 3 +-
3 files changed, 119 insertions(+), 3 deletions(-)
diff --git a/app/scripts/controllers/console.js b/app/scripts/controllers/console.js
index daf08747..a5692bc4 100644
--- a/app/scripts/controllers/console.js
+++ b/app/scripts/controllers/console.js
@@ -45,7 +45,31 @@ const crate_console = angular.module('console', ['sql', 'datatypechecks', 'stats
return service;
})
- .directive('console', function(SQLQuery, ColumnTypeCheck, ConsoleFormatting, ClusterState){
+ .service('ChartService', function () {
+ var service = {
+ colors: ["#e6194B", "#3cb44b", "#911eb4", "#4363d8", "#f58231", "#f032e6"]
+ };
+ var state = {
+ lastColorIndex: -1
+ };
+
+ service.getNextColor = function () {
+ if (state.lastColorIndex === service.colors.length - 1) { state.lastColorIndex = -1; }
+ state.lastColorIndex++;
+ return service.colors[state.lastColorIndex];
+ };
+ service.formatValue = function (value, type) {
+ switch (type) {
+ case 'timestamp':
+ return new Date(value).toISOString();
+ default:
+ return value
+ }
+ };
+
+ return service;
+ })
+ .directive('console', function(SQLQuery, ColumnTypeCheck, ConsoleFormatting, ClusterState, ChartService){
return {
restrict: 'A',
controller: ['$scope', '$translate', '$location', 'Clipboard', '$timeout' , function($scope, $translate, $location, Clipboard, $timeout){
@@ -74,6 +98,58 @@ const crate_console = angular.module('console', ['sql', 'datatypechecks', 'stats
message: ''
};
+ $scope.chartVisible = false;
+ $scope.chartOptions = {
+ chart: {
+ type: 'lineChart',
+ height: 350,
+ margin: {
+ 'top': 20,
+ 'right': 20,
+ 'bottom': 30,
+ 'left': 40
+ },
+ x: function(d) { if (d) { return d.x; } },
+ y: function(d) { if (d) { return d.y; } },
+ useInteractiveGuideline: true,
+ transitionDuration: 0,
+ showXAxis: false,
+ yAxis: {
+ ticks: 8,
+ axisLabelDistance: 0,
+ showMaxMin: false
+ },
+ showLegend: true,
+ interactiveLayer:{
+ tooltip:{
+ contentGenerator: function(e){
+ if (e == null) { return ''; }
+
+ var data = $scope.formatted_rows[e.index];
+ if (data == null) { return ''; }
+
+ var rows = '';
+ $scope.resultHeaders.forEach(function (column, index) {
+ var series = e.series.find(function (series) { return series.key === column; });
+ rows += '
' +
+ ' | ' +
+ '' + column + ' | ' +
+ '' +
+ ($scope.formatResults ? ChartService.formatValue(data[index].value, $scope.resultHeaderDataTypes[index]) : data[index].value) +
+ ' | ' +
+ '
';
+ });
+
+ return '' +
+ '' + rows + '' +
+ '
';
+ }
+ }
+ }
+ }
+ };
+ $scope.chartData = []
+
$scope.pageSize = 50;
$scope.startIndex = 0;
$scope.page = 1;
@@ -209,6 +285,9 @@ const crate_console = angular.module('console', ['sql', 'datatypechecks', 'stats
$scope.toggleOptions = function toggleOptions(){
$scope.showOptions = !$scope.showOptions;
};
+ $scope.toggleChart = function toggleChart(){
+ $scope.chartVisible = !$scope.chartVisible;
+ };
$scope.clearLocalStorage = function() {
$translate(['CONSOLE.CLEAR_HISTORY_MSG', 'CONSOLE.CLEAR_HISTORY_MSG_PLURAL']).then(function(i18n) {
@@ -298,6 +377,30 @@ const crate_console = angular.module('console', ['sql', 'datatypechecks', 'stats
$scope.paginated_formatted_rows = $scope.formatted_rows.slice($scope.startIndex, $scope.endIndex);
}
+ function buildChart(){
+ $scope.chartData.length = 0;
+
+ $scope.resultHeaders.forEach(function(column, i) {
+ var type = $scope.resultHeaderDataTypes[i]
+
+ if (type === 'number') {
+ var seriesData = {
+ key: column,
+ color: ChartService.getNextColor(),
+ values: $scope.formatted_rows.map(function(row, j){
+ return {
+ x: j + 1,
+ y: row[i].value
+ };
+ }),
+ disabled: false
+ };
+
+ $scope.chartData.push(seriesData);
+ }
+ })
+ }
+
self.execute = function(sql) {
$scope.startIndex = 0;
$scope.page = 1;
@@ -339,12 +442,18 @@ const crate_console = angular.module('console', ['sql', 'datatypechecks', 'stats
$scope.resultHeaderTypes.push(response.col_types[i]);
}
+ $scope.resultHeaderDataTypes = [];
+ for (i = 0; i < response.cols.length; i++) {
+ $scope.resultHeaderDataTypes.push(getDataType(response.cols[i], response.col_types[i]));
+ }
+
$scope.rows = response.rows;
$scope.limitToAmount = 0;
$scope.status = response.status();
$scope.statement = stmt + ';';
inputScope.updateInput($scope.statement);
formatData();
+ buildChart();
$scope.paginated_rows = $scope.rows.slice($scope.startIndex, $scope.endIndex);
$scope.numberOfPages = Math.ceil($scope.rows.length / $scope.pageSize);
//refresh cluster state
@@ -353,6 +462,7 @@ const crate_console = angular.module('console', ['sql', 'datatypechecks', 'stats
$scope.loading = false;
$scope.error.hide = false;
$scope.renderTable = false;
+ $scope.chartVisible = false;
$scope.error = response.error;
if (!$scope.showErrorTrace && !displayedErrorTraceHint) {
diff --git a/app/styles/views/_console.scss b/app/styles/views/_console.scss
index 8088bb48..8f4a526e 100644
--- a/app/styles/views/_console.scss
+++ b/app/styles/views/_console.scss
@@ -142,7 +142,8 @@
}
.query-result-container__header--next,
-.query-result-container__header--previous {
+.query-result-container__header--previous,
+.query-result-container__header--chart {
max-width: 70px !important;
}
.query-result-container__header--page {
@@ -383,3 +384,7 @@ tr > .cr-table-cell {
#share-btn {
max-width: 70px !important;
}
+
+.cr-chart {
+ margin-bottom: 15px;
+}
\ No newline at end of file
diff --git a/app/views/console.html b/app/views/console.html
index 26c59a96..46e42492 100644
--- a/app/views/console.html
+++ b/app/views/console.html
@@ -69,13 +69,14 @@ {{:: 'CONSOLE.ERROR_TRACE' | translate }}
-
+