diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -398,6 +398,7 @@ 'rsrc/js/application/herald/PathTypeahead.js' => 'ad486db3', 'rsrc/js/application/herald/herald-rule-editor.js' => '0922e81d', 'rsrc/js/application/maniphest/behavior-batch-selector.js' => '139ef688', + 'rsrc/js/application/maniphest/behavior-line-chart-legacy.js' => 'faf3ab6b', 'rsrc/js/application/maniphest/behavior-line-chart.js' => 'ad258e28', 'rsrc/js/application/maniphest/behavior-list-edit.js' => 'c687e867', 'rsrc/js/application/owners/OwnersPathEditor.js' => '2a8b62d9', @@ -627,6 +628,7 @@ 'javelin-behavior-launch-icon-composer' => 'a17b84f1', 'javelin-behavior-lightbox-attachments' => 'c7e748bf', 'javelin-behavior-line-chart' => 'ad258e28', + 'javelin-behavior-line-chart-legacy' => 'faf3ab6b', 'javelin-behavior-linked-container' => '74446546', 'javelin-behavior-maniphest-batch-selector' => '139ef688', 'javelin-behavior-maniphest-list-editor' => 'c687e867', @@ -2180,6 +2182,12 @@ 'fa74cc35' => array( 'phui-oi-list-view-css', ), + 'faf3ab6b' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-vector', + 'phui-chart-css', + ), 'fcb0c07d' => array( 'phui-chart-css', 'd3', diff --git a/src/applications/maniphest/controller/ManiphestReportController.php b/src/applications/maniphest/controller/ManiphestReportController.php --- a/src/applications/maniphest/controller/ManiphestReportController.php +++ b/src/applications/maniphest/controller/ManiphestReportController.php @@ -382,7 +382,7 @@ require_celerity_resource('d3'); require_celerity_resource('phui-chart-css'); - Javelin::initBehavior('line-chart', array( + Javelin::initBehavior('line-chart-legacy', array( 'hardpoint' => $id, 'x' => array( $burn_x, diff --git a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php --- a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php +++ b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php @@ -436,7 +436,7 @@ // We can tell the client what it should check out by making "HEAD" // point somewhere. However: // - // (1) If we don't set "receive.denyDelteCurrent" to "ignore" and a user + // (1) If we don't set "receive.denyDeleteCurrent" to "ignore" and a user // tries to delete the default branch, Git raises an error and refuses. // We want to allow this; we already have sufficient protections around // dangerous changes and do not need to special case the default branch. diff --git a/webroot/rsrc/js/application/maniphest/behavior-line-chart-legacy.js b/webroot/rsrc/js/application/maniphest/behavior-line-chart-legacy.js new file mode 100644 --- /dev/null +++ b/webroot/rsrc/js/application/maniphest/behavior-line-chart-legacy.js @@ -0,0 +1,126 @@ +/** + * @provides javelin-behavior-line-chart-legacy + * @requires javelin-behavior + * javelin-dom + * javelin-vector + * phui-chart-css + */ + +JX.behavior('line-chart-legacy', function(config) { + + function fn(n) { + return n + '(' + JX.$A(arguments).slice(1).join(', ') + ')'; + } + + var h = JX.$(config.hardpoint); + var d = JX.Vector.getDim(h); + + var padding = { + top: 24, + left: 48, + bottom: 48, + right: 32 + }; + + var size = { + frameWidth: d.x, + frameHeight: d.y, + }; + + size.width = size.frameWidth - padding.left - padding.right; + size.height = size.frameHeight - padding.top - padding.bottom; + + var x = d3.time.scale() + .range([0, size.width]); + + var y = d3.scale.linear() + .range([size.height, 0]); + + var xAxis = d3.svg.axis() + .scale(x) + .orient('bottom'); + + var yAxis = d3.svg.axis() + .scale(y) + .orient('left'); + + var svg = d3.select('#' + config.hardpoint).append('svg') + .attr('width', size.frameWidth) + .attr('height', size.frameHeight) + .attr('class', 'chart'); + + var g = svg.append('g') + .attr('transform', fn('translate', padding.left, padding.top)); + + g.append('rect') + .attr('class', 'inner') + .attr('width', size.width) + .attr('height', size.height); + + var line = d3.svg.line() + .x(function(d) { return x(d.date); }) + .y(function(d) { return y(d.count); }); + + var data = []; + for (var ii = 0; ii < config.x[0].length; ii++) { + data.push( + { + date: new Date(config.x[0][ii] * 1000), + count: +config.y[0][ii] + }); + } + + x.domain(d3.extent(data, function(d) { return d.date; })); + + var yex = d3.extent(data, function(d) { return d.count; }); + yex[0] = 0; + yex[1] = yex[1] * 1.05; + y.domain(yex); + + g.append('path') + .datum(data) + .attr('class', 'line') + .attr('d', line); + + g.append('g') + .attr('class', 'x axis') + .attr('transform', fn('translate', 0, size.height)) + .call(xAxis); + + g.append('g') + .attr('class', 'y axis') + .attr('transform', fn('translate', 0, 0)) + .call(yAxis); + + var div = d3.select('body') + .append('div') + .attr('class', 'chart-tooltip') + .style('opacity', 0); + + g.selectAll('dot') + .data(data) + .enter() + .append('circle') + .attr('class', 'point') + .attr('r', 3) + .attr('cx', function(d) { return x(d.date); }) + .attr('cy', function(d) { return y(d.count); }) + .on('mouseover', function(d) { + var d_y = d.date.getFullYear(); + + // NOTE: Javascript months are zero-based. See PHI1017. + var d_m = d.date.getMonth() + 1; + + var d_d = d.date.getDate(); + + div + .html(d_y + '-' + d_m + '-' + d_d + ': ' + d.count) + .style('opacity', 0.9) + .style('left', (d3.event.pageX - 60) + 'px') + .style('top', (d3.event.pageY - 38) + 'px'); + }) + .on('mouseout', function() { + div.style('opacity', 0); + }); + +});