aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2013-12-18 18:05:42 +0600
committerStas Vilchik <vilchiks@gmail.com>2013-12-18 18:05:56 +0600
commitf1b4697dbc4b2c90e3ddb12181d7a244fb779d02 (patch)
tree0c2d5708447ad11b2d630836879d8b2a07157a0b
parentdd9829b274c2300ac5441931239c3aa76446c023 (diff)
downloadsonarqube-f1b4697dbc4b2c90e3ddb12181d7a244fb779d02.tar.gz
sonarqube-f1b4697dbc4b2c90e3ddb12181d7a244fb779d02.zip
SONAR-3113 Provide a new Cloud widget and remove the legacy 'Clouds' page
First preview
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/cloud.html.erb56
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb2
-rw-r--r--sonar-server/src/main/webapp/javascripts/widgets/word-cloud.js206
-rw-r--r--sonar-server/wro.xml3
4 files changed, 261 insertions, 6 deletions
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/cloud.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/cloud.html.erb
index d1dc4f8b173..556f1f289bb 100644
--- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/cloud.html.erb
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/cloud.html.erb
@@ -1,10 +1,54 @@
+<%
+containerId = 'pie-chart-widget' + widget.id.to_s
+chartTitle = widget_properties["chartTitle"]
+filterId = widget_properties["filter"].to_i
+maxItems = widget_properties["maxItems"].to_i
+%>
+
+<div class="histogram-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_s %>;
- var chartTitle = <%= widget_properties['chartTitle'].to_s %>;
- var chartHeight = <%= widget_properties['chartHeight'].to_i %>;
- var colorMetric = <%= widget_properties['colorMetric'].key.to_s %>;
- var sizeMetric = <%= widget_properties['sizeMetric'].key.to_s %>;
- var maxItems = <%= widget_properties['maxItems'].to_i %>;
+ (function () {
+ var metrics = [
+ '<%= widget_properties["colorMetric"].name -%>',
+ '<%= widget_properties["sizeMetric"].name -%>'
+ ],
+ query = [
+ 'filter=<%= filterId -%>',
+ 'metrics=' + metrics.join(','),
+ 'fields=name,qualifier',
+ 'pageSize=<%= maxItems -%>',
+ 'page=1',
+ 'sort=metric:' + metrics[0],
+ 'asc=false'
+ ].join('&'),
+ widget = new SonarWidgets.Widget();
+
+ widget
+ .type('WordCloud')
+ .source(baseUrl + '/measures/search_filter?' + query)
+ .metricsPriority(metrics)
+ .options({
+ baseUrl: baseUrl + '/dashboard/index/'
+ })
+ .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 77d4b16e06d..dee89d3d383 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
@@ -46,6 +46,7 @@
<%= javascript_include_tag 'third-party/backbone.marionette.min' %>
<%= javascript_include_tag 'third-party/jquery.ba-throttle-debounce.min.js' %>
<%= javascript_include_tag 'third-party/select2.min' %>
+ <%= javascript_include_tag 'third-party/d3-cloud/d3.layout.cloud' %>
<%= javascript_include_tag 'widgets/widget' %>
<%= javascript_include_tag 'widgets/bubble-chart' %>
@@ -53,6 +54,7 @@
<%= javascript_include_tag 'widgets/stack-area' %>
<%= javascript_include_tag 'widgets/pie-chart' %>
<%= javascript_include_tag 'widgets/histogram' %>
+ <%= javascript_include_tag 'widgets/word-cloud' %>
<%= javascript_include_tag 'select-list' %>
diff --git a/sonar-server/src/main/webapp/javascripts/widgets/word-cloud.js b/sonar-server/src/main/webapp/javascripts/widgets/word-cloud.js
new file mode 100644
index 00000000000..6ca36c9d9e5
--- /dev/null
+++ b/sonar-server/src/main/webapp/javascripts/widgets/word-cloud.js
@@ -0,0 +1,206 @@
+/*global d3:false, _:false */
+/*jshint eqnull:true */
+
+window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
+
+(function () {
+
+ window.SonarWidgets.WordCloud = function () {
+ // Set default values
+ this._components = [];
+ this._metrics = [];
+ this._metricsPriority = [];
+ this._width = window.SonarWidgets.WordCloud.defaults.width;
+ this._height = window.SonarWidgets.WordCloud.defaults.height;
+ this._margin = window.SonarWidgets.WordCloud.defaults.margin;
+ this._options = {};
+
+ // 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', _);
+ };
+
+ this.height = function (_) {
+ return param.call(this, '_height', _);
+ };
+
+ this.margin = function (_) {
+ return param.call(this, '_margin', _);
+ };
+
+ this.options = function (_) {
+ return param.call(this, '_options', _);
+ };
+ };
+
+ window.SonarWidgets.WordCloud.prototype.render = function (container) {
+ var widget = this,
+ containerS = container;
+
+ container = d3.select(container);
+
+ this.width(container.property('offsetWidth'));
+
+ this.svg = container.append('svg')
+ .attr('class', 'sonar-d3');
+ this.gWrap = this.svg.append('g');
+
+ this.plotWrap = this.gWrap.append('g')
+ .classed('plot', true);
+
+ this.gWrap
+ .attr('transform', trans(this.margin().left, this.margin().top));
+
+
+ // Configure metrics
+ this.colorMetric = this.metricsPriority()[0];
+ this.getColorMetric = function(d) {
+ return d.measures[widget.colorMetric].val;
+ };
+
+ this.sizeMetric = this.metricsPriority()[1];
+ this.getSizeMetric = function(d) {
+ return d.measures[widget.sizeMetric].val;
+ };
+
+ this.fm = function(value, name) {
+ var type = this.metrics()[name].type;
+
+ switch (type) {
+ case 'FLOAT':
+ return d3.format('.1f')(value);
+ case 'INT':
+ return d3.format('d')(value);
+ default :
+ return value;
+ }
+ };
+
+
+ // Configure scales
+ this.color = d3.scale.sqrt()
+ .domain(d3.extent(this.components(), function(d) {
+ return widget.getColorMetric(d);
+ }))
+ .range(['#ee0000', '#2360bf']);
+
+ this.size = d3.scale.linear()
+ .domain(d3.extent(this.components(), function(d) {
+ return widget.getSizeMetric(d);
+ }))
+ .range([10, 48]);
+
+
+ // Update widget
+ this.update(containerS);
+
+ return this;
+ };
+
+
+
+ window.SonarWidgets.WordCloud.prototype.update = function(container) {
+ container = d3.select(container);
+
+ var widget = this,
+ width = container.property('offsetWidth');
+ this.width(width > 100 ? width : 100);
+
+
+ // Update available size
+ this.availableWidth = this.width() - this.margin().left - this.margin().right;
+ this.availableHeight = 1000;
+ this.height(this.availableHeight + this.margin().top + this.margin().bottom);
+
+
+ // Update svg canvas
+ this.svg
+ .attr('width', this.width())
+ .attr('height', this.height());
+
+
+ // Update plot
+ this.plotWrap
+ .transition()
+ .attr('transform', trans(this.availableWidth / 2, this.availableHeight / 2));
+
+
+ // Configure cloud
+ var wordsData = this.components().map(function(d) {
+ return {
+ text: d.name,
+ size: widget.size(widget.getSizeMetric(d)),
+ color: widget.color(widget.getColorMetric(d))
+ };
+ });
+
+ this.cloud = d3.layout.cloud().size([this.availableWidth, this.availableHeight])
+ .words(wordsData)
+ .padding(5)
+ .rotate(0)
+ .font("Arial")
+ .fontSize(function(d) { return d.size; })
+ .on("end", draw)
+ .start();
+
+ function draw(words) {
+ widget.words = widget.plotWrap.selectAll("text")
+ .data(words);
+
+ widget.words.enter().append("text")
+ .style("font-size", function(d) { return d.size + "px"; })
+ .style("font-family", "Arial")
+ .style("fill", function(d) { return d.color; })
+ .attr("text-anchor", "middle")
+ .text(function(d) { return d.text; });
+
+ widget.words
+ .transition()
+ .attr("transform", function(d) {
+ return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
+ });
+
+ widget.words.exit().remove();
+ }
+ };
+
+
+
+ window.SonarWidgets.WordCloud.defaults = {
+ width: 350,
+ height: 300,
+ margin: { top: 0, right: 0, bottom: 0, left: 0 }
+ };
+
+
+
+ // Some helper functions
+
+ // Gets or sets parameter
+ function param(name, value) {
+ if (value == null) {
+ return this[name];
+ } else {
+ this[name] = value;
+ return this;
+ }
+ }
+
+ // Helper for create the translate(x, y) string
+ function trans(left, top) {
+ return 'translate(' + left + ', ' + top + ')';
+ }
+
+})();
diff --git a/sonar-server/wro.xml b/sonar-server/wro.xml
index 3b110261c92..2fb8b9328c2 100644
--- a/sonar-server/wro.xml
+++ b/sonar-server/wro.xml
@@ -26,6 +26,8 @@
<js>/javascripts/third-party/backbone.marionette.min.js</js>
<js>/javascripts/third-party/jquery.ba-throttle-debounce.min.js</js>
<js>/javascripts/third-party/select2.min.js</js>
+ <js>/javascripts/third-party/d3-cloud/d3.layout.cloud.js</js>
+
<js>/javascripts/widgets/widget.js</js>
<js>/javascripts/widgets/bubble-chart.js</js>
@@ -33,6 +35,7 @@
<js>/javascripts/widgets/stack-area.js</js>
<js>/javascripts/widgets/pie-chart.js</js>
<js>/javascripts/widgets/histogram.js</js>
+ <js>/javascripts/widgets/word-cloud.js</js>
<js>/javascripts/select-list.js</js>