aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/overview
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/overview')
-rw-r--r--server/sonar-web/src/main/js/overview/app.js1
-rw-r--r--server/sonar-web/src/main/js/overview/controller.js3
-rw-r--r--server/sonar-web/src/main/js/overview/main/coverage-view.js14
-rw-r--r--server/sonar-web/src/main/js/overview/main/debt-view.js50
-rw-r--r--server/sonar-web/src/main/js/overview/main/duplications-view.js14
-rw-r--r--server/sonar-web/src/main/js/overview/main/issues-view.js14
-rw-r--r--server/sonar-web/src/main/js/overview/main/layout.js3
-rw-r--r--server/sonar-web/src/main/js/overview/main/size-view.js14
-rw-r--r--server/sonar-web/src/main/js/overview/models/state.js16
-rw-r--r--server/sonar-web/src/main/js/overview/trend-view.js163
10 files changed, 281 insertions, 11 deletions
diff --git a/server/sonar-web/src/main/js/overview/app.js b/server/sonar-web/src/main/js/overview/app.js
index 4bf5db63969..04f885f2683 100644
--- a/server/sonar-web/src/main/js/overview/app.js
+++ b/server/sonar-web/src/main/js/overview/app.js
@@ -35,6 +35,7 @@ requirejs([
// add state model
this.state = new State(window.overviewConf);
+ this.state.set('period3Name', 'During Leak Period');
// create and render layout
this.layout = new Layout({
diff --git a/server/sonar-web/src/main/js/overview/controller.js b/server/sonar-web/src/main/js/overview/controller.js
index f72b99cefdf..69f50d885bd 100644
--- a/server/sonar-web/src/main/js/overview/controller.js
+++ b/server/sonar-web/src/main/js/overview/controller.js
@@ -22,12 +22,14 @@ define([
'overview/main/gate-view',
'overview/main/size-view',
'overview/main/issues-view',
+ 'overview/main/debt-view',
'overview/main/coverage-view',
'overview/main/duplications-view'
], function (MainLayout,
GateView,
SizeView,
IssuesView,
+ DebtView,
CoverageView,
DuplicationsView) {
@@ -45,6 +47,7 @@ define([
mainLayout.gateRegion.show(new GateView(options));
mainLayout.sizeRegion.show(new SizeView(options));
mainLayout.issuesRegion.show(new IssuesView(options));
+ mainLayout.debtRegion.show(new DebtView(options));
mainLayout.coverageRegion.show(new CoverageView(options));
mainLayout.duplicationsRegion.show(new DuplicationsView(options));
this.state.fetch();
diff --git a/server/sonar-web/src/main/js/overview/main/coverage-view.js b/server/sonar-web/src/main/js/overview/main/coverage-view.js
index 8b807e4d6ed..28bb1e5c7a0 100644
--- a/server/sonar-web/src/main/js/overview/main/coverage-view.js
+++ b/server/sonar-web/src/main/js/overview/main/coverage-view.js
@@ -18,8 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define([
+ 'overview/trend-view',
'templates/overview'
-], function () {
+], function (TrendView) {
return Marionette.Layout.extend({
template: Templates['overview-coverage'],
@@ -32,7 +33,16 @@ define([
var trend = this.model.get('coverageTrend'),
hasCoverage = this.model.get('coverage') != null;
if (_.size(trend) > 1 && hasCoverage) {
- this.$('#overview-coverage-trend').sparkline(this.model.get('coverageTrend'));
+ this.trendView = new TrendView({ data: trend, type: 'PERCENT' });
+ this.trendView.render()
+ .$el.appendTo(this.$('#overview-coverage-trend'));
+ this.trendView.update();
+ }
+ },
+
+ onClose: function () {
+ if (this.trendView != null) {
+ this.trendView.detachEvents().remove();
}
}
});
diff --git a/server/sonar-web/src/main/js/overview/main/debt-view.js b/server/sonar-web/src/main/js/overview/main/debt-view.js
new file mode 100644
index 00000000000..80861a82152
--- /dev/null
+++ b/server/sonar-web/src/main/js/overview/main/debt-view.js
@@ -0,0 +1,50 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.
+ */
+define([
+ 'overview/trend-view',
+ 'templates/overview'
+], function (TrendView) {
+
+ return Marionette.Layout.extend({
+ template: Templates['overview-debt'],
+
+ modelEvents: {
+ 'change': 'render'
+ },
+
+ onRender: function () {
+ var trend = this.model.get('debtTrend'),
+ hasDebt = this.model.get('debt') != null;
+ if (_.size(trend) > 1 && hasDebt) {
+ this.trendView = new TrendView({ data: trend, type: 'WORK_DUR' });
+ this.trendView.render()
+ .$el.appendTo(this.$('#overview-debt-trend'));
+ this.trendView.update();
+ }
+ },
+
+ onClose: function () {
+ if (this.trendView != null) {
+ this.trendView.detachEvents().remove();
+ }
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/overview/main/duplications-view.js b/server/sonar-web/src/main/js/overview/main/duplications-view.js
index 18e69af549b..a1310587288 100644
--- a/server/sonar-web/src/main/js/overview/main/duplications-view.js
+++ b/server/sonar-web/src/main/js/overview/main/duplications-view.js
@@ -18,8 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define([
+ 'overview/trend-view',
'templates/overview'
-], function () {
+], function (TrendView) {
return Marionette.Layout.extend({
template: Templates['overview-duplications'],
@@ -32,7 +33,16 @@ define([
var trend = this.model.get('duplicationsTrend'),
hasDuplications = this.model.get('duplications') != null;
if (_.size(trend) > 1 && hasDuplications) {
- this.$('#overview-duplications-trend').sparkline(this.model.get('duplicationsTrend'));
+ this.trendView = new TrendView({ data: trend, type: 'PERCENT' });
+ this.trendView.render()
+ .$el.appendTo(this.$('#overview-duplications-trend'));
+ this.trendView.update();
+ }
+ },
+
+ onClose: function () {
+ if (this.trendView != null) {
+ this.trendView.detachEvents().remove();
}
}
});
diff --git a/server/sonar-web/src/main/js/overview/main/issues-view.js b/server/sonar-web/src/main/js/overview/main/issues-view.js
index a17a1d9547a..bfda55b2578 100644
--- a/server/sonar-web/src/main/js/overview/main/issues-view.js
+++ b/server/sonar-web/src/main/js/overview/main/issues-view.js
@@ -18,8 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define([
+ 'overview/trend-view',
'templates/overview'
-], function () {
+], function (TrendView) {
return Marionette.Layout.extend({
template: Templates['overview-issues'],
@@ -32,7 +33,16 @@ define([
var trend = this.model.get('issuesTrend'),
hasIssues = this.model.get('issues') != null;
if (_.size(trend) > 1 && hasIssues) {
- this.$('#overview-issues-trend').sparkline(this.model.get('issuesTrend'));
+ this.trendView = new TrendView({ data: trend, type: 'SHORT_INT' });
+ this.trendView.render()
+ .$el.appendTo(this.$('#overview-issues-trend'));
+ this.trendView.update();
+ }
+ },
+
+ onClose: function () {
+ if (this.trendView != null) {
+ this.trendView.detachEvents().remove();
}
}
});
diff --git a/server/sonar-web/src/main/js/overview/main/layout.js b/server/sonar-web/src/main/js/overview/main/layout.js
index 8db7c1e088d..c0e46deffd5 100644
--- a/server/sonar-web/src/main/js/overview/main/layout.js
+++ b/server/sonar-web/src/main/js/overview/main/layout.js
@@ -28,6 +28,7 @@ define([
gateRegion: '#overview-gate',
sizeRegion: '#overview-size',
issuesRegion: '#overview-issues',
+ debtRegion: '#overview-debt',
coverageRegion: '#overview-coverage',
duplicationsRegion: '#overview-duplications'
},
@@ -39,7 +40,7 @@ define([
toggleRegions: function () {
var conditions = this.model.get('gateConditions'),
hasGate = _.isArray(conditions) && conditions.length > 0;
- this.$(this.gateRegion.el).toggle(hasGate);
+ this.$(this.gateRegion.el).toggleClass('hidden', !hasGate);
}
});
diff --git a/server/sonar-web/src/main/js/overview/main/size-view.js b/server/sonar-web/src/main/js/overview/main/size-view.js
index db1ab7e41a8..07917e89c52 100644
--- a/server/sonar-web/src/main/js/overview/main/size-view.js
+++ b/server/sonar-web/src/main/js/overview/main/size-view.js
@@ -18,8 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define([
+ 'overview/trend-view',
'templates/overview'
-], function () {
+], function (TrendView) {
return Marionette.Layout.extend({
template: Templates['overview-size'],
@@ -32,7 +33,16 @@ define([
var trend = this.model.get('sizeTrend'),
hasSize = this.model.get('ncloc') != null;
if (_.size(trend) > 1 && hasSize) {
- this.$('#overview-size-trend').sparkline(this.model.get('sizeTrend'));
+ this.trendView = new TrendView({ data: trend, type: 'SHORT_INT' });
+ this.trendView.render()
+ .$el.appendTo(this.$('#overview-size-trend'));
+ this.trendView.update();
+ }
+ },
+
+ onClose: function () {
+ if (this.trendView != null) {
+ this.trendView.detachEvents().remove();
}
}
});
diff --git a/server/sonar-web/src/main/js/overview/models/state.js b/server/sonar-web/src/main/js/overview/models/state.js
index 6b19a415287..d3be4446ee1 100644
--- a/server/sonar-web/src/main/js/overview/models/state.js
+++ b/server/sonar-web/src/main/js/overview/models/state.js
@@ -24,9 +24,10 @@ define(function () {
SIZE_METRIC = 'ncloc',
ISSUES_METRIC = 'violations',
DEBT_METRIC = 'sqale_index',
+ NEW_DEBT_METRIC = 'new_technical_debt',
SQALE_RATING_METRIC = 'sqale_rating',
- COVERAGE_METRIC = 'overall_coverage',
- NEW_COVERAGE_METRIC = 'new_overall_coverage',
+ COVERAGE_METRIC = 'coverage',
+ NEW_COVERAGE_METRIC = 'new_coverage',
DUPLICATIONS_METRIC = 'duplicated_lines_density';
return Backbone.Model.extend({
@@ -68,6 +69,7 @@ define(function () {
GATE_METRIC,
SIZE_METRIC,
DEBT_METRIC,
+ NEW_DEBT_METRIC,
SQALE_RATING_METRIC,
COVERAGE_METRIC,
NEW_COVERAGE_METRIC,
@@ -148,10 +150,14 @@ define(function () {
parseDebt: function (msr) {
var debtMeasure = _.findWhere(msr, { key: DEBT_METRIC }),
+ newDebtMeasure = _.findWhere(msr, { key: NEW_DEBT_METRIC }),
sqaleRatingMeasure = _.findWhere(msr, { key: SQALE_RATING_METRIC });
if (debtMeasure != null) {
this.set({ debt: debtMeasure.val });
}
+ if (newDebtMeasure != null) {
+ this.set({ newDebt: newDebtMeasure.var3 });
+ }
if (sqaleRatingMeasure != null) {
this.set({ sqaleRating: sqaleRatingMeasure.val });
}
@@ -191,6 +197,7 @@ define(function () {
metrics: [
SIZE_METRIC,
ISSUES_METRIC,
+ DEBT_METRIC,
COVERAGE_METRIC,
DUPLICATIONS_METRIC
].join(',')
@@ -199,6 +206,7 @@ define(function () {
if (_.isArray(r)) {
that.parseSizeTrend(r[0]);
that.parseIssuesTrend(r[0]);
+ that.parseDebtTrend(r[0]);
that.parseCoverageTrend(r[0]);
that.parseDuplicationsTrend(r[0]);
}
@@ -224,6 +232,10 @@ define(function () {
this.parseTrend(r, 'issuesTrend', ISSUES_METRIC);
},
+ parseDebtTrend: function (r) {
+ this.parseTrend(r, 'debtTrend', DEBT_METRIC);
+ },
+
parseCoverageTrend: function (r) {
this.parseTrend(r, 'coverageTrend', COVERAGE_METRIC);
},
diff --git a/server/sonar-web/src/main/js/overview/trend-view.js b/server/sonar-web/src/main/js/overview/trend-view.js
new file mode 100644
index 00000000000..aeaac5ad697
--- /dev/null
+++ b/server/sonar-web/src/main/js/overview/trend-view.js
@@ -0,0 +1,163 @@
+define(function () {
+
+ function trans (left, top) {
+ return 'translate(' + left + ', ' + top + ')';
+ }
+
+ var $ = jQuery;
+
+
+ return Backbone.View.extend({
+
+ initialize: function (options) {
+ this.data = options.data;
+ this.type = options.type || 'INT';
+ this.width = 0;
+ this.height = 0;
+ },
+
+ attachEvents: function () {
+ this.detachEvents();
+ var event = 'resize.trend-' + this.cid,
+ update = _.throttle(_.bind(this.update, this), 50);
+ $(window).on(event, update);
+ },
+
+ detachEvents: function () {
+ var event = 'resize.trend-' + this.cid;
+ $(window).off(event);
+ return this;
+ },
+
+ render: function () {
+ var that = this,
+ data = this.data;
+ this.container = d3.select(this.el);
+ this.svg = this.container.append('svg')
+ .classed('sonar-d3', true);
+ this.plot = this.svg.append('g')
+ .classed('plot', true);
+
+ this.xScale = d3.time.scale()
+ .domain(d3.extent(data, function (d) {
+ return moment(d.val).toDate();
+ }))
+ .nice();
+ this.yScale = d3.scale.linear()
+ .domain(d3.extent(data, function (d) {
+ return d.count;
+ }))
+ .nice();
+
+ this.line = d3.svg.line()
+ .x(function (d) {
+ return that.xScale(moment(d.val).toDate());
+ })
+ .y(function (d) {
+ return that.yScale(d.count);
+ })
+ .interpolate('linear');
+
+ this.xScaleTicks = this.xScale.ticks(5);
+ this.yScaleTicks = this.yScale.ticks(3);
+
+ this.xTicks = this.xScaleTicks.map(function (tick) {
+ return that.plot.append('text')
+ .datum(tick)
+ .text(that.xScale.tickFormat()(tick))
+ .attr('dy', '0')
+ .style('text-anchor', 'middle')
+ .style('font-size', '10px')
+ .style('font-weight', '300')
+ .style('fill', '#aaa');
+ });
+ this.yTicks = this.yScaleTicks.map(function (tick) {
+ return that.plot.append('text')
+ .datum(tick)
+ .text(window.formatMeasure(tick, that.type))
+ .attr('dy', '5px')
+ .style('text-anchor', 'end')
+ .style('font-size', '10px')
+ .style('font-weight', '300')
+ .style('fill', '#aaa');
+ });
+
+ this.xTickLines = this.xScaleTicks.map(function (tick) {
+ return that.plot.append('line')
+ .datum(tick)
+ .style('stroke', '#eee')
+ .style('shape-rendering', 'crispedges');
+ });
+ this.yTickLines = this.yScaleTicks.map(function (tick) {
+ return that.plot.append('line')
+ .datum(tick)
+ .style('stroke', '#eee')
+ .style('shape-rendering', 'crispedges');
+ });
+
+ this.path = this.plot.append('path')
+ .datum(data)
+ .classed('line', true)
+ .style('stroke', 'rgb(31, 119, 180)');
+
+ this.attachEvents();
+
+ return this;
+ },
+
+ update: function () {
+ var that = this,
+ width = this.$el.closest('.overview-trend').width(),
+ height = 150,
+ marginLeft = 20,
+ marginRight = 50,
+ marginTop = 5,
+ marginBottom = 25,
+ availableWidth = width - marginLeft - marginRight,
+ availableHeight = height - marginTop - marginBottom;
+
+ this.svg
+ .attr('width', width)
+ .attr('height', height);
+
+ this.plot.attr('transform', trans(marginLeft, marginTop));
+ this.xScale.range([0, availableWidth]);
+ this.yScale.range([availableHeight, 0]);
+
+ this.path
+ .attr('d', this.line);
+
+ this.xTicks.forEach(function (tick) {
+ tick
+ .attr('x', that.xScale(tick.datum()))
+ .attr('y', availableHeight + 20);
+ });
+
+ this.yTicks.forEach(function (tick) {
+ tick
+ .attr('x', availableWidth + 50)
+ .attr('y', that.yScale(tick.datum()));
+ });
+
+ this.xTickLines.forEach(function (tick) {
+ tick
+ .attr('x1', that.xScale(tick.datum()))
+ .attr('x2', that.xScale(tick.datum()))
+ .attr('y1', 0)
+ .attr('y2', availableHeight);
+ });
+
+ this.yTickLines.forEach(function (tick) {
+ tick
+ .attr('x1', 0)
+ .attr('x2', availableWidth)
+ .attr('y1', that.yScale(tick.datum()))
+ .attr('y2', that.yScale(tick.datum()));
+ });
+
+ return this;
+ }
+
+ });
+
+});