513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
|
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
|
-
+
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
|
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
if( pRow->isDup ) continue;
if( pRow->nParent<=0 ) continue; /* Root node */
pParent = hashFind(p, pRow->aParent[0]);
if( pParent==0 ) continue; /* Parent off-screen */
if( pParent->zBranch!=pRow->zBranch ) continue; /* Different branch */
if( pParent->idx <= pRow->idx ){
pParent->timeWarp = 1;
pParent->timeWarp = 1;
continue; /* Time-warp */
}
if( pRow->idxTop < pParent->idxTop ){
}else if( pRow->idx < pParent->idx ){
pParent->pChild = pRow;
pParent->idxTop = pRow->idxTop;
}
}
if( tmFlags & TIMELINE_FILLGAPS ){
/* If a node has no pChild but there is a node higher up in the graph
** that is in the same branch and that other node has no parent in
** the graph, the lower node a step-child of the upper node. This will
** be represented on the graph by a thick dotted line without an arrowhead.
*/
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
if( pRow->pChild ) continue;
for(pLoop=pRow->pPrev; pLoop; pLoop=pLoop->pPrev){
if( pLoop->nParent>0
&& pLoop->zBranch==pRow->zBranch
&& hashFind(p,pLoop->aParent[0])==0
){
pRow->pChild = pLoop;
pRow->idxTop = pLoop->idxTop;
pRow->isStepParent = 1;
pLoop->aParent[0] = pRow->rid;
break;
}
}
}
}
/* Set the idxTop values for all entries. The idxTop value is the
** "idx" value for the top entry in its stack of children.
*/
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
GraphRow *pChild = pRow->pChild;
if( pChild && pRow->idxTop>pChild->idxTop ){
pRow->idxTop = pChild->idxTop;
}
}
/* Identify rows where the primary parent is off screen. Assign
** each to a rail and draw descenders downward.
**
** Strive to put the "trunk" branch on far left.
*/
zTrunk = persistBranchName(p, "trunk");
for(i=0; i<2; i++){
for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
if( i==0 && pRow->zBranch!=zTrunk ) continue;
if( pRow->iRail>=0 ) continue;
if( pRow->isDup ) continue;
if( pRow->nParent<0 ) continue;
if( i==0 ){
if( pRow->zBranch!=zTrunk ) continue;
}else {
if( pRow->iRail>=0 ) continue;
}
if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){
pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+RISER_MARGIN, 0);
if( p->mxRail>=GR_MAX_RAIL ) return;
mask = BIT(pRow->iRail);
if( !omitDescenders ){
int n = RISER_MARGIN;
pRow->bDescender = pRow->nParent>0;
|