summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java2
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/GlobalDefaultDashboard.java8
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TreemapWidget.java2
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/measures/MeasureFilterAsTreemapWidget.java55
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/measures/MeasureFilterTreemapWidget.java50
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/measure_filter_treemap.html.erb85
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/GlobalDefaultDashboardTest.java4
-rw-r--r--sonar-server/Gruntfile.coffee2
-rw-r--r--sonar-server/src/main/coffee/widgets/base.coffee12
-rw-r--r--sonar-server/src/main/coffee/widgets/treemap.coffee96
-rw-r--r--sonar-server/src/main/coffee/widgets/word-cloud.coffee11
-rw-r--r--sonar-server/src/main/less/style.less42
12 files changed, 266 insertions, 103 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
index 22e37e6bf34..484ff746d68 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
@@ -216,7 +216,7 @@ public final class CorePlugin extends SonarPlugin {
HotspotMetricWidget.class,
TreemapWidget.class,
MeasureFilterListWidget.class,
- MeasureFilterTreemapWidget.class,
+ MeasureFilterAsTreemapWidget.class,
WelcomeWidget.class,
DocumentationCommentsWidget.class,
DuplicationsWidget.class,
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/GlobalDefaultDashboard.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/GlobalDefaultDashboard.java
index f7933cfbbf4..5e204b18537 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/GlobalDefaultDashboard.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/GlobalDefaultDashboard.java
@@ -27,8 +27,8 @@ import org.sonar.core.measure.db.MeasureFilterDto;
import org.sonar.plugins.core.measurefilters.MyFavouritesFilter;
import org.sonar.plugins.core.measurefilters.ProjectFilter;
import org.sonar.plugins.core.widgets.WelcomeWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterAsTreemapWidget;
import org.sonar.plugins.core.widgets.measures.MeasureFilterListWidget;
-import org.sonar.plugins.core.widgets.measures.MeasureFilterTreemapWidget;
/**
* Projects global dashboard for Sonar
@@ -75,10 +75,10 @@ public final class GlobalDefaultDashboard extends DashboardTemplate {
.setProperty(MeasureFilterListWidget.PAGE_SIZE_PROPERTY, "20");
dashboard
- .addWidget(MeasureFilterTreemapWidget.ID, 2)
+ .addWidget(MeasureFilterAsTreemapWidget.ID, 2)
.setProperty(MeasureFilterListWidget.FILTER_PROPERTY, filter.getId().toString())
- .setProperty(MeasureFilterTreemapWidget.SIZE_METRIC_PROPERTY, "ncloc")
- .setProperty(MeasureFilterTreemapWidget.COLOR_METRIC_PROPERTY, "coverage");
+ .setProperty(MeasureFilterAsTreemapWidget.SIZE_METRIC_PROPERTY, "ncloc")
+ .setProperty(MeasureFilterAsTreemapWidget.COLOR_METRIC_PROPERTY, "coverage");
}
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TreemapWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TreemapWidget.java
index 6ce87b3be75..c941ef8ca36 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TreemapWidget.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TreemapWidget.java
@@ -33,6 +33,6 @@ import org.sonar.api.web.WidgetPropertyType;
public class TreemapWidget extends CoreWidget {
public TreemapWidget() {
// do not use the id "treemap" to avoid conflict with the same CSS class
- super("treemap-widget", "Treemap of Components", "/org/sonar/plugins/core/widgets/treemap.html.erb");
+ super("treemap-widget", "Treemap of Components", "/Users/Stas/Projects/sonar/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/treemap.html.erb");
}
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/measures/MeasureFilterAsTreemapWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/measures/MeasureFilterAsTreemapWidget.java
new file mode 100644
index 00000000000..ae959dd25ce
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/measures/MeasureFilterAsTreemapWidget.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+package org.sonar.plugins.core.widgets.measures;
+
+import org.sonar.api.web.*;
+import org.sonar.plugins.core.widgets.CoreWidget;
+import org.sonar.plugins.core.widgets.WidgetConstants;
+
+import static org.sonar.api.web.WidgetScope.GLOBAL;
+
+@WidgetCategory({"Filters"})
+@WidgetScope(GLOBAL)
+@WidgetProperties({
+ @WidgetProperty(key = MeasureFilterAsTreemapWidget.FILTER_PROPERTY, type = WidgetPropertyType.FILTER,
+ optional = false),
+ @WidgetProperty(key = MeasureFilterAsTreemapWidget.CHART_TITLE_PROPERTY, type = WidgetPropertyType.STRING),
+ @WidgetProperty(key = MeasureFilterAsTreemapWidget.SIZE_METRIC_PROPERTY, type = WidgetPropertyType.METRIC,
+ optional = true, options = { WidgetConstants.FILTER_OUT_NEW_METRICS }),
+ @WidgetProperty(key = MeasureFilterAsTreemapWidget.COLOR_METRIC_PROPERTY, type = WidgetPropertyType.METRIC,
+ optional = true, options = { WidgetConstants.FILTER_OUT_NEW_METRICS, "type:PERCENT,RATING,LEVEL" }),
+ @WidgetProperty(key = MeasureFilterAsTreemapWidget.HEIGHT_PERCENTS_PROPERTY, type = WidgetPropertyType.INTEGER,
+ optional = true, defaultValue = "55", description = "Height in percents of width"),
+ @WidgetProperty(key = MeasureFilterAsTreemapWidget.MAX_ITEMS_PROPERTY, type = WidgetPropertyType.INTEGER,
+ defaultValue = "100")
+})
+public class MeasureFilterAsTreemapWidget extends CoreWidget {
+ public static final String FILTER_PROPERTY = "filter";
+ public static final String SIZE_METRIC_PROPERTY = "sizeMetric";
+ public static final String COLOR_METRIC_PROPERTY = "colorMetric";
+ public static final String HEIGHT_PERCENTS_PROPERTY = "heightInPercents";
+ public static final String CHART_TITLE_PROPERTY = "chartTitle";
+ public static final String MAX_ITEMS_PROPERTY = "maxItems";
+ public static final String ID = "measure_filter_treemap";
+
+ public MeasureFilterAsTreemapWidget() {
+ super(ID, "Measure Filter as Treemap", "/Users/Stas/Projects/sonar/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/measure_filter_treemap.html.erb");
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/measures/MeasureFilterTreemapWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/measures/MeasureFilterTreemapWidget.java
deleted file mode 100644
index 29bc578b684..00000000000
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/measures/MeasureFilterTreemapWidget.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.
- */
-package org.sonar.plugins.core.widgets.measures;
-
-import org.sonar.api.web.*;
-import org.sonar.plugins.core.widgets.CoreWidget;
-import org.sonar.plugins.core.widgets.WidgetConstants;
-
-import static org.sonar.api.web.WidgetScope.GLOBAL;
-
-@WidgetCategory({"Filters"})
-@WidgetScope(GLOBAL)
-@WidgetProperties({
- @WidgetProperty(key = MeasureFilterTreemapWidget.FILTER_PROPERTY, type = WidgetPropertyType.FILTER, optional = false),
- @WidgetProperty(key = MeasureFilterTreemapWidget.SIZE_METRIC_PROPERTY, type = WidgetPropertyType.METRIC, optional = true, options = {WidgetConstants.FILTER_OUT_NEW_METRICS}),
- @WidgetProperty(key = MeasureFilterTreemapWidget.COLOR_METRIC_PROPERTY, type = WidgetPropertyType.METRIC, optional = true,
- options = {WidgetConstants.FILTER_OUT_NEW_METRICS,"type:PERCENT,RATING,LEVEL"}),
- @WidgetProperty(key = MeasureFilterTreemapWidget.HEIGHT_PERCENTS_PROPERTY, type = WidgetPropertyType.INTEGER, optional = true, defaultValue = "55",
- description = "Height in percents of width"),
- @WidgetProperty(key = MeasureFilterListWidget.DISPLAY_FILTER_DESCRIPTION, type = WidgetPropertyType.BOOLEAN, defaultValue = "false")
-})
-public class MeasureFilterTreemapWidget extends CoreWidget {
- public static final String FILTER_PROPERTY = "filter";
- public static final String SIZE_METRIC_PROPERTY = "sizeMetric";
- public static final String COLOR_METRIC_PROPERTY = "colorMetric";
- public static final String HEIGHT_PERCENTS_PROPERTY = "heightInPercents";
- public static final String DISPLAY_FILTER_DESCRIPTION = "displayFilterDescription";
- public static final String ID = "measure_filter_treemap";
-
- public MeasureFilterTreemapWidget() {
- super(ID, "Measure Filter as Treemap", "/org/sonar/plugins/core/widgets/measure_filter_treemap.html.erb");
- }
-}
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/measure_filter_treemap.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/measure_filter_treemap.html.erb
index 8d1021f5ade..67d2bd13cfb 100644
--- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/measure_filter_treemap.html.erb
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/measure_filter_treemap.html.erb
@@ -1,41 +1,56 @@
<%
- filter_id = widget_properties['filter']
- size_metric = widget_properties['sizeMetric']
- color_metric = widget_properties['colorMetric']
- filter = MeasureFilter.find_by_id(filter_id.to_i) if filter_id
- if filter
- url_options = {:controller => 'measures', :action => 'filter', :id => filter.id}
- filter.load_criteria_from_data
- filter.set_criteria_value(:display, 'treemap')
- if size_metric
- filter.set_criteria_value(:tmSize, size_metric.key)
- url_options[:tmSize]=size_metric.key
- end
- if color_metric
- filter.set_criteria_value(:tmColor, color_metric.key)
- url_options[:tmColor]=color_metric.key
- end
- filter.set_criteria_value(:tmHeight, widget_properties['heightInPercents'])
+ containerId = 'treemap-widget' + widget.id.to_s
+ chartTitle = widget_properties['chartTitle']
+ filterId = widget_properties['filter'].to_i
+ maxItems = widget_properties['maxItems'].to_i
-
- if !filter.require_authentication? || logged_in?
- filter.execute(self, :user => current_user)
-
- @widget_title = link_to h(filter.name), url_options
+ filter = MeasureFilter.find_by_id(filterId.to_i)
+ @widget_title = link_to h(filter.name), {:controller => 'measures', :action => 'filter', :id => filter.id, :display => 'list'}
%>
- <% if widget_properties['displayFilterDescription'] && !filter.description.blank? %>
- <div style="padding-bottom: 5px">
- <span class="note"><%= h filter.description -%></span>
- </div>
+<div class="treemap-widget" id="<%= containerId %>">
+ <!--[if lte IE 8 ]> <h3><%= message('widget.unsupported_browser_warning') -%></h3> <![endif]-->
+
+ <!--[if (gte IE 9)|!(IE)]><!-->
+ <% if chartTitle %>
+ <h3 style="margin-bottom: 5px;"><%= h(chartTitle) -%></h3>
<% end %>
+ <!--<![endif]-->
+</div>
- <%= render :partial => 'measures/display_treemap', :locals => {:edit_mode => false, :widget_id => widget.id, :filter => filter} %>
-<%
- end
- else
-%>
- <p><i class="icon-alert-warn"></i> <%= message 'measure_filter.widget.unknown_filter_warning' -%></p>
-<%
- end
-%>
+<!--[if (gte IE 9)|!(IE)]><!-->
+<script>
+ (function () {
+ var metrics = [
+ '<%= widget_properties['colorMetric'].name -%>',
+ '<%= widget_properties['sizeMetric'].name -%>'
+ ],
+ query = [
+ 'filter=<%= filterId -%>',
+ 'metrics=' + metrics.join(','),
+ 'fields=name,longName,qualifier',
+ 'pageSize=<%= maxItems -%>',
+ 'page=1',
+ 'sort=metric:' + metrics[1],
+ 'asc=false'
+ ].join('&'),
+ widget = new SonarWidgets.Widget();
+
+ widget
+ .type('Treemap')
+ .source(baseUrl + '/measures/search_filter?' + query)
+ .metricsPriority(metrics)
+ .options({
+ heightInPercents: '<%= widget_properties['heightInPercents'] -%>',
+ maxItemsReachedMessage: '<%= message("widget.measure_filter_histogram.max_items_reached", :params => [maxItems]) -%>',
+ baseUrl: baseUrl + '/dashboard/index/',
+ noData: '<%= message('no_data') -%>'
+ })
+ .render('#<%= containerId -%>');
+
+ autoResize(500, function() {
+ widget.update('#<%= containerId -%>');
+ });
+ })();
+</script>
+<!--<![endif]-->
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/GlobalDefaultDashboardTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/GlobalDefaultDashboardTest.java
index 49770b62dd7..b5f79bb88de 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/GlobalDefaultDashboardTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/dashboards/GlobalDefaultDashboardTest.java
@@ -29,8 +29,8 @@ import org.sonar.plugins.core.CorePlugin;
import org.sonar.plugins.core.measurefilters.MyFavouritesFilter;
import org.sonar.plugins.core.measurefilters.ProjectFilter;
import org.sonar.plugins.core.widgets.WelcomeWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterAsTreemapWidget;
import org.sonar.plugins.core.widgets.measures.MeasureFilterListWidget;
-import org.sonar.plugins.core.widgets.measures.MeasureFilterTreemapWidget;
import java.util.List;
@@ -77,7 +77,7 @@ public class GlobalDefaultDashboardTest {
assertThat(secondColumn).hasSize(2);
assertThat(secondColumn.get(0).getId()).isEqualTo(MeasureFilterListWidget.ID);
assertThat(secondColumn.get(0).getProperty("filter")).isEqualTo("101");
- assertThat(secondColumn.get(1).getId()).isEqualTo(MeasureFilterTreemapWidget.ID);
+ assertThat(secondColumn.get(1).getId()).isEqualTo(MeasureFilterAsTreemapWidget.ID);
assertThat(secondColumn.get(1).getProperty("filter")).isEqualTo("101");
}
diff --git a/sonar-server/Gruntfile.coffee b/sonar-server/Gruntfile.coffee
index 0f06e25c577..e49048f7eff 100644
--- a/sonar-server/Gruntfile.coffee
+++ b/sonar-server/Gruntfile.coffee
@@ -94,6 +94,7 @@ module.exports = (grunt) ->
'<%= pkg.assets %>js/widgets/pie-chart.js'
'<%= pkg.assets %>js/widgets/histogram.js'
'<%= pkg.assets %>js/widgets/word-cloud.js'
+ '<%= pkg.assets %>js/widgets/treemap.js'
'<%= pkg.assets %>js/top-search.js'
'<%= pkg.assets %>js/sortable.js'
'<%= pkg.assets %>js/common/inputs.js'
@@ -125,6 +126,7 @@ module.exports = (grunt) ->
'<%= pkg.assets %>js/widgets/pie-chart.js'
'<%= pkg.assets %>js/widgets/histogram.js'
'<%= pkg.assets %>js/widgets/word-cloud.js'
+ '<%= pkg.assets %>js/widgets/treemap.js'
'<%= pkg.assets %>js/top-search.js'
'<%= pkg.assets %>js/sortable.js'
'<%= pkg.assets %>js/common/inputs.js'
diff --git a/sonar-server/src/main/coffee/widgets/base.coffee b/sonar-server/src/main/coffee/widgets/base.coffee
index 133c15e464d..5531ceb2d92 100644
--- a/sonar-server/src/main/coffee/widgets/base.coffee
+++ b/sonar-server/src/main/coffee/widgets/base.coffee
@@ -2,6 +2,9 @@ window.SonarWidgets ?= {}
class BaseWidget
lineHeight: 20
+ colorLow: '#d62728'
+ colorHigh: '#85bb43'
+ colorUnknown: '#777'
constructor: ->
@@ -47,4 +50,11 @@ class BaseWidget
@
-window.SonarWidgets.BaseWidget = BaseWidget \ No newline at end of file
+ tooltip: (d) ->
+ title = d.longName
+ title += "\n#{@colorMetric.name}: #{@colorMetric.formattedValue d}" if @colorMetric.value(d)?
+ title += "\n#{@sizeMetric.name}: #{@sizeMetric.formattedValue d}" if @sizeMetric.value(d)?
+ title
+
+
+window.SonarWidgets.BaseWidget = BaseWidget
diff --git a/sonar-server/src/main/coffee/widgets/treemap.coffee b/sonar-server/src/main/coffee/widgets/treemap.coffee
new file mode 100644
index 00000000000..7cb065d02b4
--- /dev/null
+++ b/sonar-server/src/main/coffee/widgets/treemap.coffee
@@ -0,0 +1,96 @@
+class Treemap extends window.SonarWidgets.BaseWidget
+ sizeLow: 10
+ sizeHigh: 24
+
+
+ constructor: ->
+ @addField 'width', null
+ @addField 'height', null
+ @addField 'maxResultsReached', false
+ super
+
+
+ getNodes: ->
+ @treemap.nodes(children: @components()).filter (d) -> !d.children
+
+
+ renderTreemap: ->
+ @treemap = d3.layout.treemap()
+ @treemap.value (d) =>
+ @sizeMetric.value d
+ @cells = @box.selectAll('.treemap-cell').data @getNodes()
+
+ cellsEnter = @cells.enter().append 'div'
+ cellsEnter.classed 'treemap-cell', true
+ cellsEnter.attr 'title', (d) => @tooltip d
+ cellsEnter.style 'color', (d) =>
+ if @colorMetric.value(d)? then @color @colorMetric.value(d) else @colorUnknown
+ cellsEnter.style 'font-size', (d) => "#{@size @sizeMetric.value d}px"
+
+ cellsLink = cellsEnter.append('a').classed 'treemap-detach', true
+ cellsLink.attr 'target', '_blank'
+ cellsLink.attr 'href', (d) =>
+ url = @options().baseUrl + encodeURIComponent(d.key)
+ url += '?metric=' + encodeURIComponent(@colorMetric.key) if d.qualifier == 'CLA' || d.qualifier == 'FIL'
+ url
+ cellsLink.append('i').attr 'class', (d) -> "icon-qualifier-#{d.qualifier.toLowerCase()}"
+
+ @cellsInner = cellsEnter.append('div').classed 'treemap-inner', true
+ @cellsInner.text (d) -> d.longName
+ @cellsInner.style 'border-color', (d) =>
+ if @colorMetric.value(d)? then @color @colorMetric.value(d) else @colorUnknown
+
+ @attachEvents cellsEnter
+
+
+ attachEvents: (cells) ->
+
+
+ positionCells: ->
+ @cells.style 'left', (d) -> "#{d.x}px"
+ @cells.style 'top', (d) -> "#{d.y}px"
+ @cells.style 'width', (d) -> "#{d.dx}px"
+ @cells.style 'height', (d) -> "#{d.dy}px"
+ @cells.classed 'treemap-cell-small', (d) -> d.dy < 60
+ @cellsInner.style 'line-height', (d) -> "#{d.dy}px"
+
+
+ render: (container) ->
+ box = d3.select(container).append('div')
+ box.classed 'sonar-d3', true
+ @box = box.append('div').classed 'treemap-container', true
+
+ # Configure metrics
+ @addMetric 'colorMetric', 0
+ @addMetric 'sizeMetric', 1
+
+ # Configure scales
+ @color = d3.scale.linear().domain([0, 100])
+ if @colorMetric.direction == 1
+ @color.range [@colorLow, @colorHigh]
+ else
+ @color.range [@colorHigh, @colorLow]
+
+ sizeDomain = d3.extent @components(), (d) => @sizeMetric.value d
+ @size = d3.scale.linear().domain(sizeDomain).range [@sizeLow, @sizeHigh]
+
+ # Show maxResultsReached message
+ if @maxResultsReached()
+ maxResultsReachedLabel = box.append('div').text @options().maxItemsReachedMessage
+ maxResultsReachedLabel.classed 'max-results-reached-message', true
+
+ @renderTreemap()
+ super
+
+
+ update: ->
+ @width @box.property 'offsetWidth'
+ @height (@width() / 100.0 * @options().heightInPercents)
+ @box.style 'height', "#{@height()}px"
+ @treemap.size [@width(), @height()]
+ @cells.data @getNodes()
+ @positionCells()
+
+
+
+window.SonarWidgets.Treemap = Treemap
diff --git a/sonar-server/src/main/coffee/widgets/word-cloud.coffee b/sonar-server/src/main/coffee/widgets/word-cloud.coffee
index 1e09b55a6d5..1d98fd1add0 100644
--- a/sonar-server/src/main/coffee/widgets/word-cloud.coffee
+++ b/sonar-server/src/main/coffee/widgets/word-cloud.coffee
@@ -1,7 +1,4 @@
class WordCloud extends window.SonarWidgets.BaseWidget
- colorLow: '#d62728'
- colorHigh: '#1f77b4'
- colorUnknown: '#777'
sizeLow: 10
sizeHigh: 24
@@ -22,11 +19,7 @@ class WordCloud extends window.SonarWidgets.BaseWidget
url = @options().baseUrl + encodeURIComponent(d.key)
url += '?metric=' + encodeURIComponent(@colorMetric.key) if d.qualifier == 'CLA' || d.qualifier == 'FIL'
url
- wordsEnter.attr 'title', (d) =>
- title = d.longName
- title += " | #{@colorMetric.name}: #{@colorMetric.formattedValue d}" if @colorMetric.value(d)?
- title += " | #{@sizeMetric.name}: #{@sizeMetric.formattedValue d}" if @sizeMetric.value(d)?
- title
+ wordsEnter.attr 'title', (d) => @tooltip d
words.style 'color', (d) =>
if @colorMetric.value(d)? then @color @colorMetric.value(d) else @colorUnknown
@@ -67,4 +60,4 @@ class WordCloud extends window.SonarWidgets.BaseWidget
-window.SonarWidgets.WordCloud = WordCloud \ No newline at end of file
+window.SonarWidgets.WordCloud = WordCloud
diff --git a/sonar-server/src/main/less/style.less b/sonar-server/src/main/less/style.less
index d359113276f..aedda2cd0e9 100644
--- a/sonar-server/src/main/less/style.less
+++ b/sonar-server/src/main/less/style.less
@@ -2799,6 +2799,48 @@ div.rule-title {
fill: #777;
}
+.sonar-d3 .treemap-container {
+ position: relative;
+}
+
+.sonar-d3 .treemap-cell {
+ position: absolute;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ .box-sizing(border-box);
+}
+
+.sonar-d3 .treemap-inner {
+ position: absolute;
+ z-index: 1;
+ top: 0; left: 0; bottom: 0; right: 0;
+ padding: 0 5px;
+ border: 1px solid;
+ text-align: center;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.sonar-d3 .treemap-detach {
+ position: absolute;
+ z-index: 2;
+ top: 5px; right: 5px;
+ line-height: 16px;
+ color: inherit;
+ opacity: 0.5;
+
+ &:hover { opacity: 1; }
+}
+
+.sonar-d3 .treemap-cell-small {
+ .treemap-inner { text-indent: -9999px; }
+ .treemap-detach {
+ top: 50%; left: 50%;
+ margin: -8px 0 0 -8px;
+ }
+}
+
/* ------------------- Admin pages ------------------- */