@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 = "maxItems", type = WidgetPropertyType.INTEGER, defaultValue = "100")
+ @WidgetProperty(key = "maxItems", type = WidgetPropertyType.INTEGER, defaultValue = "30")
})
public class TreemapWidget extends CoreWidget {
public TreemapWidget() {
optional = false),
@WidgetProperty(key = MeasureFilterAsTreemapWidget.CHART_TITLE_PROPERTY, type = WidgetPropertyType.STRING),
@WidgetProperty(key = MeasureFilterAsTreemapWidget.SIZE_METRIC_PROPERTY, type = WidgetPropertyType.METRIC,
- defaultValue = CoreMetrics.COMPLEXITY_KEY, options = {WidgetConstants.FILTER_OUT_NEW_METRICS}),
+ defaultValue = CoreMetrics.NCLOC_KEY, options = {WidgetConstants.FILTER_OUT_NEW_METRICS}),
@WidgetProperty(key = MeasureFilterAsTreemapWidget.COLOR_METRIC_PROPERTY, type = WidgetPropertyType.METRIC,
defaultValue = CoreMetrics.COVERAGE_KEY,
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")
+ defaultValue = "30")
})
public class MeasureFilterAsTreemapWidget extends CoreWidget {
public static final String FILTER_PROPERTY = "filter";
widget.treemap-widget.name=Treemap of Components
widget.treemap-widget.description=Displays a treemap of all direct components of the selected resource.
widget.treemap-widget.property.sizeMetric.name=Size Metric
-widget.treemap-widget.property.sizeMetric.description=Metric used for square size
+widget.treemap-widget.property.sizeMetric.desc=Metric used for square size
widget.treemap-widget.property.colorMetric.name=Color Metric
-widget.treemap-widget.property.colorMetric.description=Metric used for square color
+widget.treemap-widget.property.colorMetric.desc=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.heightInPercents.desc=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.treemap-widget.property.maxItems.desc=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
widget.measure_filter_treemap.description=Displays the result of pre-configured measure filter as a Treemap.
widget.measure_filter_treemap.property.filter.name=Filter
widget.measure_filter_treemap.property.sizeMetric.name=Size Metric
+widget.measure_filter_treemap.property.sizeMetric.desc=Metric used for square size
widget.measure_filter_treemap.property.colorMetric.name=Color Metric
+widget.measure_filter_treemap.property.colorMetric.desc=Metric used for square color
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.heightInPercents.desc=Height in percents of width
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.measure_filter_treemap.property.maxItems.desc=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.
colors4r: ['#00aa00', '#80cc00', '#f77700', '#ee0000']
colors5: ['#ee0000', '#f77700', '#ffee00', '#80cc00', '#00aa00']
colors5r: ['#00aa00', '#80cc00', '#ffee00', '#f77700', '#ee0000']
+ colorsLevel: ['#d4333f', '#ff9900', '#85bb43', '##b4b4b4']
colorUnknown: '#777'
key = @metricsPriority()[index]
@[property] = _.extend @metrics()[key],
key: key
- value: (d) -> d.measures[key]?.val
- formattedValue: (d) -> d.measures[key]?.fval
+ value: (d) ->
+ if d.measures[key]?
+ if d.measures[key].text? then d.measures[key].text else d.measures[key].val
+ formattedValue: (d) ->
+ if d.measures[key]?
+ if d.measures[key].text? then d.measures[key].text else d.measures[key].fval
@
@cells.attr 'title', (d) => @tooltip d
@cells.style 'background-color', (d) =>
if @colorMetric.value(d)? then @color @colorMetric.value(d) else @colorUnknown
+ @cells.classed 'treemap-cell-drilldown', (d) ->
+ d.qualifier? && d.qualifier != 'FIL' && d.qualifier != 'CLA'
prefix = @mostCommonPrefix _.pluck @components(), 'longName'
prefixLength = prefix.length
@attachEvents cellsEnter
- # Show maxResultsReached message
@maxResultsReachedLabel.style 'display', if @maxResultsReached() then 'block' else 'none'
attachEvents: (cells) ->
- cells.on 'click', (d) =>
- @requestChildren d
+ cells.on 'click', (d) => @requestChildren d
+ cells.on 'dblclick', (d) => @openDashboard d
+
+
+ openDashboard: (d) ->
+ url = @options().baseUrl + encodeURIComponent(d.key)
+ url += '?metric=' + encodeURIComponent(@colorMetric.key) if d.qualifier == 'CLA' || d.qualifier == 'FIL'
+ window.location = url
positionCells: ->
@updateBreadcrumbs()
+ getColorScale: ->
+ return @getLevelColorScale() if @colorMetric.type == 'LEVEL'
+ return @getRatingColorScale() if @colorMetric.type == 'RATING'
+ @getPercentColorScale()
+
+
+ getPercentColorScale: ->
+ color = d3.scale.linear().domain([0, 25, 50, 75, 100])
+ color.range if @colorMetric.direction == 1 then @colors5 else @colors5r
+ color
+
+
+ getRatingColorScale: ->
+ color = d3.scale.ordinal().domain([1, 2, 3, 4, 5]).range @colors5r
+ color
+
+
+ getLevelColorScale: ->
+ color = d3.scale.ordinal().domain(['ERROR', 'WARN', 'OK', 'NONE']).range @colorsLevel
+ color
+
+
render: (container) ->
box = d3.select(container).append('div')
box.classed 'sonar-d3', true
@addMetric 'sizeMetric', 1
# Configure scales
- @color = d3.scale.linear().domain([0, 25, 50, 75, 100])
- if @colorMetric.direction == 1
- @color.range @colors5
- else
- @color.range @colors5r
+ @color = @getColorScale()
+
@size = d3.scale.linear().domain([3, 15]).range([@sizeLow, @sizeHigh]).clamp true
@treemap = d3.layout.treemap()
@positionCells()
- stopDrilldown: ->
-
-
formatComponents: (data) ->
components = _.filter data, (component) =>
hasSizeMetric = => _.findWhere component.msr, key: @sizeMetric.key
components = _.initial components, components.length - @options().maxItems - 1
@updateTreemap components, components.length > @options().maxItems
@addToBreadcrumbs _.extend d, components: components, maxResultsReached: @maxResultsReached()
- else @stopDrilldown()
mostCommonPrefix: (strings) ->
border-bottom: 1px solid #fff;
.box-sizing(border-box);
text-align: center;
+}
+
+.sonar-d3 .treemap-cell-drilldown {
cursor: pointer;
+ .trans(opacity);
+
+ &:hover { opacity: 0.8; }
}
.sonar-d3 .treemap-inner {