aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2013-12-11 17:17:16 +0600
committerStas Vilchik <vilchiks@gmail.com>2013-12-11 17:17:26 +0600
commit7ef81a9c53df3db31b60981649946705ad1d1daa (patch)
tree6166c4804444930b99e05be92abbe7774b9f79d7
parenta1f2499b07cab3fa7bbe09f1f9139b2bb16a8fa2 (diff)
downloadsonarqube-7ef81a9c53df3db31b60981649946705ad1d1daa.tar.gz
sonarqube-7ef81a9c53df3db31b60981649946705ad1d1daa.zip
SONAR-4952 Provide a new PieChart widget to display a measure filter
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/pie_chart.html.erb56
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb1
-rw-r--r--sonar-server/src/main/webapp/javascripts/widgets/pie-chart.js86
-rw-r--r--sonar-server/src/main/webapp/javascripts/widgets/widget.js70
-rw-r--r--sonar-server/wro.xml1
5 files changed, 172 insertions, 42 deletions
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/pie_chart.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/pie_chart.html.erb
index b83b65e351f..c0f2ae42206 100644
--- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/pie_chart.html.erb
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/pie_chart.html.erb
@@ -1,11 +1,53 @@
+<%
+ containerId = 'pie-chart-widget' + widget.id.to_s
+ chartHeight = widget_properties["chartHeight"]
+ chartTitle = widget_properties["chartTitle"]
+ filterId = widget_properties["filter"].to_i
+%>
+
+<div class="pie-chart-widget" id="<%= containerId %>">
+ <!--[if lte IE 8 ]> <h3><%= message('widget.unsupported_browser_warning') -%></h3> <![endif]-->
+
+ <!--[if (gte IE 9)|!(IE)]><!-->
+ <% if chartTitle %>
+ <h3 style="text-align: center;"><%= h(chartTitle) -%></h3>
+ <% end %>
+ <!--<![endif]-->
+</div>
+
+<!--[if (gte IE 9)|!(IE)]><!-->
<script>
- var filterId = <%= widget_properties['filter'].to_i %>;
- var chartTitle = <%= widget_properties['chartTitle'].to_s %>;
- var chartHeight = <%= widget_properties['chartHeight'].to_s %>;
- var mainMetric = <%= widget_properties['mainMetric'].to_s %>;
- var extraMetric1 = <%= widget_properties['extraMetric1'].to_s %>;
- var extraMetric2 = <%= widget_properties['extraMetric2'].to_s %>;
- var extraMetric3 = <%= widget_properties['extraMetric3'].to_s %>;
+ (function () {
+ var metrics = [
+ '<%= widget_properties["mainMetric"].name %>',
+ '<%= widget_properties["extraMetric1"].name %>',
+ '<%= widget_properties["extraMetric2"].name %>',
+ '<%= widget_properties["extraMetric3"].name %>'
+ ],
+ query = [
+ 'filter=<%= filterId %>',
+ 'metrics=' + metrics.join(','),
+ 'fields=name',
+ 'pageSize=9',
+ 'page=1',
+ 'sort=metric:' + metrics[0],
+ 'asc=false'
+ ].join('&');
+ widget = new SonarWidgets.Widget();
+
+ widget
+ .type('PieChart')
+ .source(baseUrl + '/measures/search_filter?' + query)
+ .metricsPriority(metrics)
+ .height(<%= chartHeight %>)
+ .render('#<%= containerId %>');
+
+ autoResize(500, function() {
+ widget.update('#<%= containerId %>');
+ });
+ })();
</script>
+<!--<![endif]-->
+
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb
index a1fd777877a..cd405b7318f 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb
@@ -47,6 +47,7 @@
<%= javascript_include_tag 'third-party/jquery.ba-throttle-debounce.min.js' %>
<%= javascript_include_tag 'third-party/select2.min' %>
+ <%= javascript_include_tag 'widgets/widget' %>
<%= javascript_include_tag 'widgets/bubble-chart' %>
<%= javascript_include_tag 'widgets/timeline' %>
<%= javascript_include_tag 'widgets/stack-area' %>
diff --git a/sonar-server/src/main/webapp/javascripts/widgets/pie-chart.js b/sonar-server/src/main/webapp/javascripts/widgets/pie-chart.js
index 4bb174b4382..254b7db6ea9 100644
--- a/sonar-server/src/main/webapp/javascripts/widgets/pie-chart.js
+++ b/sonar-server/src/main/webapp/javascripts/widgets/pie-chart.js
@@ -7,8 +7,9 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
window.SonarWidgets.PieChart = function () {
// Set default values
- this._data = [];
+ this._components = [];
this._metrics = [];
+ this._metricsPriority = [];
this._width = window.SonarWidgets.PieChart.defaults.width;
this._height = window.SonarWidgets.PieChart.defaults.height;
this._margin = window.SonarWidgets.PieChart.defaults.margin;
@@ -16,15 +17,20 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
this._lineHeight = 20;
- // Export global variables
- this.data = function (_) {
- return param.call(this, '_data', _);
- };
+ // Export global variables
this.metrics = function (_) {
return param.call(this, '_metrics', _);
};
+ this.metricsPriority = function (_) {
+ return param.call(this, '_metricsPriority', _);
+ };
+
+ this.components = function (_) {
+ return param.call(this, '_components', _);
+ };
+
this.width = function (_) {
return param.call(this, '_width', _);
};
@@ -60,6 +66,13 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
.attr('transform', trans(this.margin().left, this.margin().top));
+ // Configure metrics
+ this.mainMetric = this.metricsPriority()[0];
+ this.getMainMetric = function(d) {
+ return d.measures[widget.mainMetric].val;
+ };
+
+
// Configure scales
this.color = d3.scale.category20();
@@ -72,12 +85,12 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
// Configure pie
this.pie = d3.layout.pie()
.sort(null)
- .value(function(d) { return d.metric; });
+ .value(function(d) { return widget.getMainMetric(d); });
// Configure sectors
this.sectors = this.plotWrap.selectAll('.arc')
- .data(this.pie(this.data()))
+ .data(this.pie(this.components()))
.enter().append('g').attr('class', 'arc');
this.sectors.append('path')
@@ -89,8 +102,9 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
.attr('width', this.legendWidth());
this.legends = this.legendWrap.selectAll('.legend')
- .data(this.pie(this.data()))
- .enter().append('g')
+ .data(this.components());
+
+ this.legends.enter().append('g')
.attr('class', 'legend')
.attr('transform', function(d, i) { return trans(0, 10 + i * widget._lineHeight); });
@@ -102,7 +116,7 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
this.legends.append('text')
.attr('class', 'legend-text')
.attr('transform', trans(10, 3))
- .text(function(d) { return d.data.name; });
+ .text(function(d) { return d.name; });
// Configure details
@@ -113,22 +127,16 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
this.detailsColorIndicator = this.detailsWrap.append('rect')
.classed('details-color-indicator', true)
+ .attr('transform', trans(-1, 0))
.attr('x', 0)
.attr('y', 0)
- .attr('width', 4)
+ .attr('width', 3)
.attr('height', this._detailsHeight)
.style('opacity', 0);
- this._detailsMetric = [
- { name: 'Technical Dept', value: 8.5 },
- { name: 'Lines of Code', value: 362 },
- { name: 'Issues', value: 3 },
- { name: 'Coverage', value: 86 }
- ];
-
// Configure events
- var enterHandler = function(sector, legend, i) {
+ var enterHandler = function(sector, legend, d, i) {
var scaleFactor = (widget.radius + 5) / widget.radius;
d3.select(legend)
.classed('legend-active', true);
@@ -136,12 +144,19 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
.classed('arc-active', true)
.style('-webkit-transform', 'scale(' + scaleFactor + ')');
- updateMetrics(widget._detailsMetric);
+ var metrics = widget.metricsPriority().map(function(m) {
+ return {
+ name: widget.metrics()[m].name,
+ value: d.measures[m].val
+ };
+ });
+ updateMetrics(metrics);
widget.detailsColorIndicator
.style('opacity', 1)
.style('fill', widget.color(i));
},
+
leaveHandler = function(sector, legend) {
d3.select(legend).classed('legend-active', false);
d3.select(sector)
@@ -152,25 +167,28 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
widget.detailsMetrics
.style('opacity', 0);
},
+
updateMetrics = function(metrics) {
+
widget.detailsMetrics = widget.detailsWrap.selectAll('.details-metric')
.data(metrics);
- widget.detailsMetrics
- .enter().append('text')
- .text(function(d) { return d.name + ': ' + d.value; });
-
- widget.detailsMetrics
+ widget.detailsMetrics.enter().append('text')
.classed('details-metric', true)
.classed('details-metric-main', function(d, i) { return i === 0; })
.attr('transform', function(d, i) { return trans(10, i * widget._lineHeight); })
- .attr('dy', '1.2em')
+ .attr('dy', '1.2em');
+
+ widget.detailsMetrics
+ .text(function(d) { return d.name + ': ' + d.value; })
.style('opacity', 1);
+
+ widget.detailsMetrics.exit().remove();
};
this.legends
.on('mouseenter', function(d, i) {
- return enterHandler(widget.sectors[0][i], this, i);
+ return enterHandler(widget.sectors[0][i], this, d, i);
})
.on('mouseleave', function(d, i) {
return leaveHandler(widget.sectors[0][i], this);
@@ -178,7 +196,7 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
this.sectors
.on('mouseenter', function(d, i) {
- return enterHandler(this, widget.legends[0][i], i);
+ return enterHandler(this, widget.legends[0][i], d.data, i);
})
.on('mouseleave', function(d, i) {
return leaveHandler(this, widget.legends[0][i]);
@@ -213,21 +231,22 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
// Update radius
- this.radius = Math.min(this.availableWidth - this.legendWidth(), this.availableHeight) / 2;
+ this.radius = Math.min(this.availableWidth, this.availableHeight) / 2;
// Update plot
this.plotWrap
- .attr('transform', trans(this.radius, this.radius));
+ .attr('transform', trans(this.radius, this.radius));
// Update arc
- this.arc.outerRadius(this.radius);
+ this.arc
+ .outerRadius(this.radius);
// Update legend
this.legendWrap
- .attr('transform', trans(20 + this.radius * 2, 0 ));
+ .attr('transform', trans(20 + this.radius * 2, 0 ));
// Update details
@@ -239,9 +258,6 @@ window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
this.sectors.selectAll('path')
.transition()
.attr('d', this.arc);
-
- this.sectors.selectAll('text')
- .attr('transform', function(d) { return 'translate(' + widget.arc.centroid(d) + ')'; });
};
diff --git a/sonar-server/src/main/webapp/javascripts/widgets/widget.js b/sonar-server/src/main/webapp/javascripts/widgets/widget.js
new file mode 100644
index 00000000000..f4db2b92c8b
--- /dev/null
+++ b/sonar-server/src/main/webapp/javascripts/widgets/widget.js
@@ -0,0 +1,70 @@
+/*global d3:false, SonarWidgets:false */
+/*jshint eqnull:true */
+
+window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
+
+(function () {
+
+ window.SonarWidgets.Widget = function () {
+ // Set default values
+ this._type = null;
+ this._source = null;
+ this._metricsPriority = null;
+ this._height = null;
+
+
+ // Export global variables
+ this.type = function (_) {
+ return param.call(this, '_type', _);
+ };
+
+ this.source = function (_) {
+ return param.call(this, '_source', _);
+ };
+
+ this.metricsPriority = function (_) {
+ return param.call(this, '_metricsPriority', _);
+ };
+
+ this.height = function (_) {
+ return param.call(this, '_height', _);
+ };
+ };
+
+
+ window.SonarWidgets.Widget.prototype.render = function(container) {
+ var that = this;
+
+ d3.json(this.source(), function(error, response) {
+ if (response && !error) {
+ that.widget = new SonarWidgets[that.type()]();
+ that.widget
+ .metrics(response.metrics)
+ .metricsPriority(that.metricsPriority())
+ .components(response.components)
+ .height(that.height());
+ that.widget.render(container);
+ }
+ });
+ };
+
+
+ window.SonarWidgets.Widget.prototype.update = function(container) {
+ return this.widget && this.widget.update(container);
+ };
+
+
+
+ // Some helper functions
+
+ // Gets or sets parameter
+ function param(name, value) {
+ if (value == null) {
+ return this[name];
+ } else {
+ this[name] = value;
+ return this;
+ }
+ }
+
+})();
diff --git a/sonar-server/wro.xml b/sonar-server/wro.xml
index 11c1ba2ebe4..46f78721d25 100644
--- a/sonar-server/wro.xml
+++ b/sonar-server/wro.xml
@@ -27,6 +27,7 @@
<js>/javascripts/third-party/jquery.ba-throttle-debounce.min.js</js>
<js>/javascripts/third-party/select2.min.js</js>
+ <js>/javascripts/widgets/widget.js</js>
<js>/javascripts/widgets/bubble-chart.js</js>
<js>/javascripts/widgets/timeline.js</js>
<js>/javascripts/widgets/stack-area.js</js>