]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8978 rename bubble charts (#1974)
authorStas Vilchik <stas-vilchik@users.noreply.github.com>
Wed, 26 Apr 2017 06:51:21 +0000 (08:51 +0200)
committerGitHub <noreply@github.com>
Wed, 26 Apr 2017 06:51:21 +0000 (08:51 +0200)
18 files changed:
server/sonar-web/src/main/js/apps/projects/components/AllProjects.js
server/sonar-web/src/main/js/apps/projects/store/actions.js
server/sonar-web/src/main/js/apps/projects/utils.js
server/sonar-web/src/main/js/apps/projects/visualizations/Bugs.js [deleted file]
server/sonar-web/src/main/js/apps/projects/visualizations/CodeSmells.js [deleted file]
server/sonar-web/src/main/js/apps/projects/visualizations/Coverage.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/visualizations/DuplicatedBlocks.js [deleted file]
server/sonar-web/src/main/js/apps/projects/visualizations/Duplications.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/visualizations/Maintainability.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/visualizations/QualityModel.js [deleted file]
server/sonar-web/src/main/js/apps/projects/visualizations/Reliability.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/visualizations/Risk.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/visualizations/Security.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projects/visualizations/UncoveredLines.js [deleted file]
server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.js
server/sonar-web/src/main/js/apps/projects/visualizations/VisualizationsHeader.js
server/sonar-web/src/main/js/apps/projects/visualizations/Vulnerabilities.js [deleted file]
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 92ddc79dde0d925d7b5cb66f3a641db14a33d05d..a8fd92450896f5fd5f3c18b7fb17eec06c18ccb1 100644 (file)
@@ -95,7 +95,7 @@ export default class AllProjects extends React.PureComponent {
     const isFiltered = Object.keys(query).some(key => query[key] != null);
 
     const view = query.view || 'list';
-    const visualization = query.visualization || 'quality';
+    const visualization = query.visualization || 'risk';
 
     const top = this.props.organization ? 95 : 30;
 
index 48ec5a6d1a7a4ad58392cca491841875915372fe..1bd9eacd08767c5c490629aa84aadf497755a4f1 100644 (file)
@@ -47,13 +47,13 @@ const METRICS = [
 ];
 
 const METRICS_BY_VISUALIZATION = {
-  quality: ['reliability_rating', 'security_rating', 'coverage', 'ncloc', 'sqale_index'],
+  risk: ['reliability_rating', 'security_rating', 'coverage', 'ncloc', 'sqale_index'],
   // x, y, size, color
-  bugs: ['ncloc', 'reliability_remediation_effort', 'bugs', 'reliability_rating'],
-  vulnerabilities: ['ncloc', 'security_remediation_effort', 'vulnerabilities', 'security_rating'],
-  code_smells: ['ncloc', 'sqale_index', 'code_smells', 'sqale_rating'],
-  uncovered_lines: ['complexity', 'coverage', 'uncovered_lines'],
-  duplicated_blocks: ['ncloc', 'duplicated_lines', 'duplicated_blocks']
+  reliability: ['ncloc', 'reliability_remediation_effort', 'bugs', 'reliability_rating'],
+  security: ['ncloc', 'security_remediation_effort', 'vulnerabilities', 'security_rating'],
+  maintainability: ['ncloc', 'sqale_index', 'code_smells', 'sqale_rating'],
+  coverage: ['complexity', 'coverage', 'uncovered_lines'],
+  duplications: ['ncloc', 'duplicated_lines', 'duplicated_blocks']
 };
 
 const FACETS = [
@@ -99,7 +99,7 @@ const onReceiveOrganizations = dispatch => response => {
 
 const defineMetrics = query => {
   if (query.view === 'visualizations') {
-    return METRICS_BY_VISUALIZATION[query.visualization || 'quality'];
+    return METRICS_BY_VISUALIZATION[query.visualization || 'risk'];
   } else {
     return METRICS;
   }
index bf3e0a14a26735c2b1f36a96f60527331ff75f8e..d383b8cc388b8207211827820fb8fd55a981e1c3 100644 (file)
@@ -48,12 +48,12 @@ export const saveAll = () => save(LOCALSTORAGE_ALL);
 export const saveFavorite = () => save(LOCALSTORAGE_FAVORITE);
 
 export const VISUALIZATIONS = [
-  'quality',
-  'bugs',
-  'vulnerabilities',
-  'code_smells',
-  'uncovered_lines',
-  'duplicated_blocks'
+  'risk',
+  'reliability',
+  'security',
+  'maintainability',
+  'coverage',
+  'duplications'
 ];
 
 export const localizeSorting = (sort?: string) => {
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Bugs.js b/server/sonar-web/src/main/js/apps/projects/visualizations/Bugs.js
deleted file mode 100644 (file)
index 6a704cb..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import SimpleBubbleChart from './SimpleBubbleChart';
-
-export default class Bugs extends React.PureComponent {
-  render() {
-    return (
-      <SimpleBubbleChart
-        {...this.props}
-        xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
-        yMetric={{ key: 'reliability_remediation_effort', type: 'SHORT_WORK_DUR' }}
-        sizeMetric={{ key: 'bugs', type: 'SHORT_INT' }}
-        colorMetric="reliability_rating"
-      />
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/CodeSmells.js b/server/sonar-web/src/main/js/apps/projects/visualizations/CodeSmells.js
deleted file mode 100644 (file)
index fb7682f..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import SimpleBubbleChart from './SimpleBubbleChart';
-
-export default class CodeSmells extends React.PureComponent {
-  render() {
-    return (
-      <SimpleBubbleChart
-        {...this.props}
-        xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
-        yMetric={{ key: 'sqale_index', type: 'SHORT_WORK_DUR' }}
-        sizeMetric={{ key: 'code_smells', type: 'SHORT_INT' }}
-        colorMetric="sqale_rating"
-      />
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Coverage.js b/server/sonar-web/src/main/js/apps/projects/visualizations/Coverage.js
new file mode 100644 (file)
index 0000000..66ad04d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+// @flow
+import React from 'react';
+import SimpleBubbleChart from './SimpleBubbleChart';
+
+export default class Coverage extends React.PureComponent {
+  render() {
+    return (
+      <SimpleBubbleChart
+        {...this.props}
+        xMetric={{ key: 'complexity', type: 'SHORT_INT' }}
+        yMetric={{ key: 'coverage', type: 'PERCENT' }}
+        yDomain={[100, 0]}
+        sizeMetric={{ key: 'uncovered_lines', type: 'SHORT_INT' }}
+      />
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/DuplicatedBlocks.js b/server/sonar-web/src/main/js/apps/projects/visualizations/DuplicatedBlocks.js
deleted file mode 100644 (file)
index 88e7454..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import SimpleBubbleChart from './SimpleBubbleChart';
-
-export default class DuplicatedBlocks extends React.PureComponent {
-  render() {
-    return (
-      <SimpleBubbleChart
-        {...this.props}
-        xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
-        yMetric={{ key: 'duplicated_lines', type: 'SHORT_INT' }}
-        sizeMetric={{ key: 'duplicated_blocks', type: 'SHORT_INT' }}
-      />
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Duplications.js b/server/sonar-web/src/main/js/apps/projects/visualizations/Duplications.js
new file mode 100644 (file)
index 0000000..5df7750
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+// @flow
+import React from 'react';
+import SimpleBubbleChart from './SimpleBubbleChart';
+
+export default class Duplications extends React.PureComponent {
+  render() {
+    return (
+      <SimpleBubbleChart
+        {...this.props}
+        xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
+        yMetric={{ key: 'duplicated_lines', type: 'SHORT_INT' }}
+        sizeMetric={{ key: 'duplicated_blocks', type: 'SHORT_INT' }}
+      />
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Maintainability.js b/server/sonar-web/src/main/js/apps/projects/visualizations/Maintainability.js
new file mode 100644 (file)
index 0000000..886e22f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+// @flow
+import React from 'react';
+import SimpleBubbleChart from './SimpleBubbleChart';
+
+export default class Maintainability extends React.PureComponent {
+  render() {
+    return (
+      <SimpleBubbleChart
+        {...this.props}
+        xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
+        yMetric={{ key: 'sqale_index', type: 'SHORT_WORK_DUR' }}
+        sizeMetric={{ key: 'code_smells', type: 'SHORT_INT' }}
+        colorMetric="sqale_rating"
+      />
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/QualityModel.js b/server/sonar-web/src/main/js/apps/projects/visualizations/QualityModel.js
deleted file mode 100644 (file)
index 1f8e04e..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import BubbleChart from '../../../components/charts/BubbleChart';
-import { formatMeasure } from '../../../helpers/measures';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { RATING_COLORS } from '../../../helpers/constants';
-import { getProjectUrl } from '../../../helpers/urls';
-
-type Project = {
-  key: string,
-  measures: { [string]: string },
-  name: string,
-  organization?: { name: string }
-};
-
-const X_METRIC = 'sqale_index';
-const X_METRIC_TYPE = 'SHORT_WORK_DUR';
-const Y_METRIC = 'coverage';
-const Y_METRIC_TYPE = 'PERCENT';
-const SIZE_METRIC = 'ncloc';
-const SIZE_METRIC_TYPE = 'SHORT_INT';
-const COLOR_METRIC_1 = 'reliability_rating';
-const COLOR_METRIC_2 = 'security_rating';
-const COLOR_METRIC_TYPE = 'RATING';
-
-export default class QualityModel extends React.PureComponent {
-  props: {
-    displayOrganizations: boolean,
-    projects: Array<Project>
-  };
-
-  getMetricTooltip(metric: { key: string, type: string }, value: ?number) {
-    const name = translate('metric', metric.key, 'name');
-    const formattedValue = value != null ? formatMeasure(value, metric.type) : '–';
-    return `<div>${name}: ${formattedValue}</div>`;
-  }
-
-  getTooltip(
-    project: Project,
-    x: ?number,
-    y: ?number,
-    size: ?number,
-    color1: ?number,
-    color2: ?number
-  ) {
-    const fullProjectName = this.props.displayOrganizations && project.organization
-      ? `${project.organization.name} / <strong>${project.name}</strong>`
-      : `<strong>${project.name}</strong>`;
-    const inner = [
-      `<div class="little-spacer-bottom">${fullProjectName}</div>`,
-      this.getMetricTooltip({ key: COLOR_METRIC_1, type: COLOR_METRIC_TYPE }, color1),
-      this.getMetricTooltip({ key: COLOR_METRIC_2, type: COLOR_METRIC_TYPE }, color2),
-      this.getMetricTooltip({ key: Y_METRIC, type: Y_METRIC_TYPE }, y),
-      this.getMetricTooltip({ key: X_METRIC, type: X_METRIC_TYPE }, x),
-      this.getMetricTooltip({ key: SIZE_METRIC, type: SIZE_METRIC_TYPE }, size)
-    ].join('');
-    return `<div class="text-left">${inner}</div>`;
-  }
-
-  render() {
-    const items = this.props.projects.map(project => {
-      const x = project.measures[X_METRIC] != null ? Number(project.measures[X_METRIC]) : null;
-      const y = project.measures[Y_METRIC] != null ? Number(project.measures[Y_METRIC]) : null;
-      const size = project.measures[SIZE_METRIC] != null
-        ? Number(project.measures[SIZE_METRIC])
-        : null;
-      const color1 = project.measures[COLOR_METRIC_1] != null
-        ? Number(project.measures[COLOR_METRIC_1])
-        : null;
-      const color2 = project.measures[COLOR_METRIC_2] != null
-        ? Number(project.measures[COLOR_METRIC_2])
-        : null;
-      return {
-        x: x || 0,
-        y: y || 0,
-        size: size || 0,
-        color: color1 != null && color2 != null
-          ? RATING_COLORS[Math.max(color1, color2) - 1]
-          : undefined,
-        key: project.key,
-        tooltip: this.getTooltip(project, x, y, size, color1, color2),
-        link: getProjectUrl(project.key)
-      };
-    });
-    const formatXTick = tick => formatMeasure(tick, X_METRIC_TYPE);
-    const formatYTick = tick => formatMeasure(tick, Y_METRIC_TYPE);
-    return (
-      <div>
-        <BubbleChart
-          formatXTick={formatXTick}
-          formatYTick={formatYTick}
-          height={600}
-          items={items}
-          padding={[40, 20, 60, 100]}
-          yDomain={[100, 0]}
-        />
-        <div className="measure-details-bubble-chart-axis x">
-          {translate('metric', X_METRIC, 'name')}
-        </div>
-        <div className="measure-details-bubble-chart-axis y">
-          {translate('metric', Y_METRIC, 'name')}
-        </div>
-        <div className="measure-details-bubble-chart-axis size">
-          <span className="spacer-right">
-            {translateWithParameters(
-              'component_measures.legend.color_x',
-              translate('projects.worse_of_reliablity_and_security')
-            )}
-          </span>
-          {translateWithParameters(
-            'component_measures.legend.size_x',
-            translate('metric', SIZE_METRIC, 'name')
-          )}
-        </div>
-      </div>
-    );
-  }
-}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Reliability.js b/server/sonar-web/src/main/js/apps/projects/visualizations/Reliability.js
new file mode 100644 (file)
index 0000000..18af93d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+// @flow
+import React from 'react';
+import SimpleBubbleChart from './SimpleBubbleChart';
+
+export default class Reliability extends React.PureComponent {
+  render() {
+    return (
+      <SimpleBubbleChart
+        {...this.props}
+        xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
+        yMetric={{ key: 'reliability_remediation_effort', type: 'SHORT_WORK_DUR' }}
+        sizeMetric={{ key: 'bugs', type: 'SHORT_INT' }}
+        colorMetric="reliability_rating"
+      />
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Risk.js b/server/sonar-web/src/main/js/apps/projects/visualizations/Risk.js
new file mode 100644 (file)
index 0000000..0a1eafd
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+// @flow
+import React from 'react';
+import BubbleChart from '../../../components/charts/BubbleChart';
+import { formatMeasure } from '../../../helpers/measures';
+import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { RATING_COLORS } from '../../../helpers/constants';
+import { getProjectUrl } from '../../../helpers/urls';
+
+type Project = {
+  key: string,
+  measures: { [string]: string },
+  name: string,
+  organization?: { name: string }
+};
+
+const X_METRIC = 'sqale_index';
+const X_METRIC_TYPE = 'SHORT_WORK_DUR';
+const Y_METRIC = 'coverage';
+const Y_METRIC_TYPE = 'PERCENT';
+const SIZE_METRIC = 'ncloc';
+const SIZE_METRIC_TYPE = 'SHORT_INT';
+const COLOR_METRIC_1 = 'reliability_rating';
+const COLOR_METRIC_2 = 'security_rating';
+const COLOR_METRIC_TYPE = 'RATING';
+
+export default class Risk extends React.PureComponent {
+  props: {
+    displayOrganizations: boolean,
+    projects: Array<Project>
+  };
+
+  getMetricTooltip(metric: { key: string, type: string }, value: ?number) {
+    const name = translate('metric', metric.key, 'name');
+    const formattedValue = value != null ? formatMeasure(value, metric.type) : '–';
+    return `<div>${name}: ${formattedValue}</div>`;
+  }
+
+  getTooltip(
+    project: Project,
+    x: ?number,
+    y: ?number,
+    size: ?number,
+    color1: ?number,
+    color2: ?number
+  ) {
+    const fullProjectName = this.props.displayOrganizations && project.organization
+      ? `${project.organization.name} / <strong>${project.name}</strong>`
+      : `<strong>${project.name}</strong>`;
+    const inner = [
+      `<div class="little-spacer-bottom">${fullProjectName}</div>`,
+      this.getMetricTooltip({ key: COLOR_METRIC_1, type: COLOR_METRIC_TYPE }, color1),
+      this.getMetricTooltip({ key: COLOR_METRIC_2, type: COLOR_METRIC_TYPE }, color2),
+      this.getMetricTooltip({ key: Y_METRIC, type: Y_METRIC_TYPE }, y),
+      this.getMetricTooltip({ key: X_METRIC, type: X_METRIC_TYPE }, x),
+      this.getMetricTooltip({ key: SIZE_METRIC, type: SIZE_METRIC_TYPE }, size)
+    ].join('');
+    return `<div class="text-left">${inner}</div>`;
+  }
+
+  render() {
+    const items = this.props.projects.map(project => {
+      const x = project.measures[X_METRIC] != null ? Number(project.measures[X_METRIC]) : null;
+      const y = project.measures[Y_METRIC] != null ? Number(project.measures[Y_METRIC]) : null;
+      const size = project.measures[SIZE_METRIC] != null
+        ? Number(project.measures[SIZE_METRIC])
+        : null;
+      const color1 = project.measures[COLOR_METRIC_1] != null
+        ? Number(project.measures[COLOR_METRIC_1])
+        : null;
+      const color2 = project.measures[COLOR_METRIC_2] != null
+        ? Number(project.measures[COLOR_METRIC_2])
+        : null;
+      return {
+        x: x || 0,
+        y: y || 0,
+        size: size || 0,
+        color: color1 != null && color2 != null
+          ? RATING_COLORS[Math.max(color1, color2) - 1]
+          : undefined,
+        key: project.key,
+        tooltip: this.getTooltip(project, x, y, size, color1, color2),
+        link: getProjectUrl(project.key)
+      };
+    });
+    const formatXTick = tick => formatMeasure(tick, X_METRIC_TYPE);
+    const formatYTick = tick => formatMeasure(tick, Y_METRIC_TYPE);
+    return (
+      <div>
+        <BubbleChart
+          formatXTick={formatXTick}
+          formatYTick={formatYTick}
+          height={600}
+          items={items}
+          padding={[40, 20, 60, 100]}
+          yDomain={[100, 0]}
+        />
+        <div className="measure-details-bubble-chart-axis x">
+          {translate('metric', X_METRIC, 'name')}
+        </div>
+        <div className="measure-details-bubble-chart-axis y">
+          {translate('metric', Y_METRIC, 'name')}
+        </div>
+        <div className="measure-details-bubble-chart-axis size">
+          <span className="spacer-right">
+            {translateWithParameters(
+              'component_measures.legend.color_x',
+              translate('projects.worse_of_reliablity_and_security')
+            )}
+          </span>
+          {translateWithParameters(
+            'component_measures.legend.size_x',
+            translate('metric', SIZE_METRIC, 'name')
+          )}
+        </div>
+      </div>
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Security.js b/server/sonar-web/src/main/js/apps/projects/visualizations/Security.js
new file mode 100644 (file)
index 0000000..80f4d6d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+// @flow
+import React from 'react';
+import SimpleBubbleChart from './SimpleBubbleChart';
+
+export default class Security extends React.PureComponent {
+  render() {
+    return (
+      <SimpleBubbleChart
+        {...this.props}
+        xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
+        yMetric={{ key: 'security_remediation_effort', type: 'SHORT_WORK_DUR' }}
+        sizeMetric={{ key: 'vulnerabilities', type: 'SHORT_INT' }}
+        colorMetric="security_rating"
+      />
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/UncoveredLines.js b/server/sonar-web/src/main/js/apps/projects/visualizations/UncoveredLines.js
deleted file mode 100644 (file)
index ae36d55..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import SimpleBubbleChart from './SimpleBubbleChart';
-
-export default class UncoveredLines extends React.PureComponent {
-  render() {
-    return (
-      <SimpleBubbleChart
-        {...this.props}
-        xMetric={{ key: 'complexity', type: 'SHORT_INT' }}
-        yMetric={{ key: 'coverage', type: 'PERCENT' }}
-        yDomain={[100, 0]}
-        sizeMetric={{ key: 'uncovered_lines', type: 'SHORT_INT' }}
-      />
-    );
-  }
-}
index 4180c119b401ea182cf7381dbf35896bcd74357e..eccc643a5fd1193f0cca7b3169a221f6b81d2f19 100644 (file)
 // @flow
 import React from 'react';
 import VisualizationsHeader from './VisualizationsHeader';
-import QualityModel from './QualityModel';
-import Bugs from './Bugs';
-import Vulnerabilities from './Vulnerabilities';
-import CodeSmells from './CodeSmells';
-import UncoveredLines from './UncoveredLines';
-import DuplicatedBlocks from './DuplicatedBlocks';
+import Risk from './Risk';
+import Reliability from './Reliability';
+import Security from './Security';
+import Maintainability from './Maintainability';
+import Coverage from './Coverage';
+import Duplications from './Duplications';
 import { localizeSorting } from '../utils';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 
@@ -41,12 +41,12 @@ export default class Visualizations extends React.PureComponent {
 
   renderVisualization(projects: Array<*>) {
     const visualizationToComponent = {
-      quality: QualityModel,
-      bugs: Bugs,
-      vulnerabilities: Vulnerabilities,
-      code_smells: CodeSmells,
-      uncovered_lines: UncoveredLines,
-      duplicated_blocks: DuplicatedBlocks
+      risk: Risk,
+      reliability: Reliability,
+      security: Security,
+      maintainability: Maintainability,
+      coverage: Coverage,
+      duplications: Duplications
     };
     const Component = visualizationToComponent[this.props.visualization];
 
index 4821c24fe6aff280aacb71d48c71db6f3d6da674..04824d39d86200fc0bfd7aa34f4d16e4826ca3ec 100644 (file)
@@ -36,9 +36,7 @@ export default class VisualizationsHeader extends React.PureComponent {
   render() {
     const options = VISUALIZATIONS.map(option => ({
       value: option,
-      label: option === 'quality'
-        ? translate('projects.quality_model')
-        : translate('metric', option, 'name')
+      label: translate('projects.visualization', option)
     }));
 
     return (
diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Vulnerabilities.js b/server/sonar-web/src/main/js/apps/projects/visualizations/Vulnerabilities.js
deleted file mode 100644 (file)
index 4451e58..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-// @flow
-import React from 'react';
-import SimpleBubbleChart from './SimpleBubbleChart';
-
-export default class Vulnerabilities extends React.PureComponent {
-  render() {
-    return (
-      <SimpleBubbleChart
-        {...this.props}
-        xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
-        yMetric={{ key: 'security_remediation_effort', type: 'SHORT_WORK_DUR' }}
-        sizeMetric={{ key: 'vulnerabilities', type: 'SHORT_INT' }}
-        colorMetric="security_rating"
-      />
-    );
-  }
-}
index 747424c6de000ad0ffbc98f2a41a3e67f6fb029c..2ceec54e51987a1d0d12ad8922c7b838dbbab184 100644 (file)
@@ -843,14 +843,19 @@ projects.search=Search by project name or key
 projects.sort_list=Sort list by
 projects.view.list=List
 projects.view.visualizations=Visualizations
-projects.quality_model=Quality Model
 projects.worse_of_reliablity_and_security=Worse of Reliability and Security
-projects.visualization.quality.description=Get quick insights into the operational risks in your projects. Any color but green indicates immediate risks: Bugs or Vulnerabilities that should be examined. A position at the top or right of the graph means that the longer-term health of the project may be at risk. Small green bubbles at the bottom-left are best.
-projects.visualization.bugs.description=See bugs' operational risks to your projects. The closer a bubble's color is to red, the more severe the worst bugs in the project. Bubble size indicates bug volume in the project, and each bubble's vertical position reflects the estimated time to address the bugs in the project. Small green bubbles on the bottom edge are best.
-projects.visualization.vulnerabilities.description=See vulnerabilities' operational risks to your projects. The closer a bubble's color is to red, the more severe the worst vulnerabilities in the project. Bubble size indicates vulnerability volume in the project, and each bubble's vertical position reflects the estimated time to address the vulnerabilities in the project. Small green bubbles on the bottom edge are best.
-projects.visualization.code_smells.description=See code smells' long-term risks to your projects. The closer a bubble's color is to red, the higher the ratio of technical debt to project size. Bubble size indicates code smell volume in the project, and each bubble's vertical position reflects the estimated time to address the code smells in the project. Small green bubbles on the bottom edge are best.
-projects.visualization.uncovered_lines.description=See missing test coverage's long-term risks to your projects. Bubble size indicates the volume of uncovered lines in the project, and each bubble's vertical position reflects the volume of missing coverage. Small bubbles on the bottom edge are best.
-projects.visualization.duplicated_blocks.description=See duplications' long-term risks to your projects. Bubble size indicates the volume of duplicated blocks in the project, and each bubble's vertical position reflects the volume of lines in those blocks. Small bubbles on the bottom edge are best.
+projects.visualization.risk=Risk
+projects.visualization.risk.description=Get quick insights into the operational risks in your projects. Any color but green indicates immediate risks: Bugs or Vulnerabilities that should be examined. A position at the top or right of the graph means that the longer-term health of the project may be at risk. Small green bubbles at the bottom-left are best.
+projects.visualization.reliability=Reliability
+projects.visualization.reliability.description=See bugs' operational risks to your projects. The closer a bubble's color is to red, the more severe the worst bugs in the project. Bubble size indicates bug volume in the project, and each bubble's vertical position reflects the estimated time to address the bugs in the project. Small green bubbles on the bottom edge are best.
+projects.visualization.security=Security
+projects.visualization.security.description=See vulnerabilities' operational risks to your projects. The closer a bubble's color is to red, the more severe the worst vulnerabilities in the project. Bubble size indicates vulnerability volume in the project, and each bubble's vertical position reflects the estimated time to address the vulnerabilities in the project. Small green bubbles on the bottom edge are best.
+projects.visualization.maintainability=Maintainability
+projects.visualization.maintainability.description=See code smells' long-term risks to your projects. The closer a bubble's color is to red, the higher the ratio of technical debt to project size. Bubble size indicates code smell volume in the project, and each bubble's vertical position reflects the estimated time to address the code smells in the project. Small green bubbles on the bottom edge are best.
+projects.visualization.coverage=Coverage
+projects.visualization.coverage.description=See missing test coverage's long-term risks to your projects. Bubble size indicates the volume of uncovered lines in the project, and each bubble's vertical position reflects the volume of missing coverage. Small bubbles on the bottom edge are best.
+projects.visualization.duplications=Duplications
+projects.visualization.duplications.description=See duplications' long-term risks to your projects. Bubble size indicates the volume of duplicated blocks in the project, and each bubble's vertical position reflects the volume of lines in those blocks. Small bubbles on the bottom edge are best.
 projects.limited_set_of_projects=Displayed project set limited to the top {0} projects based on current sort: {1}.
 projects.sort.name=by name
 projects.sort.reliability=by reliability (best first)