Fossil SCM

Improved graph rendering in the case of a time-warp.

drh 2011-02-11 16:52 trunk
Commit 79b81a31c0daa6a9c7ebf43c2cc9f72d4d9ffee7
2 files changed +21 -7 +10 -2
+21 -7
--- src/graph.c
+++ src/graph.c
@@ -314,15 +314,15 @@
314314
** In the case of a fork, choose the pChild that results in the
315315
** longest rail.
316316
*/
317317
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
318318
if( pRow->isDup ) continue;
319
- if( pRow->nParent==0 ) continue;
319
+ if( pRow->nParent==0 ) continue; /* Root node */
320320
pParent = hashFind(p, pRow->aParent[0]);
321
- if( pParent==0 ) continue;
322
- if( pParent->zBranch!=pRow->zBranch ) continue;
323
- if( pParent->idx <= pRow->idx ) continue;
321
+ if( pParent==0 ) continue; /* Parent off-screen */
322
+ if( pParent->zBranch!=pRow->zBranch ) continue; /* Different branch */
323
+ if( pParent->idx <= pRow->idx ) continue; /* Time-warp */
324324
if( pRow->idxTop < pParent->idxTop ){
325325
pParent->pChild = pRow;
326326
pParent->idxTop = pRow->idxTop;
327327
}
328328
}
@@ -375,17 +375,31 @@
375375
}else{
376376
assert( pRow->nParent>0 );
377377
parentRid = pRow->aParent[0];
378378
pParent = hashFind(p, parentRid);
379379
if( pParent==0 ){
380
- /* Time skew */
381380
pRow->iRail = ++p->mxRail;
382381
pRow->railInUse = 1<<pRow->iRail;
383382
continue;
384383
}
385
- pRow->iRail = findFreeRail(p, 0, pParent->idx, inUse, pParent->iRail);
386
- pParent->aiRiser[pRow->iRail] = pRow->idx;
384
+ if( pParent->idx>pRow->idx ){
385
+ /* Common case: Child occurs after parent and is above the
386
+ ** parent in the timeline */
387
+ pRow->iRail = findFreeRail(p, 0, pParent->idx, inUse, pParent->iRail);
388
+ pParent->aiRiser[pRow->iRail] = pRow->idx;
389
+ }else{
390
+ /* Timewarp case: Child occurs earlier in time than parent and
391
+ ** appears below the parent in the timeline. */
392
+ int iDownRail = ++p->mxRail;
393
+ pRow->iRail = ++p->mxRail;
394
+ pRow->railInUse = 1<<pRow->iRail;
395
+ pParent->aiRiser[iDownRail] = pRow->idx;
396
+ mask = 1<<iDownRail;
397
+ for(pLoop=p->pFirst; pLoop; pLoop=pLoop->pNext){
398
+ pLoop->railInUse |= mask;
399
+ }
400
+ }
387401
}
388402
mask = 1<<pRow->iRail;
389403
pRow->railInUse |= mask;
390404
if( pRow->pChild==0 ){
391405
inUse &= ~mask;
392406
--- src/graph.c
+++ src/graph.c
@@ -314,15 +314,15 @@
314 ** In the case of a fork, choose the pChild that results in the
315 ** longest rail.
316 */
317 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
318 if( pRow->isDup ) continue;
319 if( pRow->nParent==0 ) continue;
320 pParent = hashFind(p, pRow->aParent[0]);
321 if( pParent==0 ) continue;
322 if( pParent->zBranch!=pRow->zBranch ) continue;
323 if( pParent->idx <= pRow->idx ) continue;
324 if( pRow->idxTop < pParent->idxTop ){
325 pParent->pChild = pRow;
326 pParent->idxTop = pRow->idxTop;
327 }
328 }
@@ -375,17 +375,31 @@
375 }else{
376 assert( pRow->nParent>0 );
377 parentRid = pRow->aParent[0];
378 pParent = hashFind(p, parentRid);
379 if( pParent==0 ){
380 /* Time skew */
381 pRow->iRail = ++p->mxRail;
382 pRow->railInUse = 1<<pRow->iRail;
383 continue;
384 }
385 pRow->iRail = findFreeRail(p, 0, pParent->idx, inUse, pParent->iRail);
386 pParent->aiRiser[pRow->iRail] = pRow->idx;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387 }
388 mask = 1<<pRow->iRail;
389 pRow->railInUse |= mask;
390 if( pRow->pChild==0 ){
391 inUse &= ~mask;
392
--- src/graph.c
+++ src/graph.c
@@ -314,15 +314,15 @@
314 ** In the case of a fork, choose the pChild that results in the
315 ** longest rail.
316 */
317 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
318 if( pRow->isDup ) continue;
319 if( pRow->nParent==0 ) continue; /* Root node */
320 pParent = hashFind(p, pRow->aParent[0]);
321 if( pParent==0 ) continue; /* Parent off-screen */
322 if( pParent->zBranch!=pRow->zBranch ) continue; /* Different branch */
323 if( pParent->idx <= pRow->idx ) continue; /* Time-warp */
324 if( pRow->idxTop < pParent->idxTop ){
325 pParent->pChild = pRow;
326 pParent->idxTop = pRow->idxTop;
327 }
328 }
@@ -375,17 +375,31 @@
375 }else{
376 assert( pRow->nParent>0 );
377 parentRid = pRow->aParent[0];
378 pParent = hashFind(p, parentRid);
379 if( pParent==0 ){
 
380 pRow->iRail = ++p->mxRail;
381 pRow->railInUse = 1<<pRow->iRail;
382 continue;
383 }
384 if( pParent->idx>pRow->idx ){
385 /* Common case: Child occurs after parent and is above the
386 ** parent in the timeline */
387 pRow->iRail = findFreeRail(p, 0, pParent->idx, inUse, pParent->iRail);
388 pParent->aiRiser[pRow->iRail] = pRow->idx;
389 }else{
390 /* Timewarp case: Child occurs earlier in time than parent and
391 ** appears below the parent in the timeline. */
392 int iDownRail = ++p->mxRail;
393 pRow->iRail = ++p->mxRail;
394 pRow->railInUse = 1<<pRow->iRail;
395 pParent->aiRiser[iDownRail] = pRow->idx;
396 mask = 1<<iDownRail;
397 for(pLoop=p->pFirst; pLoop; pLoop=pLoop->pNext){
398 pLoop->railInUse |= mask;
399 }
400 }
401 }
402 mask = 1<<pRow->iRail;
403 pRow->railInUse |= mask;
404 if( pRow->pChild==0 ){
405 inUse &= ~mask;
406
+10 -2
--- src/timeline.c
+++ src/timeline.c
@@ -532,13 +532,21 @@
532532
@ }
533533
@ var n = p.au.length;
534534
@ for(var i=0; i<n; i+=2){
535535
@ var x1 = p.au[i]*20 + left;
536536
@ var x0 = x1>p.x ? p.x+7 : p.x-6;
537
- @ drawBox("black",x0,p.y,x1,p.y+1);
538537
@ var u = rowinfo[p.au[i+1]-1];
539
- @ drawUpArrow(x1, u.y+6, p.y);
538
+ @ if(u.id<p.id){
539
+ @ drawBox("black",x0,p.y,x1,p.y+1);
540
+ @ drawUpArrow(x1, u.y+6, p.y);
541
+ @ }else{
542
+ @ drawBox("#600000",x0,p.y,x1,p.y+1);
543
+ @ drawBox("#600000",x1-1,p.y,x1,u.y+1);
544
+ @ drawBox("#600000",x1,u.y,u.x-6,u.y+1);
545
+ @ drawBox("#600000",u.x-9,u.y-1,u.x-8,u.y+2);
546
+ @ drawBox("#600000",u.x-11,u.y-2,u.x-10,u.y+3);
547
+ @ }
540548
@ }
541549
@ for(var j in p.mi){
542550
@ var y0 = p.y+5;
543551
@ var mx = p.mi[j]*20 + left;
544552
@ if( mx>p.x ){
545553
--- src/timeline.c
+++ src/timeline.c
@@ -532,13 +532,21 @@
532 @ }
533 @ var n = p.au.length;
534 @ for(var i=0; i<n; i+=2){
535 @ var x1 = p.au[i]*20 + left;
536 @ var x0 = x1>p.x ? p.x+7 : p.x-6;
537 @ drawBox("black",x0,p.y,x1,p.y+1);
538 @ var u = rowinfo[p.au[i+1]-1];
539 @ drawUpArrow(x1, u.y+6, p.y);
 
 
 
 
 
 
 
 
 
540 @ }
541 @ for(var j in p.mi){
542 @ var y0 = p.y+5;
543 @ var mx = p.mi[j]*20 + left;
544 @ if( mx>p.x ){
545
--- src/timeline.c
+++ src/timeline.c
@@ -532,13 +532,21 @@
532 @ }
533 @ var n = p.au.length;
534 @ for(var i=0; i<n; i+=2){
535 @ var x1 = p.au[i]*20 + left;
536 @ var x0 = x1>p.x ? p.x+7 : p.x-6;
 
537 @ var u = rowinfo[p.au[i+1]-1];
538 @ if(u.id<p.id){
539 @ drawBox("black",x0,p.y,x1,p.y+1);
540 @ drawUpArrow(x1, u.y+6, p.y);
541 @ }else{
542 @ drawBox("#600000",x0,p.y,x1,p.y+1);
543 @ drawBox("#600000",x1-1,p.y,x1,u.y+1);
544 @ drawBox("#600000",x1,u.y,u.x-6,u.y+1);
545 @ drawBox("#600000",u.x-9,u.y-1,u.x-8,u.y+2);
546 @ drawBox("#600000",u.x-11,u.y-2,u.x-10,u.y+3);
547 @ }
548 @ }
549 @ for(var j in p.mi){
550 @ var y0 = p.y+5;
551 @ var mx = p.mi[j]*20 + left;
552 @ if( mx>p.x ){
553

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button