Fossil

Check-in [5399c5da]
Login

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

Overview
Comment:Fix to the graph layout for complex time-warp cases. Add tooltips to timewarp arrows.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 5399c5dacb808e4cc5ec5a76fd4d8a4823d96f0b1a21d692d9c06522839c3ad3
User & Date: drh 2019-06-08 16:11:00
Context
2019-06-08
18:29
Improved handling of timewarps in the graph layout. check-in: 628fc32d user: drh tags: trunk
16:11
Fix to the graph layout for complex time-warp cases. Add tooltips to timewarp arrows. check-in: 5399c5da user: drh tags: trunk
14:48
Improvements to tooltip behavior in an effort to make it easier to move the mouse over to the "copy button" or to the hyperlink without the tooltip changing out from under the user. check-in: 55f56e91 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/graph.c.

276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
...
305
306
307
308
309
310
311

312
313
314
315
316
317
318
...
641
642
643
644
645
646
647


648
649






650
651
652
653
654
655
656
    inUseMask |= pRow->railInUse;
    pRow = pRow->pNext;
  }
  for(i=0; i<GR_MAX_RAIL; i++){
    if( (inUseMask & BIT(i))==0 ){
      int dist;
      if( iNearto<=0 ){
        return i;

      }
      dist = i - iNearto;
      if( dist<0 ) dist = -dist;
      if( dist<iBestDist ){
        iBestDist = dist;
        iBest = i;
      }
................................................................................
  u64 mask = ((u64)1)<<iRail;

  pBottom->railInUse |= mask;
  pPrior = pBottom;
  for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
    assert( pPrior->idx > pCurrent->idx );
    assert( pCurrent->iRail<0 );

    pCurrent->iRail = iRail;
    pCurrent->railInUse |= mask;
    pPrior->aiRiser[iRail] = pCurrent->idx;
    while( pPrior->idx > pCurrent->idx ){
      pPrior->railInUse |= mask;
      pPrior = pPrior->pPrev;
      assert( pPrior!=0 );
................................................................................
    pRow->railInUse |= mask;
    if( pRow->pChild ){
      assignChildrenToRail(pRow, tmFlags);
    }else if( !omitDescenders && count_nonbranch_children(pRow->rid)!=0 ){
      if( !pRow->timeWarp ) riser_to_top(pRow);
    }
    if( pParent ){


      for(pLoop=pParent->pPrev; pLoop && pLoop!=pRow; pLoop=pLoop->pPrev){
        pLoop->railInUse |= mask;






      }
    }
  }

  /*
  ** Insert merge rails and merge arrows
  */







|
>







 







>







 







>
>
|
|
>
>
>
>
>
>







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
...
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
    inUseMask |= pRow->railInUse;
    pRow = pRow->pNext;
  }
  for(i=0; i<GR_MAX_RAIL; i++){
    if( (inUseMask & BIT(i))==0 ){
      int dist;
      if( iNearto<=0 ){
        iBest = i;
        break;
      }
      dist = i - iNearto;
      if( dist<0 ) dist = -dist;
      if( dist<iBestDist ){
        iBestDist = dist;
        iBest = i;
      }
................................................................................
  u64 mask = ((u64)1)<<iRail;

  pBottom->railInUse |= mask;
  pPrior = pBottom;
  for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
    assert( pPrior->idx > pCurrent->idx );
    assert( pCurrent->iRail<0 );
    if( pPrior->timeWarp ) break;
    pCurrent->iRail = iRail;
    pCurrent->railInUse |= mask;
    pPrior->aiRiser[iRail] = pCurrent->idx;
    while( pPrior->idx > pCurrent->idx ){
      pPrior->railInUse |= mask;
      pPrior = pPrior->pPrev;
      assert( pPrior!=0 );
................................................................................
    pRow->railInUse |= mask;
    if( pRow->pChild ){
      assignChildrenToRail(pRow, tmFlags);
    }else if( !omitDescenders && count_nonbranch_children(pRow->rid)!=0 ){
      if( !pRow->timeWarp ) riser_to_top(pRow);
    }
    if( pParent ){
      if( pParent->idx>pRow->idx ){
        /* Common case:  Parent is below current row in the graph */
        for(pLoop=pParent->pPrev; pLoop && pLoop!=pRow; pLoop=pLoop->pPrev){
          pLoop->railInUse |= mask;
        }
      }else{
        /* Timewarp case: Parent is above current row in the graph */
        for(pLoop=pParent->pNext; pLoop && pLoop!=pRow; pLoop=pLoop->pNext){
          pLoop->railInUse |= mask;
        }
      }
    }
  }

  /*
  ** Insert merge rails and merge arrows
  */

Changes to src/graph.js.

483
484
485
486
487
488
489

490
491
492

493
494

495

496

497
498
499

500
501
502
503
504
505
506
        if( x0<x1 ){
          x0 = Math.ceil(x0);
          x1 += line.w;
        }
        var y0 = p.y + (node.h-line.w)/2;
        var u = tx.rowinfo[p.au[i+1]-tx.iTopRow];
        if( u.id<p.id ){

          drawLine(line,u.fg,x0,y0,x1,null);
          drawUpArrow(p,u,u.fg,u.id);
        }else{

          var y1 = u.y + (node.h-line.w)/2;
          drawLine(wLine,u.fg,x0,y0,x1,null);

          drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w);

          drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null);

          var x = u.x-wArrow.w;
          var y = u.y+(node.h-wArrow.h)/2;
          var n = drawBox(wArrow.cls,null,x,y);

          if( u.fg ) n.style.borderLeftColor = u.fg;
        }
      }
    }
    if( p.hasOwnProperty('mi') ){
      for( var i=0; i<p.mi.length; i++ ){
        var rail = p.mi[i];







>



>

|
>
|
>
|
>


|
>







483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
        if( x0<x1 ){
          x0 = Math.ceil(x0);
          x1 += line.w;
        }
        var y0 = p.y + (node.h-line.w)/2;
        var u = tx.rowinfo[p.au[i+1]-tx.iTopRow];
        if( u.id<p.id ){
          // normal thick up-arrow
          drawLine(line,u.fg,x0,y0,x1,null);
          drawUpArrow(p,u,u.fg,u.id);
        }else{
          // timewarp:  The child node occurs before the parent
          var y1 = u.y + (node.h-line.w)/2;
          var n = drawLine(wLine,u.fg,x0,y0,x1,null);
          addToolTip(n,u.id)
          n = drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w);
          addToolTip(n,u.id)
          n = drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null);
          addToolTip(n,u.id)
          var x = u.x-wArrow.w;
          var y = u.y+(node.h-wArrow.h)/2;
          n = drawBox(wArrow.cls,null,x,y);
          addToolTip(n,u.id)
          if( u.fg ) n.style.borderLeftColor = u.fg;
        }
      }
    }
    if( p.hasOwnProperty('mi') ){
      for( var i=0; i<p.mi.length; i++ ){
        var rail = p.mi[i];