diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2013-12-18 18:05:42 +0600 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2013-12-18 18:05:56 +0600 |
commit | f1b4697dbc4b2c90e3ddb12181d7a244fb779d02 (patch) | |
tree | 0c2d5708447ad11b2d630836879d8b2a07157a0b | |
parent | dd9829b274c2300ac5441931239c3aa76446c023 (diff) | |
download | sonarqube-f1b4697dbc4b2c90e3ddb12181d7a244fb779d02.tar.gz sonarqube-f1b4697dbc4b2c90e3ddb12181d7a244fb779d02.zip |
SONAR-3113 Provide a new Cloud widget and remove the legacy 'Clouds' page
First preview
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> |