Fossil SCM
Omit unused elements of the "rowinfo" JSON element used to generate a timeline graph.
Commit
c0a5083edaa3bc6bd8d132ef6dc2c8c27ad2a6cc03c1eca0c0f2f5c76d8852c4
Parent
a07f16888183312…
2 files changed
+40
-36
+34
-19
+40
-36
| --- src/graph.js | ||
| +++ src/graph.js | ||
| @@ -21,11 +21,11 @@ | ||
| 21 | 21 | ** The rowinfo field is an array of structures, one per entry in the timeline, |
| 22 | 22 | ** where each structure has the following fields: |
| 23 | 23 | ** |
| 24 | 24 | ** id: The id of the <div> element for the row. This is an integer. |
| 25 | 25 | ** to get an actual id, prepend "m" to the integer. The top node |
| 26 | -** is iTopRow and numbers increase moving down the tx. | |
| 26 | +** is iTopRow and numbers increase moving down the graph. | |
| 27 | 27 | ** bg: The background color for this row |
| 28 | 28 | ** r: The "rail" that the node for this row sits on. The left-most |
| 29 | 29 | ** rail is 0 and the number increases to the right. |
| 30 | 30 | ** d: True if there is a "descender" - an arrow coming from the bottom |
| 31 | 31 | ** of the page straight up to this node. |
| @@ -215,19 +215,19 @@ | ||
| 215 | 215 | if(e) e.style.backgroundColor = p.bg; |
| 216 | 216 | } |
| 217 | 217 | if( p.r<0 ) return; |
| 218 | 218 | if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg); |
| 219 | 219 | var cls = node.cls; |
| 220 | - if( p.mi.length ) cls += " merge"; | |
| 220 | + if( p.hasOwnProperty('mi') && p.mi.length ) cls += " merge"; | |
| 221 | 221 | if( p.f&1 ) cls += " leaf"; |
| 222 | 222 | var n = drawBox(cls,p.bg,p.x,p.y); |
| 223 | 223 | n.id = "tln"+p.id; |
| 224 | 224 | n.onclick = clickOnNode; |
| 225 | 225 | n.style.zIndex = 10; |
| 226 | 226 | if( !tx.omitDescenders ){ |
| 227 | 227 | if( p.u==0 ) drawUpArrow(p,{x: p.x, y: -node.h},p.fg); |
| 228 | - if( p.d ) drawUpArrow({x: p.x, y: btm-node.h/2},p,p.fg); | |
| 228 | + if( p.hasOwnProperty('d') ) drawUpArrow({x: p.x, y: btm-node.h/2},p,p.fg); | |
| 229 | 229 | } |
| 230 | 230 | if( p.mo>=0 ){ |
| 231 | 231 | var x0 = p.x + node.w/2; |
| 232 | 232 | var x1 = p.mo*railPitch + node.w/2; |
| 233 | 233 | var u = tx.rowinfo[p.mu-tx.iTopRow]; |
| @@ -243,43 +243,47 @@ | ||
| 243 | 243 | drawMergeLine(x1,p.y+node.h/2,null,y1); |
| 244 | 244 | }else{ |
| 245 | 245 | delete mergeLines[p.mo]; |
| 246 | 246 | } |
| 247 | 247 | } |
| 248 | - for( var i=0; i<p.au.length; i+=2 ){ | |
| 249 | - var rail = p.au[i]; | |
| 250 | - var x0 = p.x + node.w/2; | |
| 251 | - var x1 = rail*railPitch + (node.w-line.w)/2; | |
| 252 | - if( x0<x1 ){ | |
| 253 | - x0 = Math.ceil(x0); | |
| 254 | - x1 += line.w; | |
| 255 | - } | |
| 256 | - var y0 = p.y + (node.h-line.w)/2; | |
| 257 | - var u = tx.rowinfo[p.au[i+1]-tx.iTopRow]; | |
| 258 | - if( u.id<p.id ){ | |
| 259 | - drawLine(line,u.fg,x0,y0,x1,null); | |
| 260 | - drawUpArrow(p,u,u.fg); | |
| 261 | - }else{ | |
| 262 | - var y1 = u.y + (node.h-line.w)/2; | |
| 263 | - drawLine(wLine,u.fg,x0,y0,x1,null); | |
| 264 | - drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w); | |
| 265 | - drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null); | |
| 266 | - var x = u.x-wArrow.w; | |
| 267 | - var y = u.y+(node.h-wArrow.h)/2; | |
| 268 | - var n = drawBox(wArrow.cls,null,x,y); | |
| 269 | - if( u.fg ) n.style.borderLeftColor = u.fg; | |
| 270 | - } | |
| 271 | - } | |
| 272 | - for( var i=0; i<p.mi.length; i++ ){ | |
| 273 | - var rail = p.mi[i]; | |
| 274 | - if( rail<0 ){ | |
| 275 | - rail = -rail; | |
| 276 | - mergeLines[rail] = -mLine.w/2; | |
| 277 | - var x = rail*railPitch + (node.w-mLine.w)/2; | |
| 278 | - drawMergeLine(x,miLineY(p),null,btm); | |
| 279 | - } | |
| 280 | - drawMergeArrow(p,rail); | |
| 248 | + if( p.hasOwnProperty('au') ){ | |
| 249 | + for( var i=0; i<p.au.length; i+=2 ){ | |
| 250 | + var rail = p.au[i]; | |
| 251 | + var x0 = p.x + node.w/2; | |
| 252 | + var x1 = rail*railPitch + (node.w-line.w)/2; | |
| 253 | + if( x0<x1 ){ | |
| 254 | + x0 = Math.ceil(x0); | |
| 255 | + x1 += line.w; | |
| 256 | + } | |
| 257 | + var y0 = p.y + (node.h-line.w)/2; | |
| 258 | + var u = tx.rowinfo[p.au[i+1]-tx.iTopRow]; | |
| 259 | + if( u.id<p.id ){ | |
| 260 | + drawLine(line,u.fg,x0,y0,x1,null); | |
| 261 | + drawUpArrow(p,u,u.fg); | |
| 262 | + }else{ | |
| 263 | + var y1 = u.y + (node.h-line.w)/2; | |
| 264 | + drawLine(wLine,u.fg,x0,y0,x1,null); | |
| 265 | + drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w); | |
| 266 | + drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null); | |
| 267 | + var x = u.x-wArrow.w; | |
| 268 | + var y = u.y+(node.h-wArrow.h)/2; | |
| 269 | + var n = drawBox(wArrow.cls,null,x,y); | |
| 270 | + if( u.fg ) n.style.borderLeftColor = u.fg; | |
| 271 | + } | |
| 272 | + } | |
| 273 | + } | |
| 274 | + if( p.hasOwnProperty('mi') ){ | |
| 275 | + for( var i=0; i<p.mi.length; i++ ){ | |
| 276 | + var rail = p.mi[i]; | |
| 277 | + if( rail<0 ){ | |
| 278 | + rail = -rail; | |
| 279 | + mergeLines[rail] = -mLine.w/2; | |
| 280 | + var x = rail*railPitch + (node.w-mLine.w)/2; | |
| 281 | + drawMergeLine(x,miLineY(p),null,btm); | |
| 282 | + } | |
| 283 | + drawMergeArrow(p,rail); | |
| 284 | + } | |
| 281 | 285 | } |
| 282 | 286 | } |
| 283 | 287 | var mergeLines; |
| 284 | 288 | function renderGraph(){ |
| 285 | 289 | mergeLines = {}; |
| 286 | 290 |
| --- src/graph.js | |
| +++ src/graph.js | |
| @@ -21,11 +21,11 @@ | |
| 21 | ** The rowinfo field is an array of structures, one per entry in the timeline, |
| 22 | ** where each structure has the following fields: |
| 23 | ** |
| 24 | ** id: The id of the <div> element for the row. This is an integer. |
| 25 | ** to get an actual id, prepend "m" to the integer. The top node |
| 26 | ** is iTopRow and numbers increase moving down the tx. |
| 27 | ** bg: The background color for this row |
| 28 | ** r: The "rail" that the node for this row sits on. The left-most |
| 29 | ** rail is 0 and the number increases to the right. |
| 30 | ** d: True if there is a "descender" - an arrow coming from the bottom |
| 31 | ** of the page straight up to this node. |
| @@ -215,19 +215,19 @@ | |
| 215 | if(e) e.style.backgroundColor = p.bg; |
| 216 | } |
| 217 | if( p.r<0 ) return; |
| 218 | if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg); |
| 219 | var cls = node.cls; |
| 220 | if( p.mi.length ) cls += " merge"; |
| 221 | if( p.f&1 ) cls += " leaf"; |
| 222 | var n = drawBox(cls,p.bg,p.x,p.y); |
| 223 | n.id = "tln"+p.id; |
| 224 | n.onclick = clickOnNode; |
| 225 | n.style.zIndex = 10; |
| 226 | if( !tx.omitDescenders ){ |
| 227 | if( p.u==0 ) drawUpArrow(p,{x: p.x, y: -node.h},p.fg); |
| 228 | if( p.d ) drawUpArrow({x: p.x, y: btm-node.h/2},p,p.fg); |
| 229 | } |
| 230 | if( p.mo>=0 ){ |
| 231 | var x0 = p.x + node.w/2; |
| 232 | var x1 = p.mo*railPitch + node.w/2; |
| 233 | var u = tx.rowinfo[p.mu-tx.iTopRow]; |
| @@ -243,43 +243,47 @@ | |
| 243 | drawMergeLine(x1,p.y+node.h/2,null,y1); |
| 244 | }else{ |
| 245 | delete mergeLines[p.mo]; |
| 246 | } |
| 247 | } |
| 248 | for( var i=0; i<p.au.length; i+=2 ){ |
| 249 | var rail = p.au[i]; |
| 250 | var x0 = p.x + node.w/2; |
| 251 | var x1 = rail*railPitch + (node.w-line.w)/2; |
| 252 | if( x0<x1 ){ |
| 253 | x0 = Math.ceil(x0); |
| 254 | x1 += line.w; |
| 255 | } |
| 256 | var y0 = p.y + (node.h-line.w)/2; |
| 257 | var u = tx.rowinfo[p.au[i+1]-tx.iTopRow]; |
| 258 | if( u.id<p.id ){ |
| 259 | drawLine(line,u.fg,x0,y0,x1,null); |
| 260 | drawUpArrow(p,u,u.fg); |
| 261 | }else{ |
| 262 | var y1 = u.y + (node.h-line.w)/2; |
| 263 | drawLine(wLine,u.fg,x0,y0,x1,null); |
| 264 | drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w); |
| 265 | drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null); |
| 266 | var x = u.x-wArrow.w; |
| 267 | var y = u.y+(node.h-wArrow.h)/2; |
| 268 | var n = drawBox(wArrow.cls,null,x,y); |
| 269 | if( u.fg ) n.style.borderLeftColor = u.fg; |
| 270 | } |
| 271 | } |
| 272 | for( var i=0; i<p.mi.length; i++ ){ |
| 273 | var rail = p.mi[i]; |
| 274 | if( rail<0 ){ |
| 275 | rail = -rail; |
| 276 | mergeLines[rail] = -mLine.w/2; |
| 277 | var x = rail*railPitch + (node.w-mLine.w)/2; |
| 278 | drawMergeLine(x,miLineY(p),null,btm); |
| 279 | } |
| 280 | drawMergeArrow(p,rail); |
| 281 | } |
| 282 | } |
| 283 | var mergeLines; |
| 284 | function renderGraph(){ |
| 285 | mergeLines = {}; |
| 286 |
| --- src/graph.js | |
| +++ src/graph.js | |
| @@ -21,11 +21,11 @@ | |
| 21 | ** The rowinfo field is an array of structures, one per entry in the timeline, |
| 22 | ** where each structure has the following fields: |
| 23 | ** |
| 24 | ** id: The id of the <div> element for the row. This is an integer. |
| 25 | ** to get an actual id, prepend "m" to the integer. The top node |
| 26 | ** is iTopRow and numbers increase moving down the graph. |
| 27 | ** bg: The background color for this row |
| 28 | ** r: The "rail" that the node for this row sits on. The left-most |
| 29 | ** rail is 0 and the number increases to the right. |
| 30 | ** d: True if there is a "descender" - an arrow coming from the bottom |
| 31 | ** of the page straight up to this node. |
| @@ -215,19 +215,19 @@ | |
| 215 | if(e) e.style.backgroundColor = p.bg; |
| 216 | } |
| 217 | if( p.r<0 ) return; |
| 218 | if( p.u>0 ) drawUpArrow(p,tx.rowinfo[p.u-tx.iTopRow],p.fg); |
| 219 | var cls = node.cls; |
| 220 | if( p.hasOwnProperty('mi') && p.mi.length ) cls += " merge"; |
| 221 | if( p.f&1 ) cls += " leaf"; |
| 222 | var n = drawBox(cls,p.bg,p.x,p.y); |
| 223 | n.id = "tln"+p.id; |
| 224 | n.onclick = clickOnNode; |
| 225 | n.style.zIndex = 10; |
| 226 | if( !tx.omitDescenders ){ |
| 227 | if( p.u==0 ) drawUpArrow(p,{x: p.x, y: -node.h},p.fg); |
| 228 | if( p.hasOwnProperty('d') ) drawUpArrow({x: p.x, y: btm-node.h/2},p,p.fg); |
| 229 | } |
| 230 | if( p.mo>=0 ){ |
| 231 | var x0 = p.x + node.w/2; |
| 232 | var x1 = p.mo*railPitch + node.w/2; |
| 233 | var u = tx.rowinfo[p.mu-tx.iTopRow]; |
| @@ -243,43 +243,47 @@ | |
| 243 | drawMergeLine(x1,p.y+node.h/2,null,y1); |
| 244 | }else{ |
| 245 | delete mergeLines[p.mo]; |
| 246 | } |
| 247 | } |
| 248 | if( p.hasOwnProperty('au') ){ |
| 249 | for( var i=0; i<p.au.length; i+=2 ){ |
| 250 | var rail = p.au[i]; |
| 251 | var x0 = p.x + node.w/2; |
| 252 | var x1 = rail*railPitch + (node.w-line.w)/2; |
| 253 | if( x0<x1 ){ |
| 254 | x0 = Math.ceil(x0); |
| 255 | x1 += line.w; |
| 256 | } |
| 257 | var y0 = p.y + (node.h-line.w)/2; |
| 258 | var u = tx.rowinfo[p.au[i+1]-tx.iTopRow]; |
| 259 | if( u.id<p.id ){ |
| 260 | drawLine(line,u.fg,x0,y0,x1,null); |
| 261 | drawUpArrow(p,u,u.fg); |
| 262 | }else{ |
| 263 | var y1 = u.y + (node.h-line.w)/2; |
| 264 | drawLine(wLine,u.fg,x0,y0,x1,null); |
| 265 | drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w); |
| 266 | drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null); |
| 267 | var x = u.x-wArrow.w; |
| 268 | var y = u.y+(node.h-wArrow.h)/2; |
| 269 | var n = drawBox(wArrow.cls,null,x,y); |
| 270 | if( u.fg ) n.style.borderLeftColor = u.fg; |
| 271 | } |
| 272 | } |
| 273 | } |
| 274 | if( p.hasOwnProperty('mi') ){ |
| 275 | for( var i=0; i<p.mi.length; i++ ){ |
| 276 | var rail = p.mi[i]; |
| 277 | if( rail<0 ){ |
| 278 | rail = -rail; |
| 279 | mergeLines[rail] = -mLine.w/2; |
| 280 | var x = rail*railPitch + (node.w-mLine.w)/2; |
| 281 | drawMergeLine(x,miLineY(p),null,btm); |
| 282 | } |
| 283 | drawMergeArrow(p,rail); |
| 284 | } |
| 285 | } |
| 286 | } |
| 287 | var mergeLines; |
| 288 | function renderGraph(){ |
| 289 | mergeLines = {}; |
| 290 |
+34
-19
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -861,68 +861,83 @@ | ||
| 861 | 861 | ** to get an actual id, prepend "m" to the integer. The top node |
| 862 | 862 | ** is iTopRow and numbers increase moving down the timeline. |
| 863 | 863 | ** bg: The background color for this row |
| 864 | 864 | ** r: The "rail" that the node for this row sits on. The left-most |
| 865 | 865 | ** rail is 0 and the number increases to the right. |
| 866 | - ** d: True if there is a "descender" - an arrow coming from the bottom | |
| 867 | - ** of the page straight up to this node. | |
| 868 | - ** mo: "merge-out". If non-negative, this is the rail position | |
| 866 | + ** d: If exists and true then there is a "descender" - an arrow | |
| 867 | + ** coming from the bottom of the page straight up to this node. | |
| 868 | + ** mo: "merge-out". If it exists, this is the rail position | |
| 869 | 869 | ** for the upward portion of a merge arrow. The merge arrow goes up |
| 870 | - ** to the row identified by mu:. If this value is negative then | |
| 870 | + ** to the row identified by mu:. If this value is omitted then | |
| 871 | 871 | ** node has no merge children and no merge-out line is drawn. |
| 872 | 872 | ** mu: The id of the row which is the top of the merge-out arrow. |
| 873 | + ** Only exists if "mo" exists. | |
| 873 | 874 | ** u: Draw a thick child-line out of the top of this node and up to |
| 874 | 875 | ** the node with an id equal to this value. 0 if it is straight to |
| 875 | 876 | ** the top of the page, -1 if there is no thick-line riser. |
| 876 | 877 | ** f: 0x01: a leaf node. |
| 877 | 878 | ** au: An array of integers that define thick-line risers for branches. |
| 878 | 879 | ** The integers are in pairs. For each pair, the first integer is |
| 879 | 880 | ** is the rail on which the riser should run and the second integer |
| 880 | - ** is the id of the node upto which the riser should run. | |
| 881 | + ** is the id of the node upto which the riser should run. If there | |
| 882 | + ** are no risers, this array does not exist. | |
| 881 | 883 | ** mi: "merge-in". An array of integer rail positions from which |
| 882 | 884 | ** merge arrows should be drawn into this node. If the value is |
| 883 | 885 | ** negative, then the rail position is the absolute value of mi[] |
| 884 | 886 | ** and a thin merge-arrow descender is drawn to the bottom of |
| 885 | - ** the screen. | |
| 887 | + ** the screen. This array is omitted if there are no inbound | |
| 888 | + ** merges. | |
| 886 | 889 | ** h: The artifact hash of the object being graphed |
| 887 | 890 | */ |
| 888 | 891 | for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){ |
| 892 | + int k = 0; | |
| 889 | 893 | cgi_printf("{\"id\":%d,", pRow->idx); |
| 890 | 894 | cgi_printf("\"bg\":\"%s\",", pRow->zBgClr); |
| 891 | 895 | cgi_printf("\"r\":%d,", pRow->iRail); |
| 892 | - cgi_printf("\"d\":%d,", pRow->bDescender); | |
| 893 | - cgi_printf("\"mo\":%d,", pRow->mergeOut); | |
| 894 | - cgi_printf("\"mu\":%d,", pRow->mergeUpto); | |
| 896 | + if( pRow->bDescender ){ | |
| 897 | + cgi_printf("\"d\":%d,", pRow->bDescender); | |
| 898 | + } | |
| 899 | + if( pRow->mergeOut>=0 ){ | |
| 900 | + cgi_printf("\"mo\":%d,", pRow->mergeOut); | |
| 901 | + cgi_printf("\"mu\":%d,", pRow->mergeUpto); | |
| 902 | + } | |
| 895 | 903 | cgi_printf("\"u\":%d,", pRow->aiRiser[pRow->iRail]); |
| 896 | 904 | cgi_printf("\"f\":%d,", pRow->isLeaf ? 1 : 0); |
| 897 | - cgi_printf("\"au\":"); | |
| 898 | - cSep = '['; | |
| 899 | - for(i=0; i<GR_MAX_RAIL; i++){ | |
| 905 | + for(i=k=0; i<GR_MAX_RAIL; i++){ | |
| 900 | 906 | if( i==pRow->iRail ) continue; |
| 901 | 907 | if( pRow->aiRiser[i]>0 ){ |
| 908 | + if( k==0 ){ | |
| 909 | + cgi_printf("\"au\":"); | |
| 910 | + cSep = '['; | |
| 911 | + } | |
| 912 | + k++; | |
| 902 | 913 | cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]); |
| 903 | 914 | cSep = ','; |
| 904 | 915 | } |
| 905 | 916 | } |
| 906 | - if( cSep=='[' ) cgi_printf("["); | |
| 907 | - cgi_printf("],"); | |
| 917 | + if( k ){ | |
| 918 | + cgi_printf("],"); | |
| 919 | + } | |
| 908 | 920 | if( colorGraph && pRow->zBgClr[0]=='#' ){ |
| 909 | 921 | cgi_printf("\"fg\":\"%s\",", bg_to_fg(pRow->zBgClr)); |
| 910 | 922 | } |
| 911 | 923 | /* mi */ |
| 912 | - cgi_printf("\"mi\":"); | |
| 913 | - cSep = '['; | |
| 914 | - for(i=0; i<GR_MAX_RAIL; i++){ | |
| 924 | + for(i=k=0; i<GR_MAX_RAIL; i++){ | |
| 915 | 925 | if( pRow->mergeIn[i] ){ |
| 916 | 926 | int mi = i; |
| 917 | 927 | if( (pRow->mergeDown >> i) & 1 ) mi = -mi; |
| 928 | + if( k==0 ){ | |
| 929 | + cgi_printf("\"mi\":"); | |
| 930 | + cSep = '['; | |
| 931 | + } | |
| 932 | + k++; | |
| 918 | 933 | cgi_printf("%c%d", cSep, mi); |
| 919 | 934 | cSep = ','; |
| 920 | 935 | } |
| 921 | 936 | } |
| 922 | - if( cSep=='[' ) cgi_printf("["); | |
| 923 | - cgi_printf("],\"h\":\"%!S\"}%s", | |
| 937 | + if( k ) cgi_printf("],"); | |
| 938 | + cgi_printf("\"h\":\"%!S\"}%s", | |
| 924 | 939 | pRow->zUuid, pRow->pNext ? ",\n" : "]\n"); |
| 925 | 940 | } |
| 926 | 941 | @ }</script> |
| 927 | 942 | style_graph_generator(); |
| 928 | 943 | graph_free(pGraph); |
| 929 | 944 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -861,68 +861,83 @@ | |
| 861 | ** to get an actual id, prepend "m" to the integer. The top node |
| 862 | ** is iTopRow and numbers increase moving down the timeline. |
| 863 | ** bg: The background color for this row |
| 864 | ** r: The "rail" that the node for this row sits on. The left-most |
| 865 | ** rail is 0 and the number increases to the right. |
| 866 | ** d: True if there is a "descender" - an arrow coming from the bottom |
| 867 | ** of the page straight up to this node. |
| 868 | ** mo: "merge-out". If non-negative, this is the rail position |
| 869 | ** for the upward portion of a merge arrow. The merge arrow goes up |
| 870 | ** to the row identified by mu:. If this value is negative then |
| 871 | ** node has no merge children and no merge-out line is drawn. |
| 872 | ** mu: The id of the row which is the top of the merge-out arrow. |
| 873 | ** u: Draw a thick child-line out of the top of this node and up to |
| 874 | ** the node with an id equal to this value. 0 if it is straight to |
| 875 | ** the top of the page, -1 if there is no thick-line riser. |
| 876 | ** f: 0x01: a leaf node. |
| 877 | ** au: An array of integers that define thick-line risers for branches. |
| 878 | ** The integers are in pairs. For each pair, the first integer is |
| 879 | ** is the rail on which the riser should run and the second integer |
| 880 | ** is the id of the node upto which the riser should run. |
| 881 | ** mi: "merge-in". An array of integer rail positions from which |
| 882 | ** merge arrows should be drawn into this node. If the value is |
| 883 | ** negative, then the rail position is the absolute value of mi[] |
| 884 | ** and a thin merge-arrow descender is drawn to the bottom of |
| 885 | ** the screen. |
| 886 | ** h: The artifact hash of the object being graphed |
| 887 | */ |
| 888 | for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){ |
| 889 | cgi_printf("{\"id\":%d,", pRow->idx); |
| 890 | cgi_printf("\"bg\":\"%s\",", pRow->zBgClr); |
| 891 | cgi_printf("\"r\":%d,", pRow->iRail); |
| 892 | cgi_printf("\"d\":%d,", pRow->bDescender); |
| 893 | cgi_printf("\"mo\":%d,", pRow->mergeOut); |
| 894 | cgi_printf("\"mu\":%d,", pRow->mergeUpto); |
| 895 | cgi_printf("\"u\":%d,", pRow->aiRiser[pRow->iRail]); |
| 896 | cgi_printf("\"f\":%d,", pRow->isLeaf ? 1 : 0); |
| 897 | cgi_printf("\"au\":"); |
| 898 | cSep = '['; |
| 899 | for(i=0; i<GR_MAX_RAIL; i++){ |
| 900 | if( i==pRow->iRail ) continue; |
| 901 | if( pRow->aiRiser[i]>0 ){ |
| 902 | cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]); |
| 903 | cSep = ','; |
| 904 | } |
| 905 | } |
| 906 | if( cSep=='[' ) cgi_printf("["); |
| 907 | cgi_printf("],"); |
| 908 | if( colorGraph && pRow->zBgClr[0]=='#' ){ |
| 909 | cgi_printf("\"fg\":\"%s\",", bg_to_fg(pRow->zBgClr)); |
| 910 | } |
| 911 | /* mi */ |
| 912 | cgi_printf("\"mi\":"); |
| 913 | cSep = '['; |
| 914 | for(i=0; i<GR_MAX_RAIL; i++){ |
| 915 | if( pRow->mergeIn[i] ){ |
| 916 | int mi = i; |
| 917 | if( (pRow->mergeDown >> i) & 1 ) mi = -mi; |
| 918 | cgi_printf("%c%d", cSep, mi); |
| 919 | cSep = ','; |
| 920 | } |
| 921 | } |
| 922 | if( cSep=='[' ) cgi_printf("["); |
| 923 | cgi_printf("],\"h\":\"%!S\"}%s", |
| 924 | pRow->zUuid, pRow->pNext ? ",\n" : "]\n"); |
| 925 | } |
| 926 | @ }</script> |
| 927 | style_graph_generator(); |
| 928 | graph_free(pGraph); |
| 929 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -861,68 +861,83 @@ | |
| 861 | ** to get an actual id, prepend "m" to the integer. The top node |
| 862 | ** is iTopRow and numbers increase moving down the timeline. |
| 863 | ** bg: The background color for this row |
| 864 | ** r: The "rail" that the node for this row sits on. The left-most |
| 865 | ** rail is 0 and the number increases to the right. |
| 866 | ** d: If exists and true then there is a "descender" - an arrow |
| 867 | ** coming from the bottom of the page straight up to this node. |
| 868 | ** mo: "merge-out". If it exists, this is the rail position |
| 869 | ** for the upward portion of a merge arrow. The merge arrow goes up |
| 870 | ** to the row identified by mu:. If this value is omitted then |
| 871 | ** node has no merge children and no merge-out line is drawn. |
| 872 | ** mu: The id of the row which is the top of the merge-out arrow. |
| 873 | ** Only exists if "mo" exists. |
| 874 | ** u: Draw a thick child-line out of the top of this node and up to |
| 875 | ** the node with an id equal to this value. 0 if it is straight to |
| 876 | ** the top of the page, -1 if there is no thick-line riser. |
| 877 | ** f: 0x01: a leaf node. |
| 878 | ** au: An array of integers that define thick-line risers for branches. |
| 879 | ** The integers are in pairs. For each pair, the first integer is |
| 880 | ** is the rail on which the riser should run and the second integer |
| 881 | ** is the id of the node upto which the riser should run. If there |
| 882 | ** are no risers, this array does not exist. |
| 883 | ** mi: "merge-in". An array of integer rail positions from which |
| 884 | ** merge arrows should be drawn into this node. If the value is |
| 885 | ** negative, then the rail position is the absolute value of mi[] |
| 886 | ** and a thin merge-arrow descender is drawn to the bottom of |
| 887 | ** the screen. This array is omitted if there are no inbound |
| 888 | ** merges. |
| 889 | ** h: The artifact hash of the object being graphed |
| 890 | */ |
| 891 | for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){ |
| 892 | int k = 0; |
| 893 | cgi_printf("{\"id\":%d,", pRow->idx); |
| 894 | cgi_printf("\"bg\":\"%s\",", pRow->zBgClr); |
| 895 | cgi_printf("\"r\":%d,", pRow->iRail); |
| 896 | if( pRow->bDescender ){ |
| 897 | cgi_printf("\"d\":%d,", pRow->bDescender); |
| 898 | } |
| 899 | if( pRow->mergeOut>=0 ){ |
| 900 | cgi_printf("\"mo\":%d,", pRow->mergeOut); |
| 901 | cgi_printf("\"mu\":%d,", pRow->mergeUpto); |
| 902 | } |
| 903 | cgi_printf("\"u\":%d,", pRow->aiRiser[pRow->iRail]); |
| 904 | cgi_printf("\"f\":%d,", pRow->isLeaf ? 1 : 0); |
| 905 | for(i=k=0; i<GR_MAX_RAIL; i++){ |
| 906 | if( i==pRow->iRail ) continue; |
| 907 | if( pRow->aiRiser[i]>0 ){ |
| 908 | if( k==0 ){ |
| 909 | cgi_printf("\"au\":"); |
| 910 | cSep = '['; |
| 911 | } |
| 912 | k++; |
| 913 | cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]); |
| 914 | cSep = ','; |
| 915 | } |
| 916 | } |
| 917 | if( k ){ |
| 918 | cgi_printf("],"); |
| 919 | } |
| 920 | if( colorGraph && pRow->zBgClr[0]=='#' ){ |
| 921 | cgi_printf("\"fg\":\"%s\",", bg_to_fg(pRow->zBgClr)); |
| 922 | } |
| 923 | /* mi */ |
| 924 | for(i=k=0; i<GR_MAX_RAIL; i++){ |
| 925 | if( pRow->mergeIn[i] ){ |
| 926 | int mi = i; |
| 927 | if( (pRow->mergeDown >> i) & 1 ) mi = -mi; |
| 928 | if( k==0 ){ |
| 929 | cgi_printf("\"mi\":"); |
| 930 | cSep = '['; |
| 931 | } |
| 932 | k++; |
| 933 | cgi_printf("%c%d", cSep, mi); |
| 934 | cSep = ','; |
| 935 | } |
| 936 | } |
| 937 | if( k ) cgi_printf("],"); |
| 938 | cgi_printf("\"h\":\"%!S\"}%s", |
| 939 | pRow->zUuid, pRow->pNext ? ",\n" : "]\n"); |
| 940 | } |
| 941 | @ }</script> |
| 942 | style_graph_generator(); |
| 943 | graph_free(pGraph); |
| 944 |