diff options
Diffstat (limited to 'server/sonar-web/src/main/js/widgets/timeline.js')
-rw-r--r-- | server/sonar-web/src/main/js/widgets/timeline.js | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/server/sonar-web/src/main/js/widgets/timeline.js b/server/sonar-web/src/main/js/widgets/timeline.js deleted file mode 100644 index 5b871e5994e..00000000000 --- a/server/sonar-web/src/main/js/widgets/timeline.js +++ /dev/null @@ -1,417 +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. - */ -/*global d3:false*/ - -window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets; - -(function () { - - window.SonarWidgets.Timeline = function (container) { - - // Ensure container is html id - if (container.indexOf('#') !== 0) { - container = '#' + container; - } - - this.container = d3.select(container); - - // Set default values - this._data = []; - this._metrics = []; - this._snapshots = []; - this._events = []; - this._width = window.SonarWidgets.Timeline.defaults.width; - this._height = window.SonarWidgets.Timeline.defaults.height; - this._margin = window.SonarWidgets.Timeline.defaults.margin; - - // Export global variables - this.data = function (_) { - return param.call(this, '_data', _); - }; - - this.metrics = function (_) { - return param.call(this, '_metrics', _); - }; - - this.snapshots = function (_) { - return param.call(this, '_snapshots', _); - }; - - this.events = function (_) { - return param.call(this, '_events', _); - }; - - this.width = function (_) { - return param.call(this, '_width', _); - }; - - this.height = function (_) { - return param.call(this, '_height', _); - }; - - this.margin = function (_) { - return param.call(this, '_margin', _); - }; - - }; - - - window.SonarWidgets.Timeline.prototype.initScalesAndAxis = function () { - // Configure scales - var timeDomain = this.data() - .map(function(_) { - return d3.extent(_, function(d) { - return d.x; - }); - }) - .reduce(function(p, c) { - return p.concat(c); - }, []); - - this.time = d3.time.scale().domain(d3.extent(timeDomain)); - - this.y = this.data().map(function(_) { - return d3.scale.linear() - .domain(d3.extent(_, function(d) { return d.y; })); - }); - - this.color = d3.scale.category10(); - - // Configure the axis - this.timeAxis = d3.svg.axis() - .scale(this.time) - .orient('bottom') - .ticks(5); - }; - - - window.SonarWidgets.Timeline.prototype.initEvents = function () { - var widget = this; - this.events(this.events().filter(function (event) { - return event.d >= widget.time.domain()[0]; - })); - - this.gevents = this.gWrap.append('g') - .attr('class', 'axis events') - .selectAll('.event-tick') - .data(this.events()); - - this.gevents.enter().append('line') - .attr('class', 'event-tick') - .attr('y2', -8); - - this.gevents.exit().remove(); - - - this.selectSnapshot = function(cl) { - var sx = widget.time(widget.data()[0][cl].x); - - widget.markers.forEach(function(marker) { - marker.style('opacity', 0); - d3.select(marker[0][cl]).style('opacity', 1); - }); - - widget.scanner - .attr('x1', sx) - .attr('x2', sx); - - widget.infoDate - .text(moment(widget.data()[0][cl].x).format('LL')); - - var metricsLines = widget.data().map(function(d, i) { - return widget.metrics()[i] + ': ' + d[cl].yl; - }); - - metricsLines.forEach(function(d, i) { - widget.infoMetrics[i].select('text').text(d); - }); - - widget.gevents.attr('y2', -8); - widget.infoEvent.text(''); - widget.events().forEach(function(d, i) { - if (d.d - widget.data()[0][cl].x === 0) { - d3.select(widget.gevents[0][i]).attr('y2', -12); - - widget.infoEvent - .text(widget.events()[i].l - .map(function(e) { return e.n; }) - .join(', ')); - } - }); - }; - - - // Set event listeners - this.svg.on('mousemove', function() { - var mx = d3.mouse(widget.plotWrap.node())[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; - }; - - - window.SonarWidgets.Timeline.prototype.showLimitHistoryMessage = function () { - var minEvent = d3.min(this.events(), function (d) { - return d.d; - }), - minData = this.time.domain()[0]; - if (minEvent < minData) { - var maxResultsReachedLabel = this.container.append('div').text(this.limitedHistoricalData); - maxResultsReachedLabel.classed('max-results-reached-message', true); - } - }; - - - window.SonarWidgets.Timeline.prototype.update = function() { - var widget = this, - width = this.container.property('offsetWidth'); - - this.width(width > 100 ? width : 100); - - - // Update svg canvas - this.svg - .attr('width', this.width()) - .attr('height', this.height()); - - - // Update available width - this.availableWidth = this.width() - this.margin().left - this.margin().right; - - - // Update metric lines - var metricY = -1; - this.infoMetrics.forEach(function(metric, i) { - var x = 120 + i * 170, - x2 = x + 170; - - if (x2 > widget.availableWidth) { - metricY += 18; - x = 120; - } - - metric - .transition() - .attr('transform', function() { return trans(x, metricY); }); - }); - - if (metricY > -1) { - metricY += 17; - } - - // Update available width - this.availableHeight = this.height() - this.margin().top - this.margin().bottom - metricY; - - - // Update scales - this.time - .range([0, this.availableWidth]); - - this.y.forEach(function(scale) { - scale.range([widget.availableHeight, 0]); - }); - - - // Update plot - this.plotWrap - .transition() - .attr('transform', trans(0, metricY)); - - - // Update the axis - this.gtimeAxis.attr('transform', trans(0, this.availableHeight + this.margin().bottom - 30 + metricY)); - - this.gtimeAxis.transition().call(this.timeAxis); - - - // Update lines and points - this.data().forEach(function(_, i) { - widget.glines[i] - .transition() - .attr('d', widget.lines[i](_)); - - widget.markers[i] - .data(_) - .transition() - .attr('transform', function(d) { return trans(widget.time(d.x), widget.y[i](d.y)); }); - }); - - - // Update scanner - this.scanner - .attr('y2', this.availableHeight + 10); - - - // Update events - this.infoEvent - .attr('transform', trans(0, metricY > -1 ? metricY : 18)); - - this.gevents - .transition() - .attr('transform', function(d) { return trans(widget.time(d.d), widget.availableHeight + 10 + metricY); }); - - - // Select latest values if this it the first update - if (!this.firstUpdate) { - this.selectSnapshot(widget.data()[0].length - 1); - - this.firstUpdate = true; - } - - }; - - - - window.SonarWidgets.Timeline.defaults = { - width: 350, - height: 150, - margin: { top: 50, right: 10, bottom: 40, left: 10 } - }; - - - - // Some helper functions - - // Gets or sets parameter - function param(name, value) { - if (value == null) { - return this[name]; - } else { - this[name] = value; - return this; - } - } - - // Helper for create the translate(x, y) string - function trans(left, top) { - return 'translate(' + left + ', ' + top + ')'; - } - - // Helper for find the closest number in array - function closest(array, number, getter) { - var cl = null; - array.forEach(function(value, i) { - if (cl == null || - Math.abs(getter(value) - number) < Math.abs(getter(array[cl]) - number)) { - cl = i; - } - }); - return cl; - } - -})(); |