Fossil SCM

Fix to the graph layout for complex time-warp cases. Add tooltips to timewarp arrows.

drh 2019-06-08 16:11 trunk
Commit 5399c5dacb808e4cc5ec5a76fd4d8a4823d96f0b1a21d692d9c06522839c3ad3
2 files changed +13 -3 +10 -4
+13 -3
--- src/graph.c
+++ src/graph.c
@@ -278,11 +278,12 @@
278278
}
279279
for(i=0; i<GR_MAX_RAIL; i++){
280280
if( (inUseMask & BIT(i))==0 ){
281281
int dist;
282282
if( iNearto<=0 ){
283
- return i;
283
+ iBest = i;
284
+ break;
284285
}
285286
dist = i - iNearto;
286287
if( dist<0 ) dist = -dist;
287288
if( dist<iBestDist ){
288289
iBestDist = dist;
@@ -307,10 +308,11 @@
307308
pBottom->railInUse |= mask;
308309
pPrior = pBottom;
309310
for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
310311
assert( pPrior->idx > pCurrent->idx );
311312
assert( pCurrent->iRail<0 );
313
+ if( pPrior->timeWarp ) break;
312314
pCurrent->iRail = iRail;
313315
pCurrent->railInUse |= mask;
314316
pPrior->aiRiser[iRail] = pCurrent->idx;
315317
while( pPrior->idx > pCurrent->idx ){
316318
pPrior->railInUse |= mask;
@@ -643,12 +645,20 @@
643645
assignChildrenToRail(pRow, tmFlags);
644646
}else if( !omitDescenders && count_nonbranch_children(pRow->rid)!=0 ){
645647
if( !pRow->timeWarp ) riser_to_top(pRow);
646648
}
647649
if( pParent ){
648
- for(pLoop=pParent->pPrev; pLoop && pLoop!=pRow; pLoop=pLoop->pPrev){
649
- pLoop->railInUse |= mask;
650
+ if( pParent->idx>pRow->idx ){
651
+ /* Common case: Parent is below current row in the graph */
652
+ for(pLoop=pParent->pPrev; pLoop && pLoop!=pRow; pLoop=pLoop->pPrev){
653
+ pLoop->railInUse |= mask;
654
+ }
655
+ }else{
656
+ /* Timewarp case: Parent is above current row in the graph */
657
+ for(pLoop=pParent->pNext; pLoop && pLoop!=pRow; pLoop=pLoop->pNext){
658
+ pLoop->railInUse |= mask;
659
+ }
650660
}
651661
}
652662
}
653663
654664
/*
655665
--- src/graph.c
+++ src/graph.c
@@ -278,11 +278,12 @@
278 }
279 for(i=0; i<GR_MAX_RAIL; i++){
280 if( (inUseMask & BIT(i))==0 ){
281 int dist;
282 if( iNearto<=0 ){
283 return i;
 
284 }
285 dist = i - iNearto;
286 if( dist<0 ) dist = -dist;
287 if( dist<iBestDist ){
288 iBestDist = dist;
@@ -307,10 +308,11 @@
307 pBottom->railInUse |= mask;
308 pPrior = pBottom;
309 for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
310 assert( pPrior->idx > pCurrent->idx );
311 assert( pCurrent->iRail<0 );
 
312 pCurrent->iRail = iRail;
313 pCurrent->railInUse |= mask;
314 pPrior->aiRiser[iRail] = pCurrent->idx;
315 while( pPrior->idx > pCurrent->idx ){
316 pPrior->railInUse |= mask;
@@ -643,12 +645,20 @@
643 assignChildrenToRail(pRow, tmFlags);
644 }else if( !omitDescenders && count_nonbranch_children(pRow->rid)!=0 ){
645 if( !pRow->timeWarp ) riser_to_top(pRow);
646 }
647 if( pParent ){
648 for(pLoop=pParent->pPrev; pLoop && pLoop!=pRow; pLoop=pLoop->pPrev){
649 pLoop->railInUse |= mask;
 
 
 
 
 
 
 
 
650 }
651 }
652 }
653
654 /*
655
--- src/graph.c
+++ src/graph.c
@@ -278,11 +278,12 @@
278 }
279 for(i=0; i<GR_MAX_RAIL; i++){
280 if( (inUseMask & BIT(i))==0 ){
281 int dist;
282 if( iNearto<=0 ){
283 iBest = i;
284 break;
285 }
286 dist = i - iNearto;
287 if( dist<0 ) dist = -dist;
288 if( dist<iBestDist ){
289 iBestDist = dist;
@@ -307,10 +308,11 @@
308 pBottom->railInUse |= mask;
309 pPrior = pBottom;
310 for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
311 assert( pPrior->idx > pCurrent->idx );
312 assert( pCurrent->iRail<0 );
313 if( pPrior->timeWarp ) break;
314 pCurrent->iRail = iRail;
315 pCurrent->railInUse |= mask;
316 pPrior->aiRiser[iRail] = pCurrent->idx;
317 while( pPrior->idx > pCurrent->idx ){
318 pPrior->railInUse |= mask;
@@ -643,12 +645,20 @@
645 assignChildrenToRail(pRow, tmFlags);
646 }else if( !omitDescenders && count_nonbranch_children(pRow->rid)!=0 ){
647 if( !pRow->timeWarp ) riser_to_top(pRow);
648 }
649 if( pParent ){
650 if( pParent->idx>pRow->idx ){
651 /* Common case: Parent is below current row in the graph */
652 for(pLoop=pParent->pPrev; pLoop && pLoop!=pRow; pLoop=pLoop->pPrev){
653 pLoop->railInUse |= mask;
654 }
655 }else{
656 /* Timewarp case: Parent is above current row in the graph */
657 for(pLoop=pParent->pNext; pLoop && pLoop!=pRow; pLoop=pLoop->pNext){
658 pLoop->railInUse |= mask;
659 }
660 }
661 }
662 }
663
664 /*
665
+10 -4
--- src/graph.js
+++ src/graph.js
@@ -485,20 +485,26 @@
485485
x1 += line.w;
486486
}
487487
var y0 = p.y + (node.h-line.w)/2;
488488
var u = tx.rowinfo[p.au[i+1]-tx.iTopRow];
489489
if( u.id<p.id ){
490
+ // normal thick up-arrow
490491
drawLine(line,u.fg,x0,y0,x1,null);
491492
drawUpArrow(p,u,u.fg,u.id);
492493
}else{
494
+ // timewarp: The child node occurs before the parent
493495
var y1 = u.y + (node.h-line.w)/2;
494
- drawLine(wLine,u.fg,x0,y0,x1,null);
495
- drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w);
496
- drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null);
496
+ var n = drawLine(wLine,u.fg,x0,y0,x1,null);
497
+ addToolTip(n,u.id)
498
+ n = drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w);
499
+ addToolTip(n,u.id)
500
+ n = drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null);
501
+ addToolTip(n,u.id)
497502
var x = u.x-wArrow.w;
498503
var y = u.y+(node.h-wArrow.h)/2;
499
- var n = drawBox(wArrow.cls,null,x,y);
504
+ n = drawBox(wArrow.cls,null,x,y);
505
+ addToolTip(n,u.id)
500506
if( u.fg ) n.style.borderLeftColor = u.fg;
501507
}
502508
}
503509
}
504510
if( p.hasOwnProperty('mi') ){
505511
--- src/graph.js
+++ src/graph.js
@@ -485,20 +485,26 @@
485 x1 += line.w;
486 }
487 var y0 = p.y + (node.h-line.w)/2;
488 var u = tx.rowinfo[p.au[i+1]-tx.iTopRow];
489 if( u.id<p.id ){
 
490 drawLine(line,u.fg,x0,y0,x1,null);
491 drawUpArrow(p,u,u.fg,u.id);
492 }else{
 
493 var y1 = u.y + (node.h-line.w)/2;
494 drawLine(wLine,u.fg,x0,y0,x1,null);
495 drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w);
496 drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null);
 
 
 
497 var x = u.x-wArrow.w;
498 var y = u.y+(node.h-wArrow.h)/2;
499 var n = drawBox(wArrow.cls,null,x,y);
 
500 if( u.fg ) n.style.borderLeftColor = u.fg;
501 }
502 }
503 }
504 if( p.hasOwnProperty('mi') ){
505
--- src/graph.js
+++ src/graph.js
@@ -485,20 +485,26 @@
485 x1 += line.w;
486 }
487 var y0 = p.y + (node.h-line.w)/2;
488 var u = tx.rowinfo[p.au[i+1]-tx.iTopRow];
489 if( u.id<p.id ){
490 // normal thick up-arrow
491 drawLine(line,u.fg,x0,y0,x1,null);
492 drawUpArrow(p,u,u.fg,u.id);
493 }else{
494 // timewarp: The child node occurs before the parent
495 var y1 = u.y + (node.h-line.w)/2;
496 var n = drawLine(wLine,u.fg,x0,y0,x1,null);
497 addToolTip(n,u.id)
498 n = drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w);
499 addToolTip(n,u.id)
500 n = drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null);
501 addToolTip(n,u.id)
502 var x = u.x-wArrow.w;
503 var y = u.y+(node.h-wArrow.h)/2;
504 n = drawBox(wArrow.cls,null,x,y);
505 addToolTip(n,u.id)
506 if( u.fg ) n.style.borderLeftColor = u.fg;
507 }
508 }
509 }
510 if( p.hasOwnProperty('mi') ){
511

Keyboard Shortcuts

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