diff options
Diffstat (limited to 'server/sonar-web/src/main/js/widgets/bubble-chart.js')
-rw-r--r-- | server/sonar-web/src/main/js/widgets/bubble-chart.js | 541 |
1 files changed, 0 insertions, 541 deletions
diff --git a/server/sonar-web/src/main/js/widgets/bubble-chart.js b/server/sonar-web/src/main/js/widgets/bubble-chart.js deleted file mode 100644 index fc166404423..00000000000 --- a/server/sonar-web/src/main/js/widgets/bubble-chart.js +++ /dev/null @@ -1,541 +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, baseUrl:false */ - -window.SonarWidgets = window.SonarWidgets == null ? {} : window.SonarWidgets; - -(function () { - - window.SonarWidgets.BubbleChart = function () { - // Set default values - this._components = []; - this._metrics = []; - this._metricsPriority = []; - this._width = window.SonarWidgets.BubbleChart.defaults.width; - this._height = window.SonarWidgets.BubbleChart.defaults.height; - this._margin = window.SonarWidgets.BubbleChart.defaults.margin; - this._xLog = window.SonarWidgets.BubbleChart.defaults.xLog; - this._yLog = window.SonarWidgets.BubbleChart.defaults.yLog; - this._bubbleColor = window.SonarWidgets.BubbleChart.defaults.bubbleColor; - this._bubbleColorUndefined = window.SonarWidgets.BubbleChart.defaults.bubbleColorUndefined; - this._options = {}; - - // Export global variables - this.metrics = function (_) { - return param.call(this, '_metrics', _); - }; - - this.metricsPriority = function (_) { - return param.call(this, '_metricsPriority', _); - }; - - this.components = function (_) { - return param.call(this, '_components', _); - }; - - this.width = function (_) { - return param.call(this, '_width', _); - }; - - this.height = function (_) { - return param.call(this, '_height', _); - }; - - this.margin = function (_) { - return param.call(this, '_margin', _); - }; - - this.xLog = function (_) { - return param.call(this, '_xLog', _); - }; - - this.yLog = function (_) { - return param.call(this, '_yLog', _); - }; - - this.bubbleColor = function (_) { - return param.call(this, '_bubbleColor', _); - }; - - this.bubbleColorUndefined = function (_) { - return param.call(this, '_bubbleColorUndefined', _); - }; - - this.options = function (_) { - return param.call(this, '_options', _); - }; - }; - - - window.SonarWidgets.BubbleChart.prototype.hasValidData = function () { - var widget = this, - noInvalidEntry = true, - atLeastOneValueOnX = false, - atLeastOneValueOnY = false; - this.components().forEach(function(component) { - noInvalidEntry = noInvalidEntry && - !!component.measures[widget.metricsPriority()[0]] && - !!component.measures[widget.metricsPriority()[1]]; - atLeastOneValueOnX = atLeastOneValueOnX || - (component.measures[widget.metricsPriority()[0]] || {}).fval !== '-'; - atLeastOneValueOnY = atLeastOneValueOnY || - (component.measures[widget.metricsPriority()[1]] || {}).fval !== '-'; - }); - return !!noInvalidEntry && !!atLeastOneValueOnX && !!atLeastOneValueOnY; - }; - - - window.SonarWidgets.BubbleChart.prototype.init = function (container) { - this.width(container.property('offsetWidth')); - - this.svg = container.append('svg') - .attr('class', 'sonar-d3'); - this.gWrap = this.svg.append('g'); - - this.gxAxis = this.gWrap.append('g'); - this.gyAxis = this.gWrap.append('g'); - - this.gGrid = this.gWrap.append('g'); - this.gxGrid = this.gGrid.append('g'); - this.gyGrid = this.gGrid.append('g'); - - this.plotWrap = this.gWrap.append('g'); - - this.infoWrap = this.gWrap.append('g'); - this.infoDate = this.infoWrap.append('text'); - - this.gWrap - .attr('transform', trans(this.margin().left, this.margin().top)); - }; - - - window.SonarWidgets.BubbleChart.prototype.initMetrics = function () { - var widget = this; - - this.xMetric = this.metricsPriority()[0]; - this.getXMetric = function(d) { - return d.measures[widget.xMetric].val; - }; - - this.yMetric = this.metricsPriority()[1]; - this.getYMetric = function(d) { - return d.measures[widget.yMetric].val; - }; - - this.sizeMetric = this.metricsPriority()[2]; - this.getSizeMetric = function(d) { - return !!d.measures[widget.sizeMetric] ? d.measures[widget.sizeMetric].val : 0; - }; - }; - - - window.SonarWidgets.BubbleChart.prototype.initScales = function () { - var widget = this; - this - .xLog(this.options().xLog) - .yLog(this.options().yLog); - - this.x = this.xLog() ? d3.scale.log() : d3.scale.linear(); - this.y = this.yLog() ? d3.scale.log() : d3.scale.linear(); - this.size = d3.scale.linear(); - - this.x.range([0, this.availableWidth]); - this.y.range([this.availableHeight, 0]); - this.size.range([5, 45]); - - if (this.components().length > 1) { - this.x.domain(d3.extent(this.components(), function (d) { - return widget.getXMetric(d); - })); - this.y.domain(d3.extent(this.components(), function (d) { - return widget.getYMetric(d); - })); - this.size.domain(d3.extent(this.components(), function (d) { - return widget.getSizeMetric(d); - })); - } else { - var singleComponent = this.components()[0], - xm = this.getXMetric(singleComponent), - ym = this.getYMetric(singleComponent), - sm = this.getSizeMetric(singleComponent); - this.x.domain([xm * 0.8, xm * 1.2]); - this.y.domain([ym * 0.8, ym * 1.2]); - this.size.domain([sm * 0.8, sm * 1.2]); - } - }; - - - window.SonarWidgets.BubbleChart.prototype.initBubbles = function () { - var widget = this; - - // Create bubbles - this.items = this.plotWrap.selectAll('.item') - .data(this.components()); - - - // Render bubbles - this.items.enter().append('g') - .attr('class', 'item') - .attr('name', function (d) { - return d.longName; - }) - .style('cursor', 'pointer') - .append('circle') - .attr('r', function (d) { - return widget.size(widget.getSizeMetric(d)); - }) - .style('fill', function () { - return widget.bubbleColor(); - }) - .style('fill-opacity', 0.2) - .style('stroke', function () { - return widget.bubbleColor(); - }) - .style('transition', 'all 0.2s ease') - - .attr('title', function (d) { - var xMetricName = widget.metrics()[widget.xMetric].name, - yMetricName = widget.metrics()[widget.yMetric].name, - sizeMetricName = widget.metrics()[widget.sizeMetric].name, - - xMetricValue = d.measures[widget.xMetric].fval, - yMetricValue = d.measures[widget.yMetric].fval, - sizeMetricValue = d.measures[widget.sizeMetric].fval; - - return '<div class="text-left">' + - collapsedDirFromPath(d.longName) + '<br>' + - fileFromPath(d.longName) + '<br>' + '<br>' + - xMetricName + ': ' + xMetricValue + '<br>' + - yMetricName + ': ' + yMetricValue + '<br>' + - sizeMetricName + ': ' + sizeMetricValue + - '</div>'; - }) - .attr('data-placement', 'bottom') - .attr('data-toggle', 'tooltip'); - - this.items.exit().remove(); - - this.items.sort(function (a, b) { - return widget.getSizeMetric(b) - widget.getSizeMetric(a); - }); - }; - - - window.SonarWidgets.BubbleChart.prototype.initBubbleEvents = function () { - var widget = this; - this.items - .on('click', function (d) { - window.location = widget.options().baseUrl + '?id=' + encodeURIComponent(d.key); - }) - .on('mouseenter', function () { - d3.select(this).select('circle') - .style('fill-opacity', 0.8); - }) - .on('mouseleave', function () { - d3.select(this).select('circle') - .style('fill-opacity', 0.2); - }); - }; - - - window.SonarWidgets.BubbleChart.prototype.initAxes = function () { - // X - this.xAxis = d3.svg.axis() - .scale(this.x) - .orient('bottom'); - - this.gxAxisLabel = this.gxAxis.append('text') - .text(this.metrics()[this.xMetric].name) - .style('font-weight', 'bold') - .style('text-anchor', 'middle'); - - - // Y - this.yAxis = d3.svg.axis() - .scale(this.y) - .orient('left'); - - this.gyAxis.attr('transform', trans(60 - this.margin().left, 0)); - - this.gyAxisLabel = this.gyAxis.append('text') - .text(this.metrics()[this.yMetric].name) - .style('font-weight', 'bold') - .style('text-anchor', 'middle'); - }; - - - window.SonarWidgets.BubbleChart.prototype.initGrid = function () { - this.gxGridLines = this.gxGrid.selectAll('line').data(this.x.ticks()).enter() - .append('line'); - - this.gyGridLines = this.gyGrid.selectAll('line').data(this.y.ticks()).enter() - .append('line'); - - this.gGrid.selectAll('line') - .style('stroke', '#000') - .style('stroke-opacity', 0.25); - }; - - - window.SonarWidgets.BubbleChart.prototype.render = function (container) { - var containerS = container; - - container = d3.select(container); - - if (!this.hasValidData()) { - container.text(this.options().noMainMetric); - return; - } - - this.init(container); - this.initMetrics(); - this.initScales(); - this.initBubbles(); - this.initBubbleEvents(); - this.initAxes(); - this.initGrid(); - this.update(containerS); - - jQuery('[data-toggle="tooltip"]').tooltip({ container: 'body', html: true }); - - return this; - }; - - - window.SonarWidgets.BubbleChart.prototype.adjustScalesAfterUpdate = function () { - var widget = this; - // X - var minX = d3.min(this.components(), function (d) { - return widget.x(widget.getXMetric(d)) - widget.size(widget.getSizeMetric(d)); - }), - maxX = d3.max(this.components(), function (d) { - return widget.x(widget.getXMetric(d)) + widget.size(widget.getSizeMetric(d)); - }), - dMinX = minX < 0 ? this.x.range()[0] - minX : this.x.range()[0], - dMaxX = maxX > this.x.range()[1] ? maxX - this.x.range()[1] : 0; - this.x.range([dMinX, this.availableWidth - dMaxX]); - - // Y - var minY = d3.min(this.components(), function (d) { - return widget.y(widget.getYMetric(d)) - widget.size(widget.getSizeMetric(d)); - }), - maxY = d3.max(this.components(), function (d) { - return widget.y(widget.getYMetric(d)) + widget.size(widget.getSizeMetric(d)); - }), - dMinY = minY < 0 ? this.y.range()[1] - minY: this.y.range()[1], - dMaxY = maxY > this.y.range()[0] ? maxY - this.y.range()[0] : 0; - this.y.range([this.availableHeight - dMaxY, dMinY]); - - - // Format improvement for log scales - // X - if (this.xLog()) { - this.xAxis.tickFormat(function (d) { - var ticksCount = widget.availableWidth / 50; - return widget.x.tickFormat(ticksCount, d3.format(',d'))(d); - }); - } - - // Y - if (this.yLog()) { - this.yAxis.tickFormat(function (d) { - var ticksCount = widget.availableHeight / 30; - return widget.y.tickFormat(ticksCount, d3.format(',d'))(d); - }); - } - - // Make scale's domains nice - this.x.nice(); - this.y.nice(); - }; - - - window.SonarWidgets.BubbleChart.prototype.updateScales = function () { - var widget = this; - this.x.range([0, this.availableWidth]); - this.y.range([this.availableHeight, 0]); - - if (this.components().length > 1) { - this.x.domain(d3.extent(this.components(), function (d) { - return widget.getXMetric(d); - })); - this.y.domain(d3.extent(this.components(), function (d) { - return widget.getYMetric(d); - })); - } else { - var singleComponent = this.components()[0], - xm = this.getXMetric(singleComponent), - ym = this.getYMetric(singleComponent), - sm = this.getSizeMetric(singleComponent); - this.x.domain([xm * 0.8, xm * 1.2]); - this.y.domain([ym * 0.8, ym * 1.2]); - this.size.domain([sm * 0.8, sm * 1.2]); - } - - if (this.x.domain()[0] === 0 && this.x.domain()[1] === 0) { - this.x.domain([0, 1]); - } - if (this.y.domain()[0] === 0 && this.y.domain()[1] === 0) { - this.y.domain([0, 1]); - } - - // Avoid zero values when using log scale - if (this.xLog) { - var xDomain = this.x.domain(); - this.x - .domain([xDomain[0] > 0 ? xDomain[0] : 0.1, xDomain[1]]) - .clamp(true); - } - - if (this.yLog) { - var yDomain = this.y.domain(); - this.y - .domain([yDomain[0] > 0 ? yDomain[0] : 0.1, yDomain[1]]) - .clamp(true); - } - }; - - - window.SonarWidgets.BubbleChart.prototype.updateBubbles = function () { - var widget = this; - this.items - .transition() - .attr('transform', function (d) { - return trans(widget.x(widget.getXMetric(d)), widget.y(widget.getYMetric(d))); - }); - }; - - - window.SonarWidgets.BubbleChart.prototype.updateAxes = function () { - // X - this.gxAxis.attr('transform', trans(0, this.availableHeight + this.margin().bottom - 40)); - - this.gxAxis.transition().call(this.xAxis); - - this.gxAxis.selectAll('path') - .style('fill', 'none') - .style('stroke', '#444'); - - this.gxAxis.selectAll('text') - .style('fill', '#444'); - - this.gxAxisLabel - .attr('transform', trans(this.availableWidth / 2, 35)); - - // Y - this.gyAxis.transition().call(this.yAxis); - - this.gyAxis.selectAll('path') - .style('fill', 'none') - .style('stroke', '#444'); - - this.gyAxis.selectAll('text') - .style('fill', '#444'); - - this.gyAxisLabel - .attr('transform', trans(-45, this.availableHeight / 2) + ' rotate(-90)'); - }; - - - window.SonarWidgets.BubbleChart.prototype.updateGrid = function () { - var widget = this; - this.gxGridLines - .transition() - .attr({ - x1: function (d) { - return widget.x(d); - }, - x2: function (d) { - return widget.x(d); - }, - y1: widget.y.range()[0], - y2: widget.y.range()[1] - }); - - this.gyGridLines - .transition() - .attr({ - x1: widget.x.range()[0], - x2: widget.x.range()[1], - y1: function (d) { - return widget.y(d); - }, - y2: function (d) { - return widget.y(d); - } - }); - }; - - - window.SonarWidgets.BubbleChart.prototype.update = function (container) { - container = d3.select(container); - - var width = container.property('offsetWidth'); - - this.width(width > 100 ? width : 100); - - // Update svg canvas - this.svg - .attr('width', this.width()) - .attr('height', this.height()); - - // Update available size - this.availableWidth = this.width() - this.margin().left - this.margin().right; - this.availableHeight = this.height() - this.margin().top - this.margin().bottom; - - this.updateScales(); - this.adjustScalesAfterUpdate(); - this.updateBubbles(); - this.updateAxes(); - this.updateGrid(); - }; - - - - window.SonarWidgets.BubbleChart.defaults = { - width: 350, - height: 150, - margin: { top: 10, right: 10, bottom: 50, left: 70 }, - xLog: false, - yLog: false, - bubbleColor: '#4b9fd5', - bubbleColorUndefined: '#b3b3b3' - }; - - - - // 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 + ')'; - } - -})(); |