Fossil SCM
Improved graph rendering in the case of a time-warp.
Commit
79b81a31c0daa6a9c7ebf43c2cc9f72d4d9ffee7
Parent
a327bd29bcc567a…
2 files changed
+21
-7
+10
-2
+21
-7
| --- src/graph.c | ||
| +++ src/graph.c | ||
| @@ -314,15 +314,15 @@ | ||
| 314 | 314 | ** In the case of a fork, choose the pChild that results in the |
| 315 | 315 | ** longest rail. |
| 316 | 316 | */ |
| 317 | 317 | for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ |
| 318 | 318 | if( pRow->isDup ) continue; |
| 319 | - if( pRow->nParent==0 ) continue; | |
| 319 | + if( pRow->nParent==0 ) continue; /* Root node */ | |
| 320 | 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; | |
| 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 | 324 | if( pRow->idxTop < pParent->idxTop ){ |
| 325 | 325 | pParent->pChild = pRow; |
| 326 | 326 | pParent->idxTop = pRow->idxTop; |
| 327 | 327 | } |
| 328 | 328 | } |
| @@ -375,17 +375,31 @@ | ||
| 375 | 375 | }else{ |
| 376 | 376 | assert( pRow->nParent>0 ); |
| 377 | 377 | parentRid = pRow->aParent[0]; |
| 378 | 378 | pParent = hashFind(p, parentRid); |
| 379 | 379 | if( pParent==0 ){ |
| 380 | - /* Time skew */ | |
| 381 | 380 | pRow->iRail = ++p->mxRail; |
| 382 | 381 | pRow->railInUse = 1<<pRow->iRail; |
| 383 | 382 | continue; |
| 384 | 383 | } |
| 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 | + } | |
| 387 | 401 | } |
| 388 | 402 | mask = 1<<pRow->iRail; |
| 389 | 403 | pRow->railInUse |= mask; |
| 390 | 404 | if( pRow->pChild==0 ){ |
| 391 | 405 | inUse &= ~mask; |
| 392 | 406 |
| --- 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 @@ | ||
| 532 | 532 | @ } |
| 533 | 533 | @ var n = p.au.length; |
| 534 | 534 | @ for(var i=0; i<n; i+=2){ |
| 535 | 535 | @ var x1 = p.au[i]*20 + left; |
| 536 | 536 | @ var x0 = x1>p.x ? p.x+7 : p.x-6; |
| 537 | - @ drawBox("black",x0,p.y,x1,p.y+1); | |
| 538 | 537 | @ 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 | + @ } | |
| 540 | 548 | @ } |
| 541 | 549 | @ for(var j in p.mi){ |
| 542 | 550 | @ var y0 = p.y+5; |
| 543 | 551 | @ var mx = p.mi[j]*20 + left; |
| 544 | 552 | @ if( mx>p.x ){ |
| 545 | 553 |
| --- 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 |