Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Improvements to the display of the "Context" graph on check-in /info pages. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
01d8bf97e206fc8eeae4c59e6046a9ae |
| User & Date: | drh 2019-05-14 13:47:21.296 |
Context
|
2019-05-14
| ||
| 14:33 | The dotted vertical lines in the graph should use the default color, not the foreground color of the node. ... (check-in: 47b080876b user: drh tags: trunk) | |
| 13:47 | Improvements to the display of the "Context" graph on check-in /info pages. ... (check-in: 01d8bf97e2 user: drh tags: trunk) | |
| 13:46 | Fix the graph on the /finfo page - apparently broken by check-in [8e2b8b027bc2d62a1]. ... (check-in: aa149371ed user: drh tags: trunk) | |
Changes
Changes to src/default_css.txt.
| ︙ | ︙ | |||
187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
margin-left: 1px;
border-width: 3px 0;
border-left: 7px solid #600000;
}
.tl-line.warp {
background: #600000;
}
span.tagDsp {
font-weight: bold;
}
span.wikiError {
font-weight: bold;
color: red;
}
| > > > > > > | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
margin-left: 1px;
border-width: 3px 0;
border-left: 7px solid #600000;
}
.tl-line.warp {
background: #600000;
}
.tl-line.dotted {
width: 0px;
border-top: 0px dotted #888;
border-left: 2px dotted #888;
background: rgba(255,255,255,0);
}
span.tagDsp {
font-weight: bold;
}
span.wikiError {
font-weight: bold;
color: red;
}
|
| ︙ | ︙ |
Changes to src/graph.c.
| ︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
GraphRow *pPrev; /* Previous row */
int idx; /* Row index. First is 1. 0 used for "none" */
int idxTop; /* Direct descendent highest up on the graph */
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 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 */
u64 cherrypickDown; /* Draw cherrypick lines up from bottom */
u64 railInUse; /* Mask of occupied rails at this row */
};
/* Context while building a graph
*/
struct GraphContext {
int nErr; /* Number of errors encountered */
int mxRail; /* Number of rails required to render the graph */
| > | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
GraphRow *pPrev; /* Previous row */
int idx; /* Row index. First is 1. 0 used for "none" */
int idxTop; /* Direct descendent highest up on the graph */
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 */
u64 cherrypickDown; /* Draw cherrypick lines up from bottom */
u64 railInUse; /* Mask of occupied rails at this row */
};
/* Context while building a graph
*/
struct GraphContext {
int nErr; /* Number of errors encountered */
int mxRail; /* Number of rails required to render the graph */
GraphRow *pFirst; /* First row in the list. Top row of graph. */
GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
int nBranch; /* Number of distinct branches */
char **azBranch; /* Names of the branches */
int nRow; /* Number of rows */
int nHash; /* Number of slots in apHash[] */
GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
};
|
| ︙ | ︙ | |||
475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
continue; /* Time-warp */
}
if( pRow->idxTop < pParent->idxTop ){
pParent->pChild = pRow;
pParent->idxTop = pRow->idxTop;
}
}
/* Identify rows where the primary parent is off screen. Assign
** each to a rail and draw descenders to the bottom of the screen.
**
** Strive to put the "trunk" branch on far left.
*/
zTrunk = persistBranchName(p, "trunk");
| > > > > > > > > > > > > > > > > > > > > | 476 477 478 479 480 481 482 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 |
continue; /* Time-warp */
}
if( pRow->idxTop < pParent->idxTop ){
pParent->pChild = pRow;
pParent->idxTop = pRow->idxTop;
}
}
/* If a node has no pChild, and there is a later node (a node higher
** up on the graph) in the same branch that has no parent, then make
** the lower node a step-child of the upper node.
*/
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;
}
}
}
/* Identify rows where the primary parent is off screen. Assign
** each to a rail and draw descenders to the bottom of the screen.
**
** Strive to put the "trunk" branch on far left.
*/
zTrunk = persistBranchName(p, "trunk");
|
| ︙ | ︙ |
Changes to src/graph.js.
| ︙ | ︙ | |||
90 91 92 93 94 95 96 |
canvasDiv.style.position = "absolute";
parent.appendChild(canvasDiv);
var elems = {};
var elemClasses = [
"rail", "mergeoffset", "node", "arrow u", "arrow u sm", "line",
"arrow merge r", "line merge", "arrow warp", "line warp",
| | | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
canvasDiv.style.position = "absolute";
parent.appendChild(canvasDiv);
var elems = {};
var elemClasses = [
"rail", "mergeoffset", "node", "arrow u", "arrow u sm", "line",
"arrow merge r", "line merge", "arrow warp", "line warp",
"line cherrypick", "line dotted"
];
for( var i=0; i<elemClasses.length; i++ ){
var cls = elemClasses[i];
var elem = document.createElement("div");
elem.className = "tl-" + cls;
if( cls.indexOf("line")==0 ) elem.className += " v";
canvasDiv.appendChild(elem);
|
| ︙ | ︙ | |||
113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
arrowSmall = elems.arrow_u_sm;
line = elems.line;
mArrow = elems.arrow_merge_r;
mLine = elems.line_merge;
cpLine = elems.line_cherrypick;
wArrow = elems.arrow_warp;
wLine = elems.line_warp;
var minRailPitch = Math.ceil((node.w+line.w)/2 + mArrow.w + 1);
if( window.innerWidth<400 ){
railPitch = minRailPitch;
}else{
if( tx.iRailPitch>0 ){
railPitch = tx.iRailPitch;
| > | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
arrowSmall = elems.arrow_u_sm;
line = elems.line;
mArrow = elems.arrow_merge_r;
mLine = elems.line_merge;
cpLine = elems.line_cherrypick;
wArrow = elems.arrow_warp;
wLine = elems.line_warp;
dotLine = elems.line_dotted;
var minRailPitch = Math.ceil((node.w+line.w)/2 + mArrow.w + 1);
if( window.innerWidth<400 ){
railPitch = minRailPitch;
}else{
if( tx.iRailPitch>0 ){
railPitch = tx.iRailPitch;
|
| ︙ | ︙ | |||
194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
var y0 = from.y + node.h/2;
var y1 = Math.ceil(to.y + node.h + arw.h/2);
drawLine(line,color,x,y0,null,y1);
x = to.x + (node.w-arw.w)/2;
var n = drawBox(arw.cls,null,x,y);
if(color) n.style.borderBottomColor = color;
}
/* Draw thin horizontal or vertical lines representing merges */
function drawMergeLine(x0,y0,x1,y1){
drawLine(mLine,null,x0,y0,x1,y1);
}
function drawCherrypickLine(x0,y0,x1,y1){
drawLine(cpLine,null,x0,y0,x1,y1);
}
| > > > > > > | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
var y0 = from.y + node.h/2;
var y1 = Math.ceil(to.y + node.h + arw.h/2);
drawLine(line,color,x,y0,null,y1);
x = to.x + (node.w-arw.w)/2;
var n = drawBox(arw.cls,null,x,y);
if(color) n.style.borderBottomColor = color;
}
function drawUpDotted(from,to,color){
var x = to.x + (node.w-line.w)/2;
var y0 = from.y + node.h/2;
var y1 = Math.ceil(to.y + node.h);
drawLine(dotLine,color,x,y0,null,y1);
}
/* Draw thin horizontal or vertical lines representing merges */
function drawMergeLine(x0,y0,x1,y1){
drawLine(mLine,null,x0,y0,x1,y1);
}
function drawCherrypickLine(x0,y0,x1,y1){
drawLine(cpLine,null,x0,y0,x1,y1);
}
|
| ︙ | ︙ | |||
234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
var e = document.getElementById("mc"+p.id);
if(e) e.style.backgroundColor = p.bg;
e = document.getElementById("md"+p.id);
if(e) e.style.backgroundColor = p.bg;
}
if( p.r<0 ) return;
if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg);
var cls = node.cls;
if( p.hasOwnProperty('mi') && p.mi.length ) cls += " merge";
if( p.f&1 ) cls += " leaf";
var n = drawBox(cls,p.bg,p.x,p.y);
n.id = "tln"+p.id;
n.onclick = clickOnNode;
n.style.zIndex = 10;
| > | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
var e = document.getElementById("mc"+p.id);
if(e) e.style.backgroundColor = p.bg;
e = document.getElementById("md"+p.id);
if(e) e.style.backgroundColor = p.bg;
}
if( p.r<0 ) return;
if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg);
if( p.sb>0 ) drawUpDotted(p,tx.rowinfo[p.sb-tx.iTopRow],p.fg);
var cls = node.cls;
if( p.hasOwnProperty('mi') && p.mi.length ) cls += " merge";
if( p.f&1 ) cls += " leaf";
var n = drawBox(cls,p.bg,p.x,p.y);
n.id = "tln"+p.id;
n.onclick = clickOnNode;
n.style.zIndex = 10;
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
279 280 281 282 283 284 285 |
rid, rid
);
}
}
blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC");
db_prepare(&q, "%s", blob_sql_text(&sql));
www_print_timeline(&q,
| < | | 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
rid, rid
);
}
}
blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC");
db_prepare(&q, "%s", blob_sql_text(&sql));
www_print_timeline(&q,
TIMELINE_GRAPH
|TIMELINE_NOSCROLL
|TIMELINE_CHPICK,
0, 0, rid, 0);
db_finalize(&q);
}
/*
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
877 878 879 880 881 882 883 884 885 886 887 888 889 890 |
** mu: The id of the row which is the top of the merge-out arrow.
** Only exists if "mo" exists.
** cu: Extend the mu merge arrow up to this row as a cherrypick
** merge line, if this value exists.
** u: Draw a thick child-line out of the top of this node and up to
** the node with an id equal to this value. 0 if it is straight to
** the top of the page, -1 if there is no thick-line riser.
** f: 0x01: a leaf node.
** au: An array of integers that define thick-line risers for branches.
** The integers are in pairs. For each pair, the first integer is
** is the rail on which the riser should run and the second integer
** is the id of the node upto which the riser should run. If there
** are no risers, this array does not exist.
** mi: "merge-in". An array of integer rail positions from which
| > > > > | 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 |
** mu: The id of the row which is the top of the merge-out arrow.
** Only exists if "mo" exists.
** cu: Extend the mu merge arrow up to this row as a cherrypick
** merge line, if this value exists.
** u: Draw a thick child-line out of the top of this node and up to
** the node with an id equal to this value. 0 if it is straight to
** the top of the page, -1 if there is no thick-line riser.
** sb: Draw a dotted child-line out of the top of this node up to the
** node with the id equal to the value. This is like "u" except
** that the line is dotted instead of solid and has no arrow.
** Mnemonic: "Same Branch".
** f: 0x01: a leaf node.
** au: An array of integers that define thick-line risers for branches.
** The integers are in pairs. For each pair, the first integer is
** is the rail on which the riser should run and the second integer
** is the id of the node upto which the riser should run. If there
** are no risers, this array does not exist.
** mi: "merge-in". An array of integer rail positions from which
|
| ︙ | ︙ | |||
909 910 911 912 913 914 915 |
cgi_printf("\"mo\":%d,", pRow->mergeOut);
if( pRow->mergeUpto==0 ) pRow->mergeUpto = pRow->idx;
cgi_printf("\"mu\":%d,", pRow->mergeUpto);
if( pRow->cherrypickUpto>0 && pRow->cherrypickUpto<pRow->mergeUpto ){
cgi_printf("\"cu\":%d,", pRow->cherrypickUpto);
}
}
| > > > | > | 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 |
cgi_printf("\"mo\":%d,", pRow->mergeOut);
if( pRow->mergeUpto==0 ) pRow->mergeUpto = pRow->idx;
cgi_printf("\"mu\":%d,", pRow->mergeUpto);
if( pRow->cherrypickUpto>0 && pRow->cherrypickUpto<pRow->mergeUpto ){
cgi_printf("\"cu\":%d,", pRow->cherrypickUpto);
}
}
if( pRow->isStepParent ){
cgi_printf("\"sb\":%d,", pRow->aiRiser[pRow->iRail]);
}else{
cgi_printf("\"u\":%d,", pRow->aiRiser[pRow->iRail]);
}
k = 0;
if( pRow->isLeaf ) k |= 1;
cgi_printf("\"f\":%d,",k);
for(i=k=0; i<GR_MAX_RAIL; i++){
if( i==pRow->iRail ) continue;
if( pRow->aiRiser[i]>0 ){
if( k==0 ){
|
| ︙ | ︙ |