mirror of
https://github.com/klaussilveira/gitlist.git
synced 2025-11-17 19:20:56 +01:00
Changed the entire drawing direction of the graph, now more git-hub like, ie. from right to left
This commit is contained in:
@@ -14,15 +14,21 @@ class NetworkController implements ControllerProviderInterface
|
|||||||
{
|
{
|
||||||
$route = $app['controllers_factory'];
|
$route = $app['controllers_factory'];
|
||||||
|
|
||||||
$route->get('{repo}/network/{branch}/{page}.json', function($repo, $branch, $page) use ($app) {
|
$route->get('{repo}/network/{commitishPath}/{page}.json', function($repo, $commitishPath, $page) use ($app) {
|
||||||
/** @var $repository Repository */
|
/** @var $repository Repository */
|
||||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||||
if ($branch === null) {
|
|
||||||
$branch = $repository->getHead();
|
if ($commitishPath === null) {
|
||||||
|
$commitishPath = $repository->getHead();
|
||||||
}
|
}
|
||||||
|
|
||||||
$pager = $app['util.view']->getPager($page, $repository->getTotalCommits($branch));
|
list($branch, $file) = $app['util.routing']
|
||||||
$commits = $repository->getPaginatedCommits($branch, $pager['current']);
|
->parseCommitishPathParam($commitishPath, $repo);
|
||||||
|
|
||||||
|
list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);
|
||||||
|
|
||||||
|
$pager = $app['util.view']->getPager($page, $repository->getTotalCommits($commitishPath));
|
||||||
|
$commits = $repository->getPaginatedCommits($commitishPath, $pager['current']);
|
||||||
|
|
||||||
// format the commits for the json reponse
|
// format the commits for the json reponse
|
||||||
$jsonFormattedCommits = array();
|
$jsonFormattedCommits = array();
|
||||||
@@ -43,39 +49,46 @@ class NetworkController implements ControllerProviderInterface
|
|||||||
$nextPageUrl = null;
|
$nextPageUrl = null;
|
||||||
if ( $pager['last'] !== $pager['current'] ) {
|
if ( $pager['last'] !== $pager['current'] ) {
|
||||||
$nextPageUrl = $app['url_generator']->generate('networkData', array( 'repo' => $repo,
|
$nextPageUrl = $app['url_generator']->generate('networkData', array( 'repo' => $repo,
|
||||||
'branch' => $branch,
|
'commitishPath' => $commitishPath,
|
||||||
'page' => $pager['next']));
|
'page' => $pager['next']));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $app->json(array(
|
return $app->json(array(
|
||||||
'repo' => $repo,
|
'repo' => $repo,
|
||||||
'branch' => $branch,
|
'commitishPath' => $commitishPath,
|
||||||
'nextPage' => $nextPageUrl,
|
'nextPage' => $nextPageUrl,
|
||||||
'start' => $commits[0]->getHash(),
|
'start' => $commits[0]->getHash(),
|
||||||
'commits' => $jsonFormattedCommits
|
'commits' => $jsonFormattedCommits
|
||||||
), 200);
|
), 200);
|
||||||
|
|
||||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||||
->assert('branch', $app['util.routing']->getBranchRegex())
|
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
|
||||||
->value('branch', null)
|
->value('commitishPath', null)
|
||||||
->assert('page', '\d+')
|
->assert('page', '\d+')
|
||||||
->value('page', '0')
|
->value('page', '0')
|
||||||
->bind('networkData');
|
->bind('networkData');
|
||||||
|
|
||||||
|
|
||||||
$route->get('{repo}/network/{branch}', function($repo, $branch) use ($app) {
|
$route->get('{repo}/network/{commitishPath}', function($repo, $commitishPath) use ($app) {
|
||||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||||
if ($branch === null) {
|
|
||||||
$branch = $repository->getHead();
|
if ($commitishPath === null) {
|
||||||
|
$commitishPath = $repository->getHead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list($branch, $file) = $app['util.routing']
|
||||||
|
->parseCommitishPathParam($commitishPath, $repo);
|
||||||
|
|
||||||
|
list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);
|
||||||
|
|
||||||
return $app['twig']->render('network.twig', array(
|
return $app['twig']->render('network.twig', array(
|
||||||
'repo' => $repo,
|
'repo' => $repo,
|
||||||
'branch' => $branch,
|
'branch' => $branch,
|
||||||
|
'commitishPath' => $commitishPath,
|
||||||
));
|
));
|
||||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||||
->assert('branch', $app['util.routing']->getBranchRegex())
|
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
|
||||||
->value('branch', null)
|
->value('commitishPath', null)
|
||||||
->bind('network');
|
->bind('network');
|
||||||
|
|
||||||
return $route;
|
return $route;
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
{% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Network', path:''}]} %}
|
{% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Network', path:''}]} %}
|
||||||
<div class="network-view">
|
<div class="network-view">
|
||||||
<div class="network-header">
|
<div class="network-header">
|
||||||
<div class="meta">Network Graph of {{ repo }} / {{ branch }}</div>
|
<div class="meta">Network Graph of {{ repo }} / {{ commitishPath }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table-striped network-graph" data-source="{{ path('networkData', {repo: repo, branch: branch}) }}">
|
<div class="network-graph" data-source="{{ path('networkData', {repo: repo, commitishPath: commitishPath}) }}">
|
||||||
{#<div class="network-graph" data-source="/dummynetwork.json">#}
|
{#<div class="network-graph" data-source="/dummynetwork.json">#}
|
||||||
|
|
||||||
</table>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -8,7 +8,7 @@
|
|||||||
$( function() {
|
$( function() {
|
||||||
|
|
||||||
// initialise network graph only when there is one network graph container on the page
|
// initialise network graph only when there is one network graph container on the page
|
||||||
if( $('table.network-graph').length !== 1 ) {
|
if( $('div.network-graph').length !== 1 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,18 +16,22 @@ $( function() {
|
|||||||
|
|
||||||
cfg = {
|
cfg = {
|
||||||
laneColors: ['#ff0000', '#0000FF', '#00FFFF', '#00FF00', '#FFFF00', '#ff00ff'],
|
laneColors: ['#ff0000', '#0000FF', '#00FFFF', '#00FF00', '#FFFF00', '#ff00ff'],
|
||||||
laneWidth: 10,
|
laneHeight: 20,
|
||||||
dotRadius: 3,
|
columnWidth: 42,
|
||||||
rowHeight: 42 // thanks for making this divisable by two
|
dotRadius: 3
|
||||||
},
|
},
|
||||||
|
|
||||||
// the table element into which we will render our graph
|
// the table element into which we will render our graph
|
||||||
commitsTable = $('table.network-graph').first(),
|
commitsGraph = $('div.network-graph').first(),
|
||||||
nextPage = commitsTable.data('source'),
|
nextPage = commitsGraph.data('source'),
|
||||||
|
|
||||||
refreshButton = $('<button class="btn btn-small"></button>').insertAfter(commitsTable.parent('div'))
|
refreshButton = $('<button class="btn btn-small"></button>').insertAfter(commitsGraph.parent('div')),
|
||||||
|
paper = Raphael( commitsGraph[0], commitsGraph.width(), commitsGraph.height()),
|
||||||
|
usedColumns = 0
|
||||||
;
|
;
|
||||||
|
|
||||||
|
window.pap = paper;
|
||||||
|
|
||||||
function fetchCommitData( url ) {
|
function fetchCommitData( url ) {
|
||||||
console.log('Starting to fetch commit data from ', url);
|
console.log('Starting to fetch commit data from ', url);
|
||||||
setRefreshButtonState(true);
|
setRefreshButtonState(true);
|
||||||
@@ -49,14 +53,10 @@ $( function() {
|
|||||||
refreshButton.html(newInner);
|
refreshButton.html(newInner);
|
||||||
};
|
};
|
||||||
|
|
||||||
var refreshButtonClickHandler = function () {
|
function refreshButtonClickHandler() {
|
||||||
fetchCommitData(nextPage);
|
fetchCommitData(nextPage);
|
||||||
};
|
};
|
||||||
|
|
||||||
refreshButton.click(refreshButtonClickHandler);
|
|
||||||
|
|
||||||
// load initial data
|
|
||||||
fetchCommitData( nextPage );
|
|
||||||
|
|
||||||
function handleNetworkDataLoaded( data ) {
|
function handleNetworkDataLoaded( data ) {
|
||||||
setRefreshButtonState(false);
|
setRefreshButtonState(false);
|
||||||
@@ -126,18 +126,15 @@ $( function() {
|
|||||||
|
|
||||||
// remove this item from parentsBeingWaitedFor
|
// remove this item from parentsBeingWaitedFor
|
||||||
delete parentsBeingWaitedFor[commit.hash];
|
delete parentsBeingWaitedFor[commit.hash];
|
||||||
console.log('taking commit out', commit.hash, parentsBeingWaitedFor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.isFork = ( commit.children.length > 1 );
|
commit.isFork = ( commit.children.length > 1 );
|
||||||
commit.isMerge = ( commit.parentsHash.length > 1 );
|
commit.isMerge = ( commit.parentsHash.length > 1 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// after a fork, the occupied lanes must be cleaned up. The children used some lanes we no longer occupy
|
// after a fork, the occupied lanes must be cleaned up. The children used some lanes we no longer occupy
|
||||||
if (commit.isFork === true ) {
|
if (commit.isFork === true ) {
|
||||||
$.each( commit.children, function( key, thisChild ) {
|
$.each( commit.children, function( key, thisChild ) {
|
||||||
console.log('Freeing lane ', thisChild.lane.number);
|
// free this lane
|
||||||
occupiedLanes[thisChild.lane.number] = false;
|
occupiedLanes[thisChild.lane.number] = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -162,7 +159,6 @@ $( function() {
|
|||||||
commit.lane = getLaneInfo( laneNumber );
|
commit.lane = getLaneInfo( laneNumber );
|
||||||
|
|
||||||
// now the lane we chose must be marked occupied again.
|
// now the lane we chose must be marked occupied again.
|
||||||
console.log('Occupying lane ', commit.lane.number);
|
|
||||||
occupiedLanes[commit.lane.number] = true;
|
occupiedLanes[commit.lane.number] = true;
|
||||||
maxLanes = Math.max( occupiedLanes.length, maxLanes);
|
maxLanes = Math.max( occupiedLanes.length, maxLanes);
|
||||||
|
|
||||||
@@ -187,6 +183,16 @@ $( function() {
|
|||||||
|
|
||||||
var lastRenderedDate = new Date(0);
|
var lastRenderedDate = new Date(0);
|
||||||
function renderCommits( commits ) {
|
function renderCommits( commits ) {
|
||||||
|
var neededWidth = ((usedColumns + Object.keys(commits).length) * cfg.columnWidth);
|
||||||
|
if ( neededWidth > paper.width ) {
|
||||||
|
console.log(neededWidth);
|
||||||
|
extendPaper( neededWidth, paper.height );
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log( paper.width, neededWidth);
|
||||||
|
}
|
||||||
|
|
||||||
$.each( commits, function ( index, commit) {
|
$.each( commits, function ( index, commit) {
|
||||||
if( lastRenderedDate.getYear() !== commit.date.getYear()
|
if( lastRenderedDate.getYear() !== commit.date.getYear()
|
||||||
|| lastRenderedDate.getMonth() !== commit.date.getMonth()
|
|| lastRenderedDate.getMonth() !== commit.date.getMonth()
|
||||||
@@ -198,108 +204,115 @@ $( function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extendPaper( newWidth, newHeight ) {
|
||||||
|
var deltaX = newWidth - paper.width;
|
||||||
|
|
||||||
|
paper.setSize( newWidth, newHeight );
|
||||||
|
// fixup parent's scroll position
|
||||||
|
paper.canvas.parentNode.scrollLeft = paper.canvas.parentNode.scrollLeft + deltaX;
|
||||||
|
|
||||||
|
// now fixup the x position
|
||||||
|
|
||||||
|
paper.forEach( function( el ) {
|
||||||
|
|
||||||
|
if( el.type === "circle" ) {
|
||||||
|
el.attr('cx', el.attr('cx') + deltaX);
|
||||||
|
} else if ( el.type === "path") {
|
||||||
|
var newXTranslation = el.data('currentXTranslation') || 0;
|
||||||
|
newXTranslation += deltaX;
|
||||||
|
el.transform( 't' + newXTranslation + ' 0' );
|
||||||
|
el.data('currentXTranslation', newXTranslation);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function renderCommit( commit ) {
|
function renderCommit( commit ) {
|
||||||
|
// find the column this dot is drawn on
|
||||||
var tableRow = $('<tr></tr>');
|
usedColumns++;
|
||||||
|
commit.column = usedColumns;
|
||||||
// the required canvas width is at least the lane center plus the radius - but that will be added later
|
|
||||||
|
|
||||||
// now the parent with the highest lane number determines whether we need more space to the right...
|
// now the parent with the highest lane number determines whether we need more space to the right...
|
||||||
|
|
||||||
|
|
||||||
// build the table row and insert it, so we can find out the required height
|
commit.dot = paper.circle( getXPositionForColumnNumber(commit.column), commit.lane.centerY, cfg.dotRadius );
|
||||||
var drawingArea = $('<div class="network-tree-segment"></div>');
|
|
||||||
tableRow.append( $('<td/>').append(drawingArea));
|
|
||||||
tableRow.append('<td>' + commit.date.toLocaleString() +'</td>');
|
|
||||||
tableRow.append('<td>' + commit.author.name + '</td>');
|
|
||||||
tableRow.append('<td>' + commit.message + '</td>');
|
|
||||||
tableRow.data('theCommit', commit);
|
|
||||||
|
|
||||||
commitsTable.append(tableRow);
|
|
||||||
|
|
||||||
// awesome, now we have the height!
|
|
||||||
var paper = Raphael( drawingArea[0], cfg.laneWidth * maxLanes, cfg.rowHeight);
|
|
||||||
tableRow.data('rjsPaper', paper);
|
|
||||||
|
|
||||||
commit.tr = tableRow;
|
|
||||||
|
|
||||||
commit.dot = paper.circle( commit.lane.centerX, cfg.rowHeight/2, cfg.dotRadius );
|
|
||||||
commit.dot.attr({
|
commit.dot.attr({
|
||||||
fill: commit.lane.color,
|
fill: commit.lane.color,
|
||||||
stroke: 'none'
|
stroke: 'none',
|
||||||
});
|
cursor: 'pointer'
|
||||||
|
})
|
||||||
|
.data('commit', commit)
|
||||||
|
.click( dotClickHandler );
|
||||||
|
|
||||||
// render the line from this commit to it's children, but on their lane
|
|
||||||
$.each( commit.children, function ( idx, thisChild ) {
|
$.each( commit.children, function ( idx, thisChild ) {
|
||||||
connectDots( commit, thisChild );
|
// if there is one child only, stay on the commit's lane as long as possible when connecting the dots.
|
||||||
|
// but if there is more than one child, switch to the child's lane ASAP.
|
||||||
|
// this is to display merges and forks where they happen (ie. at a commit node/ a dot), rather than
|
||||||
|
// connecting from a line.
|
||||||
|
// So: commit.isFork decides whether or not we must switch lanes early
|
||||||
|
|
||||||
|
connectDots( commit, thisChild, commit.isFork );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function connectDots( firstCommit, secondCommit ) {
|
/**
|
||||||
var tableRow = firstCommit.tr;
|
*
|
||||||
// for each child,
|
* @param firstCommit
|
||||||
// move upwards in <tr>s, beginning from the "commit" (not: child!)
|
* @param secondCommit
|
||||||
// until the tr.data('theCommit') is thisChild.
|
* @param switchLanesEarly (boolean): Move the line to the secondCommit's lane ASAP? Defaults to false
|
||||||
//
|
*/
|
||||||
// if there is one child only, stay on the commit's lane as long as possible,
|
function connectDots( firstCommit, secondCommit, switchLanesEarly ) {
|
||||||
// but if there is more than one child, switch to the child's lane ASAP.
|
switchLanesEarly = switchLanesEarly || false;
|
||||||
// this is to display merges and forks where they happen (ie. at a commit node/ a dot), rather than
|
|
||||||
// "forking" from a line
|
|
||||||
|
|
||||||
var nRow = tableRow.prev('tr'),
|
|
||||||
// lineX holds the X position the line will be on while it's straight
|
|
||||||
lineLane = firstCommit.lane;
|
|
||||||
|
|
||||||
if( firstCommit.isFork ) {
|
var lineLane = switchLanesEarly ? secondCommit.lane : firstCommit.lane;
|
||||||
lineLane = secondCommit.lane;
|
|
||||||
}
|
|
||||||
|
|
||||||
// before iterating upwards as described above, the line part from the commit to the adequate lane
|
// the connection has 3 segments:
|
||||||
// must be drawn
|
// - from the x/y center of firstCommit.dot to the rightmost end (x) of the commit's column, with y=lineLane
|
||||||
tableRow.data('rjsPaper').path(
|
// - from the rightmost end of firstCommit's column, to the leftmost end of secondCommit's column
|
||||||
getSvgLineString( firstCommit.lane.centerX, cfg.rowHeight/2,
|
// - from the leftmost end of secondCommit's column (y=lineLane) to the x/y center of secondCommit
|
||||||
lineLane.centerX, 0) )
|
|
||||||
.attr({
|
|
||||||
|
|
||||||
|
// draw the line between the two dots
|
||||||
|
paper.path( getSvgLineString( [firstCommit.dot.attr('cx'),
|
||||||
|
firstCommit.dot.attr('cy')],
|
||||||
|
|
||||||
|
[firstCommit.dot.attr('cx') + (cfg.columnWidth/2),
|
||||||
|
lineLane.centerY],
|
||||||
|
|
||||||
|
[secondCommit.dot.attr('cx') - (cfg.columnWidth/2),
|
||||||
|
lineLane.centerY],
|
||||||
|
|
||||||
|
[secondCommit.dot.attr('cx'),
|
||||||
|
secondCommit.dot.attr('cy')]
|
||||||
|
)).attr({
|
||||||
stroke: lineLane.color, "stroke-width": 2
|
stroke: lineLane.color, "stroke-width": 2
|
||||||
})
|
}).toBack();
|
||||||
.data('theCommit', firstCommit).data('theChild', secondCommit).click(lineClickHandler)
|
return;
|
||||||
.toBack();
|
|
||||||
|
|
||||||
while( nRow.length > 0 ) {
|
|
||||||
|
|
||||||
if ( nRow.data('theCommit') === secondCommit ) {
|
|
||||||
// we are done, render only the bottom half line towards the child
|
|
||||||
// Starting at lineX, but moving to thisChild's lane.
|
|
||||||
nRow.data('rjsPaper')
|
|
||||||
.path(
|
|
||||||
getSvgLineString( lineLane.centerX, cfg.rowHeight,
|
|
||||||
secondCommit.lane.centerX, cfg.rowHeight/2) )
|
|
||||||
.attr({
|
|
||||||
stroke: lineLane.color, "stroke-width": 2
|
|
||||||
})
|
|
||||||
.data('theCommit', firstCommit).data('theChild', secondCommit).click(lineClickHandler)
|
|
||||||
.toBack();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// this is just a common "throughput" line part from bottom of the TR to top without any X movement
|
|
||||||
//
|
|
||||||
// maybe the paper isn't big enough yet, so expand it first...
|
|
||||||
nRow.data('rjsPaper')
|
|
||||||
.path(
|
|
||||||
getSvgLineString( lineLane.centerX, 0,
|
|
||||||
lineLane.centerX, cfg.rowHeight) )
|
|
||||||
.attr({
|
|
||||||
stroke: lineLane.color, "stroke-width": 2
|
|
||||||
})
|
|
||||||
.data('theCommit', firstCommit).data('theChild', secondCommit).click(lineClickHandler)
|
|
||||||
.toBack();
|
|
||||||
nRow = nRow.prev('tr');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSvgLineString( fromX, fromY, toX, toY ) {
|
// set together a path string from any amount of arguments
|
||||||
return 'M' + fromX + ',' + fromY + 'L' + toX + ',' + toY;
|
// each argument is an array of [x, y]
|
||||||
|
function getSvgLineString( ) {
|
||||||
|
if (arguments.length < 2) return
|
||||||
|
|
||||||
|
// we are using a little trick here: Due to the right-to-left direction of the graph, the fix point is at the
|
||||||
|
// right hand side. But the top-right point will change each time we extend the drawing area, which would
|
||||||
|
// result in a terrible parsing and re-assembling every single sub path.
|
||||||
|
// Instead, we use the moveto feature to start the line at "our" base (top-right), and draw the lines using
|
||||||
|
// relative linetos: The linetos will always stay the same - we only have to update the base
|
||||||
|
|
||||||
|
var svgString = 'M' + arguments[0][0] + ' ' + arguments[0][1];
|
||||||
|
|
||||||
|
for (var i = 1, j = arguments.length; i < j; i++){
|
||||||
|
|
||||||
|
// x =0 means a relatively unchanged x value
|
||||||
|
|
||||||
|
svgString += 'L' + arguments[i][0] + ' ' + arguments[i][1];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return svgString;
|
||||||
}
|
}
|
||||||
|
|
||||||
function lineClickHandler() {
|
function lineClickHandler() {
|
||||||
@@ -324,10 +337,52 @@ $( function() {
|
|||||||
function getLaneInfo( laneNumber ) {
|
function getLaneInfo( laneNumber ) {
|
||||||
return {
|
return {
|
||||||
'number': laneNumber,
|
'number': laneNumber,
|
||||||
'centerX': ( laneNumber * cfg.laneWidth ) + (cfg.laneWidth/2),
|
'centerY': ( laneNumber * cfg.laneHeight ) + (cfg.laneHeight/2),
|
||||||
'color': cfg.laneColors[ laneNumber % cfg.laneColors.length ]
|
'color': cfg.laneColors[ laneNumber % cfg.laneColors.length ]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getXPositionForColumnNumber( columnNumber ) {
|
||||||
|
// we want the column's center point
|
||||||
|
return ( paper.width - ( columnNumber * cfg.columnWidth ) - (cfg.columnWidth / 2 ));
|
||||||
|
}
|
||||||
|
|
||||||
|
function initScrolling() {
|
||||||
|
commitsGraph.on('mousedown', handleMouseDown);
|
||||||
|
var lastX, lastY;
|
||||||
|
|
||||||
|
function handleMouseDown( evt ) {
|
||||||
|
commitsGraph.on('mousemove', handleMouseMove);
|
||||||
|
commitsGraph.on('mouseup', handleMouseUp);
|
||||||
|
commitsGraph.on('mouseleave', handleMouseUp);
|
||||||
|
lastX = evt.pageX;
|
||||||
|
lastY = evt.pageY;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMouseMove(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
|
||||||
|
commitsGraph[0].scrollLeft = commitsGraph[0].scrollLeft + lastX - evt.pageX;
|
||||||
|
commitsGraph[0].scrollTop = commitsGraph[0].scrollTop + lastY - evt.pageY;
|
||||||
|
|
||||||
|
lastX = evt.pageX;
|
||||||
|
lastY = evt.pageY;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMouseUp(evt) {
|
||||||
|
commitsGraph.off('mousemove', handleMouseMove);
|
||||||
|
commitsGraph.off('mouseup', handleMouseUp);
|
||||||
|
commitsGraph.off('mouseleave', handleMouseUp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
refreshButton.click(refreshButtonClickHandler);
|
||||||
|
initScrolling();
|
||||||
|
// load initial data
|
||||||
|
fetchCommitData( nextPage );
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -28,6 +28,9 @@
|
|||||||
}
|
}
|
||||||
.network-graph {
|
.network-graph {
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
|
height: 400px;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: move;
|
||||||
|
|
||||||
.network-tree-segment {
|
.network-tree-segment {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -35,9 +38,5 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user