Fossil

Check-in [980adfa6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge graph layout enhancements from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tooltip-experiments
Files: files | file ages | folders
SHA3-256: 980adfa6bdc917ffb10e663dfbab9bcfbd0019920626a04f1ddd5c3c76b687e2
User & Date: drh 2019-05-21 19:07:27
Wiki:tooltip-experiments
Context
2019-05-22
11:37
Simplifications to the javascript for tooltip handling. check-in: 2189edcd user: drh tags: tooltip-experiments
2019-05-21
19:07
Merge graph layout enhancements from trunk. check-in: 980adfa6 user: drh tags: tooltip-experiments
19:04
Improved computation of the rail mapper for timelines on a branch. If the branch is across two or more rails, then all rails of that branch are moved to the left as far as practical. check-in: d19df616 user: drh tags: trunk
09:40
Fix a bug introduced with [e0198213f3]: using "style.visibility" is essential to calculate the dimensions in the hidden state. check-in: 3850b32c user: florian tags: tooltip-experiments
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/graph.c.

71
72
73
74
75
76
77

78
79
80
81
82
83
84
...
317
318
319
320
321
322
323

324

325
326
327
328
329
330
331
...
343
344
345
346
347
348
349


350
351
352
353
354
355
356
357
358
359
360
361
362
...
422
423
424
425
426
427
428

429
430
431
432
433
434
435
...
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738

739
740
741
742
  GraphRow *pChild;           /* Child immediately above this node */
  u8 isDup;                   /* True if this is duplicate of a prior entry */
  u8 isLeaf;                  /* True if this is a leaf node */
  u8 isStepParent;            /* pChild is actually a step-child */
  u8 hasNormalOutMerge;       /* Is parent of at laest 1 non-cherrypick merge */
  u8 timeWarp;                /* Child is earlier in time */
  u8 bDescender;              /* True if riser from bottom of graph to here. */

  i8 iRail;                   /* Which rail this check-in appears on. 0-based.*/
  i8 mergeOut;                /* Merge out to this rail.  -1 if no merge-out */
  u8 mergeIn[GR_MAX_RAIL];    /* Merge in from non-zero rails */
  int aiRiser[GR_MAX_RAIL];   /* Risers from this node to a higher row. */
  int mergeUpto;              /* Draw the mergeOut rail up to this level */
  int cherrypickUpto;         /* Continue the mergeOut rail up to here */
  u64 mergeDown;              /* Draw merge lines up from bottom of graph */
................................................................................
      assert( pPrior!=0 );
    }
  }
  /* Mask of additional rows for the riser to infinity */
  if( !pPrior->isLeaf && (tmFlags & TIMELINE_DISJOINT)==0 ){
    int n = RISER_MARGIN;
    GraphRow *p;

    for(p=pPrior; p && (n--)>0; p=p->pPrev){

      p->railInUse |= mask;
    }
  }
}

/*
** Create a merge-arrow riser going from pParent up to pChild.
................................................................................
  if( pParent->mergeOut<0 ){
    u = pParent->aiRiser[pParent->iRail];
    if( u>0 && u<pChild->idx ){
      /* The thick arrow up to the next primary child of pDesc goes
      ** further up than the thin merge arrow riser, so draw them both
      ** on the same rail. */
      pParent->mergeOut = pParent->iRail;


    }else{
      /* The thin merge arrow riser is taller than the thick primary
      ** child riser, so use separate rails. */
      int iTarget = pParent->iRail;
      int iBtm = pParent->idx - (u==0 ? RISER_MARGIN : 1);
      pParent->mergeOut = findFreeRail(p, pChild->idx, iBtm, iTarget);
      mask = BIT(pParent->mergeOut);
      for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
           pLoop=pLoop->pNext){
        pLoop->railInUse |= mask;
      }
    }
  }
................................................................................
*/
void graph_finish(GraphContext *p, const char *zLeftBranch, u32 tmFlags){
  GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
  int i, j;
  u64 mask;
  int hasDup = 0;      /* True if one or more isDup entries */
  const char *zTrunk;

  int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;

  /* If mergeRiserFrom[X]==Y that means rail X holds a merge riser
  ** coming up from the bottom of the graph from off-screen check-in Y
  ** where Y is the RID.  There is no riser on rail X if mergeRiserFrom[X]==0.
  */
  int mergeRiserFrom[GR_MAX_RAIL];
................................................................................
  ** Find the maximum rail number.
  */
  find_max_rail(p);

  /*
  ** Compute the rail mapping.
  */
  for(i=0; i<=p->mxRail; i++) p->aiRailMap[i] = i;
  if( zLeftBranch ){
    char *zLeft = persistBranchName(p, zLeftBranch);
    for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
      if( pRow->zBranch==zLeft ){
        int iLeftRail = pRow->iRail;
        p->aiRailMap[iLeftRail] = 0;
        for(i=0, j=1; i<=p->mxRail; i++){
          if( i==iLeftRail ) continue;
          p->aiRailMap[i] = j++;
        }
        assert( j==p->mxRail+1 );
        break;
      }
    }

  }

  p->nErr = 0;
}







>







 







>

>







 







>
>




<
|







 







>







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>




71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
...
346
347
348
349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
...
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
...
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
  GraphRow *pChild;           /* Child immediately above this node */
  u8 isDup;                   /* True if this is duplicate of a prior entry */
  u8 isLeaf;                  /* True if this is a leaf node */
  u8 isStepParent;            /* pChild is actually a step-child */
  u8 hasNormalOutMerge;       /* Is parent of at laest 1 non-cherrypick merge */
  u8 timeWarp;                /* Child is earlier in time */
  u8 bDescender;              /* True if riser from bottom of graph to here. */
  u8 selfUp;                  /* Space above this node but belonging */
  i8 iRail;                   /* Which rail this check-in appears on. 0-based.*/
  i8 mergeOut;                /* Merge out to this rail.  -1 if no merge-out */
  u8 mergeIn[GR_MAX_RAIL];    /* Merge in from non-zero rails */
  int aiRiser[GR_MAX_RAIL];   /* Risers from this node to a higher row. */
  int mergeUpto;              /* Draw the mergeOut rail up to this level */
  int cherrypickUpto;         /* Continue the mergeOut rail up to here */
  u64 mergeDown;              /* Draw merge lines up from bottom of graph */
................................................................................
      assert( pPrior!=0 );
    }
  }
  /* Mask of additional rows for the riser to infinity */
  if( !pPrior->isLeaf && (tmFlags & TIMELINE_DISJOINT)==0 ){
    int n = RISER_MARGIN;
    GraphRow *p;
    pPrior->selfUp = 0;
    for(p=pPrior; p && (n--)>0; p=p->pPrev){
      pPrior->selfUp++;
      p->railInUse |= mask;
    }
  }
}

/*
** Create a merge-arrow riser going from pParent up to pChild.
................................................................................
  if( pParent->mergeOut<0 ){
    u = pParent->aiRiser[pParent->iRail];
    if( u>0 && u<pChild->idx ){
      /* The thick arrow up to the next primary child of pDesc goes
      ** further up than the thin merge arrow riser, so draw them both
      ** on the same rail. */
      pParent->mergeOut = pParent->iRail;
    }else if( pParent->idx - pChild->idx < pParent->selfUp ){
      pParent->mergeOut = pParent->iRail;
    }else{
      /* The thin merge arrow riser is taller than the thick primary
      ** child riser, so use separate rails. */
      int iTarget = pParent->iRail;

      pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1, iTarget);
      mask = BIT(pParent->mergeOut);
      for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
           pLoop=pLoop->pNext){
        pLoop->railInUse |= mask;
      }
    }
  }
................................................................................
*/
void graph_finish(GraphContext *p, const char *zLeftBranch, u32 tmFlags){
  GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
  int i, j;
  u64 mask;
  int hasDup = 0;      /* True if one or more isDup entries */
  const char *zTrunk;
  u8 *aMap;            /* Copy of p->aiRailMap */
  int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;

  /* If mergeRiserFrom[X]==Y that means rail X holds a merge riser
  ** coming up from the bottom of the graph from off-screen check-in Y
  ** where Y is the RID.  There is no riser on rail X if mergeRiserFrom[X]==0.
  */
  int mergeRiserFrom[GR_MAX_RAIL];
................................................................................
  ** Find the maximum rail number.
  */
  find_max_rail(p);

  /*
  ** Compute the rail mapping.
  */
  aMap = p->aiRailMap;
  for(i=0; i<=p->mxRail; i++) aMap[i] = i;
  if( zLeftBranch ){
    char *zLeft = persistBranchName(p, zLeftBranch);
    j = 0;
    for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
      if( pRow->zBranch==zLeft && aMap[pRow->iRail]>=j ){
        for(i=0; i<=p->mxRail; i++){
          if( aMap[i]>=j && aMap[i]<=pRow->iRail ) aMap[i]++;
        }
        aMap[pRow->iRail] = j++;
      }
    }
    cgi_printf("<!-- aiRailMap =");
    for(i=0; i<=p->mxRail; i++) cgi_printf(" %d", aMap[i]);
    cgi_printf(" -->\n");
  }

  p->nErr = 0;
}