From d163695d58b77e1fca590725520dfb57862548ca Mon Sep 17 00:00:00 2001 From: Fabrice Bellingard Date: Fri, 26 Aug 2011 18:06:54 +0200 Subject: [PATCH] SONAR-2074 Improve timeline widget - Default height set to 80 pixels - Events are displayed by default - Space added between measures in the footer - Adapt left margin to be able to display the max number on the Y axis - Chart displayed even if no values for a selected metric --- .../plugins/core/widgets/TimelineWidget.java | 2 +- .../plugins/core/widgets/timeline.html.erb | 48 ++++++++++--------- .../main/webapp/javascripts/protovis-sonar.js | 26 +++++++--- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TimelineWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TimelineWidget.java index 7483f0018cc..bceb37b2a0c 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TimelineWidget.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TimelineWidget.java @@ -31,7 +31,7 @@ import org.sonar.api.web.WidgetPropertyType; @WidgetProperty(key = "metric1", type = WidgetPropertyType.METRIC, defaultValue = "ncloc"), @WidgetProperty(key = "metric2", type = WidgetPropertyType.METRIC), @WidgetProperty(key = "metric3", type = WidgetPropertyType.METRIC), - @WidgetProperty(key = "displayEvents", type = WidgetPropertyType.BOOLEAN), + @WidgetProperty(key = "hideEvents", type = WidgetPropertyType.BOOLEAN), @WidgetProperty(key = "chartHeight", type = WidgetPropertyType.INTEGER) } ) diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/timeline.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/timeline.html.erb index 806d77f7a7c..88c1d07cdb5 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/timeline.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/timeline.html.erb @@ -33,37 +33,39 @@ js_snapshots = "[" js_metrics = "[" metric_data_map.keys.each_with_index() do |metric_id, index| - js_metrics += "\"" + metric_name_map[metric_id] + "\"," - js_data += "[" - metric_data_map[metric_id].each() do |metric_data| - m_date = Time.parse(metric_data[:date]) - js_data += "{\"x\":d(" - js_data += m_date.year.to_s - js_data += "," - # Need to decrease by 1 the month as the JS Date object start months at 0 (= January) - js_data += (m_date.month - 1).to_s - js_data += "," - js_data += m_date.day.to_s - js_data += "),\"y\":" - js_data += sprintf( "%0.02f", metric_data[:value]) - js_data += "}," - if index == 0 - # we fill the js_snapshots array (no need to do this more than once) - js_snapshots += "{\"sid\":" - js_snapshots += metric_data[:sid] - js_snapshots += ",\"d\":\"" - js_snapshots += human_short_date(m_date) - js_snapshots += "\"}," + unless metric_data_map[metric_id].empty? + js_metrics += "\"" + metric_name_map[metric_id] + "\"," + js_data += "[" + metric_data_map[metric_id].each() do |metric_data| + m_date = Time.parse(metric_data[:date]) + js_data += "{\"x\":d(" + js_data += m_date.year.to_s + js_data += "," + # Need to decrease by 1 the month as the JS Date object start months at 0 (= January) + js_data += (m_date.month - 1).to_s + js_data += "," + js_data += m_date.day.to_s + js_data += "),\"y\":" + js_data += sprintf( "%0.02f", metric_data[:value]) + js_data += "}," + if index == 0 + # we fill the js_snapshots array (no need to do this more than once) + js_snapshots += "{\"sid\":" + js_snapshots += metric_data[:sid] + js_snapshots += ",\"d\":\"" + js_snapshots += human_short_date(m_date) + js_snapshots += "\"}," + end end + js_data += "]," end - js_data += "]," end js_data += "]" js_snapshots += "]" js_metrics += "]" # Prepare also event structure if required - if widget_properties["displayEvents"] + unless widget_properties["hideEvents"] events = {} Event.find(:all, :conditions => {:resource_id => @resource.id}, :order => 'event_date').each() do |event| if events[event.event_date] diff --git a/sonar-server/src/main/webapp/javascripts/protovis-sonar.js b/sonar-server/src/main/webapp/javascripts/protovis-sonar.js index 4067c2b0c6b..9958ce7dd18 100755 --- a/sonar-server/src/main/webapp/javascripts/protovis-sonar.js +++ b/sonar-server/src/main/webapp/javascripts/protovis-sonar.js @@ -46,14 +46,27 @@ SonarWidgets.Timeline.prototype.render = function() { var footerFont = "12px Arial,Helvetica,sans-serif"; /* Sizing and scales. */ + var leftMargin = 20; + var show_y_axis = (data.length==1) + if (show_y_axis) { + // We must evaluate how wide the left margin must be, depending on the values that we get (so that they can be displayed correctly) + var maxNumberOnY = 0; + for each (var dataArray in trendData) { + for each (var d in dataArray) { + if (d.y > maxNumberOnY) maxNumberOnY = d.y; + } + } + minMargin = (maxNumberOnY + "").length * 7 + if (minMargin > leftMargin) leftMargin = minMargin + } var footerHeight = 30 + (events ? 3 : this.wMetrics.size()) * 12; - var w = widgetDiv.parentNode.clientWidth - 60, - h = (this.wHeight == null ? 250 : this.wHeight) + footerHeight - 5, + var w = widgetDiv.parentNode.clientWidth - leftMargin - 30, + h = (this.wHeight == null ? 80 : this.wHeight) + footerHeight - 5, S=2; var x = pv.Scale.linear(pv.blend(pv.map(data, function(d) {return d;})), function(d) {return d.x}).range(0, w); var y = new Array(data.length); - for(var i = 0; i < data.length; i++){ + for(var i = 0; i < data.length; i++){ y[i]=pv.Scale.linear(data[i], function(d) {return d.y;}).range(20, h-10) } var interpolate = "linear"; /* cardinal or linear */ @@ -64,7 +77,7 @@ SonarWidgets.Timeline.prototype.render = function() { .canvas(widgetDiv) .width(w) .height(h) - .left(30) + .left(leftMargin) .right(20) .bottom(footerHeight) .top(5) @@ -81,7 +94,6 @@ SonarWidgets.Timeline.prototype.render = function() { .text(x.tickFormat); /* Y-axis and ticks. */ - var show_y_axis = (data.length==1) if (show_y_axis) { vis.add(pv.Rule) .data(y[0].ticks(5)) @@ -113,7 +125,7 @@ SonarWidgets.Timeline.prototype.render = function() { .lineWidth(1) .add(pv.Dot) .left(0) - .bottom(function() {return 0 - 30 - this.parent.index * 12;}) + .bottom(function() {return 0 - 30 - this.parent.index * 14;}) .anchor("right").add(pv.Label) .font(footerFont) .text(function(d) {return metrics[this.parent.index] + ": " + d.y.toFixed(2);}); @@ -143,7 +155,7 @@ SonarWidgets.Timeline.prototype.render = function() { .add(pv.Dot) .visible(function(e) { return e.l[0].ld == snapshots[idx].d;}) .left(w/2+8) - .bottom(-42) + .bottom(-45) .shape("triangle") .fillStyle(function(e) {return e.l[0].ld == snapshots[idx].d ? eventHoverColor : eventColor}) .strokeStyle("grey") -- 2.39.5