diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2010-12-10 17:56:55 +0000 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2010-12-10 17:56:55 +0000 |
commit | ddbaf492be30974ce54995ce0927d598e4128552 (patch) | |
tree | 44c501e0dde9d05976f51ee02580a5d0f405f33d /sonar-server | |
parent | 9dcf2f2c45ec1ce16ea78a489d78e026634ed2fb (diff) | |
download | sonarqube-ddbaf492be30974ce54995ce0927d598e4128552.tar.gz sonarqube-ddbaf492be30974ce54995ce0927d598e4128552.zip |
SONAR-1956 support variations in treemaps
Diffstat (limited to 'sonar-server')
10 files changed, 153 insertions, 54 deletions
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/filters_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/filters_controller.rb index 69644b74a1f..d1be0ad873e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/filters_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/filters_controller.rb @@ -333,7 +333,8 @@ class FiltersController < ApplicationController filter.columns.clear params[:columns].each do |colstring| - filter.columns<<::FilterColumn.create_from_string(colstring) + column=::FilterColumn.create_from_string(colstring) + filter.columns<<column if column end filter.save redirect_to :action => :edit, :id => filter.id @@ -406,7 +407,9 @@ class FiltersController < ApplicationController @width=(params[:width]||'800').to_i @height=(params[:height]||'500').to_i - @treemap=Sonar::Treemap.new(@filter_context.measures_by_snapshot, @width, @height, @size_metric, @color_metric) + + treemap_options={:variation_index => @filter_context.variation_index} + @treemap=Sonar::Treemap.new(@filter_context.measures_by_snapshot, @width, @height, @size_metric, @color_metric, treemap_options) render :action => "treemap", :layout => false end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/filters_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/filters_helper.rb index 35bea1ad091..159341710d1 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/filters_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/filters_helper.rb @@ -34,7 +34,7 @@ module FiltersHelper end if filter.favourites - java_filter.setFavouriteIds((filter_context.user ? user.favourite_ids : []).to_java(:Integer)) + java_filter.setFavouriteIds((filter_context.user ? filter_context.user.favourite_ids : []).to_java(:Integer)) end date_criterion=filter.criterion('date') @@ -133,7 +133,13 @@ module FiltersHelper def treemap_metrics(filter) metrics=filter.measure_columns.map{|col| col.metric} size_metric=(metrics.size>=1 ? metrics[0] : Metric.by_key('ncloc')) - color_metric=(metrics.size>=2 ? metrics[1] : Metric.by_key('violations_density')) + color_metric=nil + if metrics.size>=2 + color_metric=metrics[1] + end + if color_metric.nil? || !color_metric.treemap_color? + color_metric=Metric.by_key('violations_density') + end [size_metric, color_metric] end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/measure_color.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/measure_color.rb new file mode 100644 index 00000000000..4f8afc58f65 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/measure_color.rb @@ -0,0 +1,80 @@ +# +# Sonar, entreprise quality control tool. +# Copyright (C) 2009 SonarSource SA +# mailto:contact AT sonarsource DOT com +# +# Sonar 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. +# +# Sonar 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 Sonar; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 +# +class MeasureColor + + MIN_COLOR=Color::RGB.from_html("EE0000") # red + MEAN_COLOR=Color::RGB.from_html("FFEE00") # orange + MAX_COLOR=Color::RGB.from_html("00AA00") # green + NONE_COLOR=Color::RGB.from_html("DDDDDD") # gray + + # + # Options : + # * min : min value, else the metric worst_value + # * max : max value, else the metric best_value + # * variation_index: integer between 1 and 5 if set, else nil + # * check_alert_status: true|false. Default is true. + # + def self.color(measure, options={}) + return NONE_COLOR if measure.nil? + + max_value = options[:max] || measure.metric.best_value + min_value = options[:min] || measure.metric.worst_value + percent=-1.0 + + if options[:variation_index] + if min_value && max_value + value=measure.variation(options[:variation_index]) + percent = value_to_percent(value, min_value, max_value) + end + else + if !measure.alert_status.blank? && (options[:check_alert_status]||true) + case(measure.alert_status) + when Metric::TYPE_LEVEL_OK : percent=100.0 + when Metric::TYPE_LEVEL_ERROR : percent=0.0 + when Metric::TYPE_LEVEL_WARN : percent=50.0 + end + elsif measure.metric.value_type==Metric::VALUE_TYPE_LEVEL + case(measure.text_value) + when Metric::TYPE_LEVEL_OK : percent=100.0 + when Metric::TYPE_LEVEL_WARN : percent=50.0 + when Metric::TYPE_LEVEL_ERROR : percent=0.0 + end + elsif measure.value && max_value && min_value + percent = value_to_percent(measure.value, min_value, max_value) + end + end + + if percent<0.0 + NONE_COLOR + elsif (percent > 50.0) + MAX_COLOR.mix_with(MEAN_COLOR, (percent - 50.0) * 2.0) + else + MIN_COLOR.mix_with(MEAN_COLOR, (50.0 - percent) * 2.0) + end + end + + + def self.value_to_percent(value, min, max) + percent = 100.0 * (value.to_f - min.to_f) / (max.to_f - min.to_f) + percent=100.0 if percent>100.0 + percent=0.0 if percent<0.0 + percent + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/metric.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/metric.rb index 21a08a20616..cc680cf7106 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/metric.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/metric.rb @@ -194,6 +194,14 @@ class Metric < ActiveRecord::Base 'direction' => direction.to_i, 'val_type' => val_type.to_s, 'hidden' => hidden} end + def treemap_color? + enabled && !hidden && ((numeric? && worst_value && best_value) || val_type==Metric::VALUE_TYPE_LEVEL) + end + + def treemap_size? + enabled && !hidden && numeric? && !domain.blank? + end + def to_xml(options={}) xml = Builder::XmlMarkup.new xml.metric do diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb index cd5f7c8e618..5c45f336390 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb @@ -150,39 +150,10 @@ class ProjectMeasure < ActiveRecord::Base end end - - MIN_COLOR=Color::RGB.from_html("EE0000") # red - MEAN_COLOR=Color::RGB.from_html("FFEE00") # orange - MAX_COLOR=Color::RGB.from_html("00AA00") # green - def color @color ||= begin - percent=-1.0 - if !alert_status.blank? - case(alert_status) - when Metric::TYPE_LEVEL_OK : percent=100.0 - when Metric::TYPE_LEVEL_ERROR : percent=0.0 - when Metric::TYPE_LEVEL_WARN : percent=50.0 - end - elsif metric.value_type==Metric::VALUE_TYPE_LEVEL - case(text_value) - when Metric::TYPE_LEVEL_OK : percent=100.0 - when Metric::TYPE_LEVEL_WARN : percent=50.0 - when Metric::TYPE_LEVEL_ERROR : percent=0.0 - end - elsif value && metric.worst_value && metric.best_value - percent = 100.0 * (value.to_f - metric.worst_value.to_f) / (metric.best_value.to_f - metric.worst_value.to_f) - percent=100.0 if percent>100.0 - percent=0.0 if percent<0.0 - end - if percent<0.0 - nil - elsif (percent > 50.0) - MAX_COLOR.mix_with(MEAN_COLOR, (percent - 50.0) * 2.0) - else - MIN_COLOR.mix_with(MEAN_COLOR, (50.0 - percent) * 2.0) - end + MeasureColor.color(self) end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/sonar/treemap.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/sonar/treemap.rb index 3892d709a6d..a7b6c931adb 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/sonar/treemap.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/sonar/treemap.rb @@ -22,12 +22,16 @@ class Sonar::Treemap attr_accessor :color_metric, :size_metric, :width, :height - def initialize(measures_by_snapshot, width, height, size_metric, color_metric) + def initialize(measures_by_snapshot, width, height, size_metric, color_metric, options={}) @measures_by_snapshot = measures_by_snapshot @size_metric = size_metric - @color_metric = color_metric + @color_metric = color_metric if color_metric && color_metric.treemap_color? @width = width @height = height + + if options[:variation_index] && options[:variation_index]>0 + @variation_index = options[:variation_index] + end end def generate_html @@ -50,41 +54,55 @@ class Sonar::Treemap id_counter = 0 @measures_by_snapshot.each_pair do |snapshot, measures| size_measure=measures[@size_metric] - color_measure=measures[@color_metric] + color_measure=measures[@color_metric] if @color_metric if size_measure resource = snapshot.project child = Treemap::Node.new( :id => (id_counter += 1), - :size => size_measure.value.to_f||0, + :size => size_value(size_measure), :label => resource.name(false), :title => escape_javascript(resource.name(true)), :tooltip => get_html_tooltip(snapshot, size_measure, color_measure), :color => html_color(color_measure), - :url => get_url(snapshot,color_measure)) + :url => get_url(snapshot)) node.add_child(child) end end end - def get_url(snapshot,color_measure) + def get_url(snapshot) if snapshot.display_dashboard? "document.location='#{ApplicationController.root_context}/dashboard/index/#{snapshot.project.copy_resource_id || snapshot.project_id}'" else - "window.open('#{ApplicationController.root_context}/resource/index/#{snapshot.project_id}?viewer_metric_key=#{@color_metric.key}','resource','height=800,width=900,scrollbars=1,resizable=1');return false;" + color_metric_key=(@color_metric ? @color_metric.key : nil) + "window.open('#{ApplicationController.root_context}/resource/index/#{snapshot.project_id}?viewer_metric_key=#{color_metric_key}','resource','height=800,width=900,scrollbars=1,resizable=1');return false;" end end def get_html_tooltip(snapshot, size_measure, color_measure) html = "<table>" html += "<tr><td align=left>#{escape_javascript(@size_metric.short_name)}</td><td align=right><b>#{escape_javascript(size_measure ? size_measure.formatted_value : '-')}</b></td></tr>" - html += "<tr><td align=left>#{escape_javascript(@color_metric.short_name)}</td><td align=right><b>#{escape_javascript(color_measure ? color_measure.formatted_value : '-')}</b></td></tr>" + if color_measure + html += "<tr><td align=left>#{escape_javascript(@color_metric.short_name)}</td><td align=right><b>#{escape_javascript(color_measure ? color_measure.formatted_value : '-')}</b></td></tr>" + end html += "</table>" html end + + def size_value(measure) + if @variation_index + var=measure.variation(@variation_index) + var ? var.to_f.abs : 0.0 + elsif measure.value + measure.value.to_f.abs||0.0 + else + 0.0 + end + end def html_color(measure) - measure ? measure.color.html : '#DDDDDD' + MeasureColor.color(measure).html end end @@ -97,10 +115,10 @@ class Sonar::HtmlOutput < Treemap::HtmlOutput html = "" html += "<div id=\"node-#{node.id}\" style=\"" - html += "overflow: hidden; position:absolute;" - html += "left: #{node.bounds.x1}px; top: #{node.bounds.y1}px;" - html += "width: #{node.bounds.width}px; height: #{node.bounds.height}px;" - html += "background-color: #FFF;" + html += "overflow:hidden;position:absolute;" + html += "left:#{node.bounds.x1}px; top:#{node.bounds.y1}px;" + html += "width:#{node.bounds.width}px;height: #{node.bounds.height}px;" + html += "background-color:#FFF;" html += "\" class=\"node\">" html += "<div id=\"link_node-#{node.id}\" style='margin: 2px;background-color: #{node.color}; height: #{node.bounds.height-4}px; border: 1px solid #{node.color};' " if node.url && @details_at_depth==node.depth diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/sonar/treemap_builder.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/sonar/treemap_builder.rb index 7b80d4858c8..d79914f4be3 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/sonar/treemap_builder.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/sonar/treemap_builder.rb @@ -27,13 +27,13 @@ class Sonar::TreemapBuilder def self.size_metrics(options={}) exclude_user_managed=options[:exclude_user_managed]||false Metric.all.select{ |metric| - metric.enabled && !metric.hidden && metric.numeric? && !metric.domain.blank? && (!exclude_user_managed || !metric.user_managed?) + metric.treemap_size? && (!exclude_user_managed || !metric.user_managed?) }.sort end def self.color_metrics Metric.all.select{ |metric| - metric.enabled && !metric.hidden && ((metric.numeric? && metric.worst_value && metric.best_value) || metric.val_type==Metric::VALUE_TYPE_LEVEL) + metric.treemap_color? }.sort end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/filters/_treemap.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/filters/_treemap.html.erb index 983ffb96c7d..ee040078283 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/filters/_treemap.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/filters/_treemap.html.erb @@ -10,12 +10,12 @@ color_metric=metrics[1] <script> var treemap_width = $('treemap').getDimensions().width - 15; var treemap_height = document.viewport.getDimensions().height - 220; -function load_treemap(size_metric, color_metric, hide_form) { +function load_treemap(size_metric, color_metric, hide_form, variation_index) { $('treemap_loading').show(); $('treemap').hide(); - <%= remote_function :update => 'treemap', :url => {:action => 'treemap', :id => @filter.id}, + <%= remote_function :update => 'treemap', :url => {:action => 'treemap', :id => @filter.id, :show_periods => true}, :complete => "$('treemap_loading').hide();$('treemap').show();", - :with => "'width=' + treemap_width + '&height=' + treemap_height + '&size_metric=' + size_metric + '&color_metric=' + color_metric + '&hide_form=' + hide_form" %> + :with => "'width=' + treemap_width + '&height=' + treemap_height + '&size_metric=' + size_metric + '&color_metric=' + color_metric + '&hide_form=' + hide_form + '&var=' + variation_index" %> } -load_treemap('<%= size_metric.key -%>', '<%= color_metric.key -%>', <%= edit_mode -%>); +load_treemap('<%= size_metric.key -%>', '<%= color_metric.key -%>', <%= edit_mode -%>, <%= params[:var].to_i -%>); </script>
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/filters/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/filters/index.html.erb index 901852cabe5..96bb7d2c6a6 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/filters/index.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/filters/index.html.erb @@ -1,4 +1,4 @@ <%= render :partial => 'filters/tabs', :locals => {:selected_tab=> (@active && @active.filter ? @active.filter.id : nil) } %> <div class="tabs-panel"> -<%= render :partial => "filters/#{@filter.default_view}", :locals => {:edit_mode => false } if @filter %> +<%= render :partial => "filters/#{@filter.default_view}", :locals => {:edit_mode => false} if @filter %> </div>
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/filters/treemap.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/filters/treemap.html.erb index dbe6685989b..4fa5b299e59 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/filters/treemap.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/filters/treemap.html.erb @@ -14,6 +14,19 @@ <%= select_tag 'color_metric', options_grouped_by_domain(Sonar::TreemapBuilder.color_metrics, @color_metric.key), :id => 'color_metric', :class => 'small', :onchange => "load_treemap(this.form.size_metric.value,this.form.color_metric.value, false);return false;" %> </td> + <% if params[:show_periods]=='true' %> + <td class="sep"> </td> + <td> + <span class="comments">Period:</span> + <br/> + <select name="var" onchange="submit()" class="small"> + <option value="">None</option> + <% period_names.each_with_index do |name, index| %> + <option value="<%= index+1 -%>" <%= 'selected' if params[:var].to_i==index+1 -%>><%= name -%></value> + <% end %> + </select> + </td> + <% end %> </tr> </table> </form> |