diff --git a/frontend/app/pages/dashboards/index.js b/frontend/app/pages/dashboards/index.js index 9c25c9687..4428398bb 100644 --- a/frontend/app/pages/dashboards/index.js +++ b/frontend/app/pages/dashboards/index.js @@ -9,4 +9,4 @@ export default function (ngModule) { widgetComponent(ngModule); registerEditDashboardDialog(ngModule); return Object.assign({}, dashboardPage(ngModule), dashboardList(ngModule)); -} \ No newline at end of file +} diff --git a/frontend/app/pages/users/show.js b/frontend/app/pages/users/show.js index a071d490c..05ee123da 100644 --- a/frontend/app/pages/users/show.js +++ b/frontend/app/pages/users/show.js @@ -1,7 +1,8 @@ import { each } from 'underscore'; import template from './show.html'; -function UserCtrl($scope, $routeParams, $http, $location, toastr, clientConfig, currentUser, Events, User) { +function UserCtrl($scope, $routeParams, $http, $location, toastr, + clientConfig, currentUser, Events, User) { // $scope.$parent.pageTitle = 'Users'; $scope.userId = $routeParams.userId; diff --git a/frontend/app/services/dashboard.js b/frontend/app/services/dashboard.js index 44b28c33f..fd3aea53a 100644 --- a/frontend/app/services/dashboard.js +++ b/frontend/app/services/dashboard.js @@ -24,7 +24,7 @@ function Dashboard($resource, $http, currentUser, Widget) { isArray: true, url: 'api/dashboards/recent', transformResponse: transform, - } + }, }); resource.prototype.canEdit = () => currentUser.canEdit(this) || this.can_edit; diff --git a/frontend/app/utils/index.js b/frontend/app/utils/index.js index eb5749b09..7f73b5ead 100644 --- a/frontend/app/utils/index.js +++ b/frontend/app/utils/index.js @@ -1 +1,2 @@ +// eslint-disable-next-line import/prefer-default-export export { default as Paginator } from './paginator'; diff --git a/frontend/app/visualizations/chart/plotly.js b/frontend/app/visualizations/chart/plotly.js index d9c2cbeea..7e2ba351f 100644 --- a/frontend/app/visualizations/chart/plotly.js +++ b/frontend/app/visualizations/chart/plotly.js @@ -440,6 +440,7 @@ const CustomPlotlyChart = (clientConfig) => { return; } const refresh = () => { + // eslint-disable-next-line no-eval const codeCall = eval(`codeCall = function(x, ys, element, Plotly){ ${scope.options.customCode} }`); codeCall(scope.x, scope.ys, element[0].children[0], Plotly); }; @@ -459,6 +460,7 @@ const CustomPlotlyChart = (clientConfig) => { refresh(); } catch (err) { if (scope.options.enableConsoleLogs) { + // eslint-disable-next-line no-console console.log(`Error while executing custom graph: ${err}`); } } diff --git a/frontend/app/visualizations/sunburst/sunburst.js b/frontend/app/visualizations/sunburst/sunburst.js index 898197274..fbfc1c342 100644 --- a/frontend/app/visualizations/sunburst/sunburst.js +++ b/frontend/app/visualizations/sunburst/sunburst.js @@ -2,22 +2,32 @@ import d3 from 'd3'; import _ from 'underscore'; import angular from 'angular'; +const exitNode = '<<>>'; +const colors = d3.scale.category10(); + +// helper function colorMap - color gray if "end" is detected +function colorMap(d) { + return colors(d.name); +} + + +// Return array of ancestors of nodes, highest first, but excluding the root. +function getAncestors(node) { + const path = []; + let current = node; + + while (current.parent) { + path.unshift(current); + current = current.parent; + } + return path; +} + // The following is based on @chrisrzhou's example from: http://bl.ocks.org/chrisrzhou/d5bdd8546f64ca0e4366. export default function Sunburst(scope, element) { this.element = element; - - const refreshData = () => { - const queryData = scope.queryResult.getData(); - if (queryData) { - render(queryData); - } - }; - this.watches = []; - this.watches.push(scope.$watch('visualization.options', refreshData, true)); - this.watches.push(scope.$watch('queryResult && queryResult.getData()', refreshData)); - const exitNode = '<<>>'; // svg dimensions const width = element[0].parentElement.clientWidth; const height = scope.visualization.options.height; @@ -45,7 +55,6 @@ export default function Sunburst(scope, element) { * e.g. colors, totalSize, partitions, arcs */ // Mapping of nodes to colorscale. - const colors = d3.scale.category10(); // Total size of all nodes, to be used later when data is loaded let totalSize = 0; @@ -125,9 +134,69 @@ export default function Sunburst(scope, element) { .style('color', '#666') .style('z-index', '1'); - refreshData(); + // Generate a string representation for drawing a breadcrumb polygon. + function breadcrumbPoints(d, i) { + const points = []; + points.push('0,0'); + points.push(`${b.w},0`); + points.push(`${b.w + b.t},${b.h / 2}`); + points.push(`${b.w},${b.h}`); + points.push(`0,${b.h}`); - // helper function mouseover to handle mouseover events/animations and calculation of ancestor nodes etc + if (i > 0) { // Leftmost breadcrumb; don't include 6th vertex. + points.push(`${b.t},${b.h / 2}`); + } + return points.join(' '); + } + + // Update the breadcrumb breadcrumbs to show the current sequence and percentage. + function updateBreadcrumbs(ancestors, percentageString) { + // Data join, where primary key = name + depth. + const g = breadcrumbs.selectAll('g') + .data(ancestors, d => + d.name + d.depth + ); + + // Add breadcrumb and label for entering nodes. + const breadcrumb = g.enter().append('g'); + + breadcrumb + .append('polygon').classed('breadcrumbs-shape', true) + .attr('points', breadcrumbPoints) + .attr('fill', colorMap); + + breadcrumb + .append('text').classed('breadcrumbs-text', true) + .attr('x', (b.w + b.t) / 2) + .attr('y', b.h / 2) + .attr('dy', '0.35em') + .attr('font-size', '10px') + .attr('text-anchor', 'middle') + .text(d => + d.name + ); + + // Set position for entering and updating nodes. + g.attr('transform', (d, i) => + `translate(${i * (b.w + b.s)}, 0)` + ); + + // Remove exiting nodes. + g.exit().remove(); + + // Update percentage at the lastCrumb. + lastCrumb + .attr('x', (ancestors.length + 0.5) * (b.w + b.s)) + .attr('y', b.h / 2) + .attr('dy', '0.35em') + .attr('text-anchor', 'middle') + .attr('fill', 'black') + .attr('font-weight', 600) + .text(percentageString); + } + + // helper function mouseover to handle mouseover events/animations and calculation + // of ancestor nodes etc function mouseover(d) { // build percentage string const percentage = (100 * d.value / totalSize).toPrecision(3); @@ -170,7 +239,7 @@ export default function Sunburst(scope, element) { .transition() .duration(1000) .attr('opacity', 1) - .each('end', function () { + .each('end', function endClick() { d3.select(this).on('mouseover', mouseover); }); @@ -188,7 +257,7 @@ export default function Sunburst(scope, element) { ); // this section is required to update the colors.domain() every time the data updates - const uniqueNames = (function (a) { + const uniqueNames = (function uniqueNames(a) { const output = []; a.forEach((d) => { if (output.indexOf(d.name) === -1) output.push(d.name); @@ -200,10 +269,9 @@ export default function Sunburst(scope, element) { // create path based on nodes const path = sunburst.data([json]).selectAll('path') .data(nodes).enter() - .append('path').classed('nodePath', true) - .attr('display', d => - d.depth ? null : 'none' - ) + .append('path') + .classed('nodePath', true) + .attr('display', d => (d.depth ? null : 'none')) .attr('d', arc) .attr('fill', colorMap) .attr('opacity', 1) @@ -321,85 +389,16 @@ export default function Sunburst(scope, element) { createVisualization(json); // visualize json tree } - - // helper function colorMap - color gray if "end" is detected - function colorMap(d) { - return colors(d.name); - } - - - // Return array of ancestors of nodes, highest first, but excluding the root. - function getAncestors(node) { - const path = []; - let current = node; - - while (current.parent) { - path.unshift(current); - current = current.parent; + function refreshData() { + const queryData = scope.queryResult.getData(); + if (queryData) { + render(queryData); } - return path; } - // Generate a string representation for drawing a breadcrumb polygon. - function breadcrumbPoints(d, i) { - const points = []; - points.push('0,0'); - points.push(`${b.w},0`); - points.push(`${b.w + b.t},${b.h / 2}`); - points.push(`${b.w},${b.h}`); - points.push(`0,${b.h}`); - - if (i > 0) { // Leftmost breadcrumb; don't include 6th vertex. - points.push(`${b.t},${b.h / 2}`); - } - return points.join(' '); - } - - // Update the breadcrumb breadcrumbs to show the current sequence and percentage. - function updateBreadcrumbs(ancestors, percentageString) { - // Data join, where primary key = name + depth. - const g = breadcrumbs.selectAll('g') - .data(ancestors, d => - d.name + d.depth - ); - - // Add breadcrumb and label for entering nodes. - const breadcrumb = g.enter().append('g'); - - breadcrumb - .append('polygon').classed('breadcrumbs-shape', true) - .attr('points', breadcrumbPoints) - .attr('fill', colorMap); - - breadcrumb - .append('text').classed('breadcrumbs-text', true) - .attr('x', (b.w + b.t) / 2) - .attr('y', b.h / 2) - .attr('dy', '0.35em') - .attr('font-size', '10px') - .attr('text-anchor', 'middle') - .text(d => - d.name - ); - - // Set position for entering and updating nodes. - g.attr('transform', (d, i) => - `translate(${i * (b.w + b.s)}, 0)` - ); - - // Remove exiting nodes. - g.exit().remove(); - - // Update percentage at the lastCrumb. - lastCrumb - .attr('x', (ancestors.length + 0.5) * (b.w + b.s)) - .attr('y', b.h / 2) - .attr('dy', '0.35em') - .attr('text-anchor', 'middle') - .attr('fill', 'black') - .attr('font-weight', 600) - .text(percentageString); - } + refreshData(); + this.watches.push(scope.$watch('visualization.options', refreshData, true)); + this.watches.push(scope.$watch('queryResult && queryResult.getData()', refreshData)); } Sunburst.prototype.remove = function remove() {