aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2014-07-08 23:02:40 +0600
committerStas Vilchik <vilchiks@gmail.com>2014-07-08 23:02:56 +0600
commit70edcaa052727c5fb844e391d894b2f1202fe0ad (patch)
tree6643c6aee910470556af01ee03b2b81b58edfa5c
parent79ab08f123b13eb52c1f2c6ab828a2586ac8aaa3 (diff)
downloadsonarqube-70edcaa052727c5fb844e391d894b2f1202fe0ad.tar.gz
sonarqube-70edcaa052727c5fb844e391d894b2f1202fe0ad.zip
SONAR-5207 Dynamic size of labels. Show labels in two lines. l10n messages.
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TreemapWidget.java6
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/treemap.html.erb90
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties7
-rw-r--r--sonar-server/src/main/coffee/widgets/treemap.coffee31
-rw-r--r--sonar-server/src/main/less/style.less23
5 files changed, 123 insertions, 34 deletions
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..e0787c4c5a8 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
@@ -17,6 +17,7 @@
* 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;
import org.sonar.api.measures.CoreMetrics;
@@ -25,14 +26,15 @@ import org.sonar.api.web.WidgetProperty;
import org.sonar.api.web.WidgetPropertyType;
@WidgetProperties({
+ @WidgetProperty(key = "chartTitle", type = WidgetPropertyType.STRING),
@WidgetProperty(key = "sizeMetric", type = WidgetPropertyType.METRIC, defaultValue = CoreMetrics.NCLOC_KEY, options = {WidgetConstants.FILTER_OUT_NEW_METRICS}),
@WidgetProperty(key = "colorMetric", type = WidgetPropertyType.METRIC, defaultValue = CoreMetrics.COVERAGE_KEY,
options = {WidgetConstants.FILTER_OUT_NEW_METRICS, "type:PERCENT,RATING,LEVEL"}),
- @WidgetProperty(key = "heightInPercents", type = WidgetPropertyType.INTEGER, optional = true, defaultValue = "55")
+ @WidgetProperty(key = "heightInPercents", type = WidgetPropertyType.INTEGER, optional = true, defaultValue = "55"),
+ @WidgetProperty(key = "maxItems", type = WidgetPropertyType.INTEGER, defaultValue = "100")
})
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");
}
}
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/treemap.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/treemap.html.erb
index 2dccace2b6f..55c2c87796a 100644
--- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/treemap.html.erb
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/treemap.html.erb
@@ -1,13 +1,81 @@
<%
- size_metric = widget_properties['sizeMetric']
- color_metric = widget_properties['colorMetric']
-
- filter = MeasureFilter.new
- filter.set_criteria_value(:base, @resource.key)
- filter.set_criteria_value(:display, 'treemap')
- filter.set_criteria_value(:tmSize, size_metric.key) if size_metric
- filter.set_criteria_value(:tmColor, color_metric.key) if color_metric
- filter.set_criteria_value(:tmHeight, widget_properties['heightInPercents'])
- filter.execute(self, :user => current_user)
+ containerId = 'project-file-widget' + widget.id.to_s
+ colorMetric = widget_properties['colorMetric']
+ sizeMetric = widget_properties['sizeMetric']
+ chartTitle = widget_properties['chartTitle']
+ maxItems = widget_properties['maxItems'].to_i
%>
-<%= render :partial => "measures/display_treemap", :locals => {:edit_mode => false, :widget_id => widget.id, :filter => filter} %>
+
+<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>
+
+<!--[if (gte IE 9)|!(IE)]><!-->
+<script>
+ (function () {
+ <%
+ filter = MeasureFilter.new
+ filter.set_criteria_value(:base, @resource.key)
+ filter.set_criteria_value(:display, 'treemap')
+ filter.set_criteria_value(:tmSize, sizeMetric.key) if sizeMetric
+ filter.set_criteria_value(:tmColor, colorMetric.key) if colorMetric
+ filter.set_criteria_value(:tmHeight, widget_properties['heightInPercents'])
+ filter.execute(self, :user => current_user)
+ %>
+
+ var data = {
+ metrics: {
+ <%= colorMetric.name -%>: {
+ name: '<%= colorMetric.short_name -%>',
+ direction: <%= colorMetric.direction -%>
+ },
+ <%= sizeMetric.name -%>: {
+ name: '<%= sizeMetric.short_name -%>'
+ }
+ },
+ components: [
+ <%
+ filter.rows.each do |row|
+ color = row.measure(colorMetric)
+ size = row.measure(sizeMetric)
+ %>
+ {
+ key: '<%= escape_javascript row.resource.key -%>',
+ name: '<%= escape_javascript row.resource.name -%>',
+ longName: '<%= escape_javascript row.resource.long_name -%>',
+ qualifier: '<%= escape_javascript row.resource.qualifier -%>',
+ measures: {
+ <%= colorMetric.name -%>: { val: <%= color ? color.value : "null" -%>, fval: '<%= color ? color.formatted_value : "-" -%>' },
+ <%= sizeMetric.name -%>: { val: <%= size ? size.value : "null" -%>, fval: '<%= size ? size.formatted_value : "-" -%>' }
+ }
+ },
+ <% end %>
+ ]
+ },
+ widget = new SonarWidgets.Treemap();
+
+ widget
+ .metrics(data.metrics)
+ .metricsPriority(['<%= colorMetric.name -%>', '<%= sizeMetric.name -%>'])
+ .components(data.components)
+ .options({
+ heightInPercents: '<%= widget_properties['heightInPercents'] -%>',
+ maxItems: <%= maxItems -%>,
+ 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/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
index 35813a3e104..e01120de5d6 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -1244,6 +1244,9 @@ widget.treemap-widget.property.colorMetric.name=Color Metric
widget.treemap-widget.property.colorMetric.description=Metric used for square color
widget.treemap-widget.property.heightInPercents.name=Height
widget.treemap-widget.property.heightInPercents.description=Height in percents of width
+widget.treemap-widget.property.chartTitle.name=Chart Title
+widget.treemap-widget.property.maxItems.name=Max Components
+widget.treemap-widget.property.maxItems.description=Maximum number of components to show
widget.welcome.name=Welcome
widget.welcome.description=Welcome message used to provide links to the most valuable resources like documentation and support
@@ -1270,7 +1273,9 @@ widget.measure_filter_treemap.property.sizeMetric.name=Size Metric
widget.measure_filter_treemap.property.colorMetric.name=Color Metric
widget.measure_filter_treemap.property.heightInPercents.name=Height
widget.measure_filter_treemap.property.heightInPercents.description=Height in percents of width
-widget.measure_filter_treemap.property.displayFilterDescription.name=Display Filter Description
+widget.measure_filter_treemap.property.chartTitle.name=Chart Title
+widget.measure_filter_treemap.property.maxItems.name=Max Components
+widget.measure_filter_treemap.property.maxItems.description=Maximum number of components to show
widget.technical_debt_pyramid.name=Technical Debt Pyramid
widget.technical_debt_pyramid.description=Displays the technical debt by characteristics. Characteristics located at the bottom should be addressed before those on top.
diff --git a/sonar-server/src/main/coffee/widgets/treemap.coffee b/sonar-server/src/main/coffee/widgets/treemap.coffee
index 6b2ce67acca..72f4f2e04d0 100644
--- a/sonar-server/src/main/coffee/widgets/treemap.coffee
+++ b/sonar-server/src/main/coffee/widgets/treemap.coffee
@@ -1,7 +1,6 @@
class Treemap extends window.SonarWidgets.BaseWidget
sizeLow: 11
- sizeMedium: 13
- sizeHigh: 20
+ sizeHigh: 18
constructor: ->
@@ -28,8 +27,13 @@ class Treemap extends window.SonarWidgets.BaseWidget
@cells.style 'background-color', (d) =>
if @colorMetric.value(d)? then @color @colorMetric.value(d) else @colorUnknown
+ prefix = @mostCommonPrefix _.pluck @components(), 'longName'
+ prefixLength = prefix.length
@cellsInner = @box.selectAll('.treemap-inner').data nodes
- @cellsInner.text (d) -> d.longName
+ @cellsInner.html (d) ->
+ if prefixLength > 0
+ "#{prefix}<br>#{d.longName.substr prefixLength}"
+ else d.longName
@attachEvents cellsEnter
@@ -54,9 +58,12 @@ class Treemap extends window.SonarWidgets.BaseWidget
@cells.style 'left', (d) -> "#{d.x}px"
@cells.style 'top', (d) -> "#{d.y}px"
@cells.style 'width', (d) -> "#{d.dx}px"
+ @cellsInner.style 'max-width', (d) -> "#{d.dx}px"
@cells.style 'height', (d) -> "#{d.dy}px"
@cells.style 'line-height', (d) -> "#{d.dy}px"
- @cells.style 'font-size', (d) => "#{@size d.dx}px"
+ @cells.style 'font-size', (d) => "#{@size (d.dx / d.longName.length)}px"
+ @cells.classed 'treemap-cell-small', (d) ->
+ (d.dx / d.longName.length) < 1 || d.dy < 40
renderLegend: (box) ->
@@ -120,7 +127,7 @@ class Treemap extends window.SonarWidgets.BaseWidget
@color.range @colors5
else
@color.range @colors5r
- @size = d3.scale.linear().domain([80, 300]).range([@sizeLow, @sizeHigh]).clamp true
+ @size = d3.scale.linear().domain([3, 15]).range([@sizeLow, @sizeHigh]).clamp true
@treemap = d3.layout.treemap()
@treemap.value (d) => @sizeMetric.value d
@@ -177,5 +184,19 @@ class Treemap extends window.SonarWidgets.BaseWidget
else @stopDrilldown()
+ mostCommonPrefix: (strings) ->
+ sortedStrings = strings.slice(0).sort()
+ firstString = sortedStrings[0]
+ firstStringLength = firstString.length
+ lastString = sortedStrings[sortedStrings.length - 1]
+ i = 0
+ while i < firstStringLength && firstString.charAt(i) == lastString.charAt(i)
+ i++
+ prefix = firstString.substr 0, i
+ lastPrefixPart = _.last prefix.split /[\s\\\/]/
+ prefix.substr 0, prefix.length - lastPrefixPart.length
+
+
+
window.SonarWidgets.Treemap = Treemap
diff --git a/sonar-server/src/main/less/style.less b/sonar-server/src/main/less/style.less
index 4d625437987..b431f3df0dd 100644
--- a/sonar-server/src/main/less/style.less
+++ b/sonar-server/src/main/less/style.less
@@ -2819,17 +2819,19 @@ div.rule-title {
border-right: 1px solid #fff;
border-bottom: 1px solid #fff;
.box-sizing(border-box);
+ text-align: center;
cursor: pointer;
}
.sonar-d3 .treemap-inner {
- position: absolute;
- z-index: 1;
- top: 0; left: 0; bottom: 0; right: 0;
- padding: 0 5px;
+ display: inline-block;
+ vertical-align: middle;
+ line-height: 1.2;
+ padding: 5px;
+ .box-sizing(border-box);
color: #fff;
font-weight: 300;
- text-align: center;
+ text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -2847,16 +2849,7 @@ div.rule-title {
}
.sonar-d3 .treemap-cell-small {
- .treemap-inner { text-indent: -9999px; }
- .treemap-dashboard {
- top: 50%; left: 50%;
- margin: -8px 0 0 -8px;
- }
-}
-
-.sonar-d3 .treemap-cell-very-small {
- .treemap-inner { text-indent: -9999px; }
- .treemap-dashboard { display: none; }
+ .treemap-inner { display: none; }
}
.sonar-d3 .treemap-breadcrumbs {