-//******************* TIMELINE CHART ******************* //
-/*
- * Displays the evolution of metrics on a line chart, displaying related events.
- *
- * Parameters of the Timeline class:
- * - data: array of arrays, each containing maps {x,y,yl} where x is a (JS) date, y is a number value (representing
- * a metric value at a given time), and yl the localized value of y. The {x,y, yl} maps must be sorted
- * by ascending date.
- * - metrics: array of metric names. The order is important as it defines which array of the "data" parameter
- * represents which metric.
- * - snapshots: array of maps {sid,d} where sid is the snapshot id and d is the locale-formatted date of the snapshot.
- * The {sid,d} maps must be sorted by ascending date.
- * - events: array of maps {sid,d,l[{n}]} where sid is the snapshot id corresponding to an event, d is the (JS) date
- * of the event, and l is an array containing the different event names for this date.
- * - height: height of the chart area (notice header excluded). Defaults to 80.
- *
- * Example: displays 2 metrics:
- *
- <code>
- function d(y,m,d,h,min,s) {
- return new Date(y,m,d,h,min,s);
- }
- var data = [
- [{x:d(2011,5,15,0,1,0),y:912.00,yl:"912"},{x:d(2011,6,21,0,1,0),y:152.10,yl:"152.10"}],
- [{x:d(2011,5,15,0,1,0),y:52.20,yi:"52.20"},{x:d(2011,6,21,0,1,0),y:1452.10,yi:"1,452.10"}]
- ];
- var metrics = ["Lines of code","Rules compliance"];
- var snapshots = [{sid:1,d:"June 15, 2011 00:01"},{sid:30,d:"July 21, 2011 00:01"}];
- var events = [
- {sid:1,d:d(2011,5,15,0,1,0),l:[{n:"0.6-SNAPSHOT"},{n:"Sun checks"}]},
- {sid:30,d:d(2011,6,21,0,1,0),l:[{n:"0.7-SNAPSHOT"}]}
- ];
-
- var timeline = new SonarWidgets.Timeline('timeline-chart-20')
- .height(160)
- .data(data)
- .snapshots(snapshots)
- .metrics(metrics)
- .events(events);
- timeline.render();
- </code>
- *
- */
-
-
/*global d3:false*/
window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets;
};
- window.SonarWidgets.Timeline.prototype.render = function () {
- var widget = this;
-
- this.svg = this.container.append('svg')
- .attr('class', 'sonar-d3');
-
- this.gWrap = this.svg.append('g');
-
- this.gtimeAxis = this.gWrap.append('g')
- .attr('class', 'axis x');
-
- this.plotWrap = this.gWrap.append('g')
- .attr('class', 'plot');
-
- this.scanner = this.plotWrap.append('line');
-
- this.infoWrap = this.gWrap.append('g')
- .attr('class', 'info');
-
- this.infoDate = this.infoWrap.append('text')
- .attr('class', 'info-text info-text-bold');
-
- this.infoEvent = this.infoWrap.append('text')
- .attr('class', 'info-text info-text-small');
-
- this.gWrap
- .attr('transform', trans(this.margin().left, this.margin().top));
-
+ window.SonarWidgets.Timeline.prototype.initScalesAndAxis = function () {
// Configure scales
var timeDomain = this.data()
.map(function(_) {
this.color = d3.scale.category10();
-
// Configure the axis
this.timeAxis = d3.svg.axis()
.scale(this.time)
.orient('bottom')
.ticks(5);
+ };
- this.showLimitHistoryMessage();
-
-
- // Configure lines and points
- this.lines = [];
- this.glines = [];
- this.markers = [];
- this.data().forEach(function(_, i) {
- var line = d3.svg.line()
- .x(function(d) { return widget.time(d.x); })
- .y(function(d) { return widget.y[i](d.y); })
- .interpolate('linear');
-
- var gline = widget.plotWrap.append('path')
- .attr('class', 'line')
- .style('stroke', function() { return widget.color(i); });
-
- widget.lines.push(line);
- widget.glines.push(gline);
-
- var marker = widget.plotWrap.selectAll('.marker').data(_);
- marker.enter().append('circle')
- .attr('class', 'line-marker')
- .attr('r', 3)
- .style('stroke', function() { return widget.color(i); });
- marker.exit().remove();
-
- widget.markers.push(marker);
- });
-
-
- // Configure scanner
- this.scanner
- .attr('class', 'scanner')
- .attr('y1', 0);
-
-
- // Configure info
- this.infoWrap
- .attr('transform', trans(0, -30));
-
- this.infoDate
- .attr('transform', trans(0, 0));
-
- this.infoMetrics = [];
- this.metrics().forEach(function(d, i) {
- var infoMetric = widget.infoWrap.append('g')
- .attr('class', 'metric-legend')
- .attr('transform', function() { return trans(110 + i * 150, -1); });
-
- infoMetric.append('text')
- .attr('class', 'info-text-small')
- .attr('transform', trans(10, 0));
-
- infoMetric.append('circle')
- .attr('class', 'metric-legend-line')
- .attr('transform', trans(0, -4))
- .attr('r', 4)
- .style('fill', function() { return widget.color(i); });
-
- widget.infoMetrics.push(infoMetric);
- });
-
-
- // Configure events
+ window.SonarWidgets.Timeline.prototype.initEvents = function () {
+ var widget = this;
this.events(this.events().filter(function (event) {
return event.d >= widget.time.domain()[0];
}));
cl = closest(widget.data()[0], mx, function(d) { return widget.time(d.x); });
widget.selectSnapshot(cl);
});
+ };
+
+
+ window.SonarWidgets.Timeline.prototype.render = function () {
+ var widget = this;
+
+ this.svg = this.container.append('svg')
+ .attr('class', 'sonar-d3');
+
+ this.gWrap = this.svg.append('g');
+
+ this.gtimeAxis = this.gWrap.append('g')
+ .attr('class', 'axis x');
+
+ this.plotWrap = this.gWrap.append('g')
+ .attr('class', 'plot');
+
+ this.scanner = this.plotWrap.append('line');
+
+ this.infoWrap = this.gWrap.append('g')
+ .attr('class', 'info');
+
+ this.infoDate = this.infoWrap.append('text')
+ .attr('class', 'info-text info-text-bold');
+
+ this.infoEvent = this.infoWrap.append('text')
+ .attr('class', 'info-text info-text-small');
+
+ this.gWrap
+ .attr('transform', trans(this.margin().left, this.margin().top));
+
+ this.initScalesAndAxis();
+ this.showLimitHistoryMessage();
+
+ // Configure lines and points
+ this.lines = [];
+ this.glines = [];
+ this.markers = [];
+ this.data().forEach(function(_, i) {
+ var line = d3.svg.line()
+ .x(function(d) { return widget.time(d.x); })
+ .y(function(d) { return widget.y[i](d.y); })
+ .interpolate('linear');
+
+ var gline = widget.plotWrap.append('path')
+ .attr('class', 'line')
+ .style('stroke', function() { return widget.color(i); });
+
+ widget.lines.push(line);
+ widget.glines.push(gline);
+
+ var marker = widget.plotWrap.selectAll('.marker').data(_);
+ marker.enter().append('circle')
+ .attr('class', 'line-marker')
+ .attr('r', 3)
+ .style('stroke', function() { return widget.color(i); });
+ marker.exit().remove();
+
+ widget.markers.push(marker);
+ });
+
+
+ // Configure scanner
+ this.scanner
+ .attr('class', 'scanner')
+ .attr('y1', 0);
+ // Configure info
+ this.infoWrap
+ .attr('transform', trans(0, -30));
+
+ this.infoDate
+ .attr('transform', trans(0, 0));
+
+ this.infoMetrics = [];
+ this.metrics().forEach(function(d, i) {
+ var infoMetric = widget.infoWrap.append('g')
+ .attr('class', 'metric-legend')
+ .attr('transform', function() { return trans(110 + i * 150, -1); });
+
+ infoMetric.append('text')
+ .attr('class', 'info-text-small')
+ .attr('transform', trans(10, 0));
+
+ infoMetric.append('circle')
+ .attr('class', 'metric-legend-line')
+ .attr('transform', trans(0, -4))
+ .attr('r', 4)
+ .style('fill', function() { return widget.color(i); });
+
+ widget.infoMetrics.push(infoMetric);
+ });
+
+ this.initEvents();
this.update();
return this;