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 }}

- +
{{:: 'CONSOLE.RESULT_FROM_QUERY' | translate }}
+
{{ page }} / {{ numberOfPages }}
From 99e94350b0db6be48cca2abb2e2047d8f98019df Mon Sep 17 00:00:00 2001 From: RPS <26383032+rps-v@users.noreply.github.com> Date: Sun, 29 Sep 2019 09:31:57 +0300 Subject: [PATCH 2/2] Only show legend color if column is in chart --- app/scripts/controllers/console.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/controllers/console.js b/app/scripts/controllers/console.js index a5692bc4..24b1392c 100644 --- a/app/scripts/controllers/console.js +++ b/app/scripts/controllers/console.js @@ -132,7 +132,7 @@ const crate_console = angular.module('console', ['sql', 'datatypechecks', 'stats $scope.resultHeaders.forEach(function (column, index) { var series = e.series.find(function (series) { return series.key === column; }); rows += '' + - '
' + + '' + (series != null ? ('
') : '') + '' + '' + column + '' + '' + ($scope.formatResults ? ChartService.formatValue(data[index].value, $scope.resultHeaderDataTypes[index]) : data[index].value) +