Last active
November 18, 2023 03:08
-
-
Save steveroush/412d9c5479ba8f5c30239e4963338b82 to your computer and use it in GitHub Desktop.
Graphviz post-processor to customize edges
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
cat <<QUitquIT | |
# This is a shell archive. | |
# | |
# to execute this file, type: sh alter_archive.sh | |
# | |
# On Linux/UNIX/MacOS(?) systems it is an executable program that will create | |
# a subdirectory (named alter.d) in the currect directory and then | |
# install multiple (text) files in that directory. | |
# This shell archive and all contents are humanly readable - no binary files. | |
# | |
# Windows OS users will have to manually cut this file up and create any files | |
# that are desired. Sorry. | |
# | |
# To proceed, type "y" at the prompt. | |
# | |
QUitquIT | |
read -p "Type y to proceed " ans | |
if [ "$ans" != "y" ];then echo "exiting";exit;fi | |
if [ -d "alter.d" ];then | |
if [ -w "alter.d" ];then echo "directory alter.d exists and is writable"; | |
else echo "directory alter.d exists but is NOT writable\nExiting"; exit; fi | |
else | |
mkdir "alter.d" ; | |
if [ -d "alter.d" ];then | |
if [ -w "alter.d" ];then echo "directory alter.d has been created and is writable"; | |
else echo "directory alter.d has been created but is NOT writable\nExiting"; exit; | |
fi | |
fi | |
fi | |
echo writing alter.d/alterSimpleEdge.gvpr | |
cat >alter.d/alterSimpleEdge.gvpr <<'STopstOP' | |
/*********************************************************************** | |
replace edge spline | |
"edgeType" (required): | |
- "curve" - "regular", symmetric, curve | |
- "straight" - two points define a line | |
- "ortho2" (2 connected sides of a rectangle == one horizontal segment and one vertical segment ) (newer feature) | |
- "ortho3" (3 sides of a rectangle) (was called "ortho") | |
"edgeOffset" (optional): | |
- offset from straight line (does not apply to "straight" or "ortho2") | |
- default: 50% of port-to-port distance | |
- units defined by trailing character(s): | |
- default: points | |
- "pt" - points | |
- "in" - inches | |
- "%" - percent of port-to-port distance | |
"edgeDirection (required):" | |
- "cw" (clockwise) or "ccw" (counter-clockwise) | |
- from tail to head | |
- does not apply to "straight" | |
- default is "cw" ??????? | |
command line: | |
dot myfile.gv | gvpr -cf alterSimpleEdge.gvpr | neato -n2 -Tpng >myfile.png | |
Future: | |
- allow repositioning of arrowhead & arrowtail, using n,s,e,w,nw,ne,sw,se ports | |
(not very interesting, this can be done via the source graph (not applicilbe to some node shapes) | |
- allow repositioning of arrowhead & arrowtail, using new port definitions (1-12 clock positions, degrees (1-359/360), or % along node side 17% fron .ne to .se) | |
(not applicilbe to some node shapes) | |
************************************************************************/ | |
BEGIN{ | |
float Offset; // distance, in points | |
float Percent; // fraction of point-to-point (port-to-port) distance | |
float di, Distance; | |
float deltaX, deltaY; | |
float newX[], newY[]; | |
float oldX[], oldY[], arrowSize[]; | |
float dx, dy; | |
float tail2headDeltaX, tail2headDeltaY; | |
int i, cnt, n, v, goodDirection; | |
int arrowStart, arrowEnd, nextToarrowStart, nextToarrowEnd; | |
int splineStart, splineEnd; | |
int arrow[], clockWise; | |
string ptStr, outStr; | |
string aPoint, whichWay, point[int]; | |
string rslt, MSG; | |
string numstr="?([+-])@(+([0-9])?(.*([0-9]))|\.+([0-9]))"; | |
graph_t Root; | |
////////////////////////////////////////////////////////////// | |
void doErr(string errString) { | |
print("// Error: ", errString); | |
printf(2,"Error: %s\n", errString); | |
} | |
////////////////////////////////////////////////////////////// | |
void doMsg(string errString) { | |
print("// Note: ", errString); | |
//printf(2,"Note: %s\n", errString); | |
} | |
///////////////////////////////////////////////////////////// | |
float Max(float f1, float f2) { | |
float fx; | |
if (f1>f2) fx=f1; | |
else fx=f2; | |
return fx; | |
} | |
///////////////////////////////////////////////////////////// | |
float abs(float f1) { | |
float fx; | |
if (f1<0) fx=-f1; | |
else fx=f1; | |
return fx; | |
} | |
///////////////////////////////////////////////////////////// | |
string mkPoint(float thisX, float thisY) { | |
rslt=(string)thisX + "," + (string)thisY + " "; | |
print("// mkPoint rslt: ", rslt); | |
return rslt; | |
} | |
////////////////////////////////////////////////////////////// | |
// compute distance in points - always positive value | |
float distance(float x1,float y1,float x2,float y2) { | |
di=sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); | |
//print("// DISTANCE: ", di, " ", x1," ", y1," ", x2," ", y2); | |
return di; // /72.; // convert points to inches !! | |
} | |
////////////////////////////////////////////////////////////// | |
string pointAlongLine(float x1, float y1, float x2, float y2, float percent, int direction) { | |
float newx, newy; | |
dx=x1-x2; | |
dy=y1-y2; | |
if (direction==1) { | |
newx=x1-(dx*percent); | |
newy=y1-(dy*percent); | |
} else { | |
newx=x1+(dx*percent); | |
newy=y1+(dy*percent); | |
} | |
print ("// pointAlongLine new point: ", direction," -- ", x1,",", y1," ", x2, ",", y2," -- ", newx, ",", newy); | |
rslt=(string)newx + "," + (string)newy; | |
print("// pointAlongLine rslt: ", rslt); | |
return rslt; | |
} | |
////////////////////////////////////////////////////////////// | |
string rightAnglePoint(float x1, float y1, float x2, float y2, float percent, int direction) { | |
// calculate a point on a line 90 degrees from midpoint of the given line | |
rslt=pointAlongLine(x1, y1, (x1+y1-y2), (y1-x1+x2), percent, direction); | |
print("// 90 rslt: ", rslt); | |
return rslt; | |
} | |
////////////////////////////////////////////////////////////// | |
string reposition(float x1, float y1, float x2, float y2, float aSize) { | |
float tmpX, tmpY, dist; | |
print("// reposition: ", x1,",",y1," ",x2,",",y2); | |
dist=distance(x1,y1,x2,y2); | |
tmpX=x1+((x2-x1)*(aSize/dist)); | |
tmpY=y1+((y2-y1)*(aSize/dist)); | |
print("// reposition: ", x1,",",y1," ",x2,",",y2, " == ", tmpX, " ", tmpY); | |
return (string)tmpX + "," + (string)tmpY; | |
} | |
//////////////////////////////////////////////////////////////////// | |
// point1 & point2: - newX[2],newY[2] & newX[3],newY[3] - "outer spline points" | |
// port (point) - where the arrowhead lands | |
// aSize - arrowhead length | |
// perc - a percentage ?????? (starting w/ .67) | |
// MAYBE % of way from newX[2],newY[2] to newX[3],newY[3] | |
// | |
string arrowheadCalc(float p1X, float p1Y, float p2X, float p2Y, float portX, float portY, float aSize, float perc) { | |
float partialX, partialY, ahX, ahY, dX, dY, d, ahP; | |
string retS; | |
print("// arrowheadCalc: ", p1X,",",p1Y," ",p2X,",",p2Y); | |
partialX=p1X+((p2X-p1X)*perc); | |
partialY=p1Y+((p2Y-p1Y)*perc); | |
print("// arrowheadCalc: ", p1X, ",", p1Y," ",p2X,",",p2Y, " == ", partialX,",",partialY); | |
d=distance(portX, portY, partialX, partialY); | |
ahP=aSize/d; // some fraction | |
dX=partialX-portX; | |
dY=partialY-portY; | |
ahX=portX+(ahP*dX); | |
ahY=portY+(ahP*dY); | |
retS=(string)ahX + "," + (string)ahY; | |
print("// arrowheadCalc: ", retS); | |
return retS; | |
} | |
////////////////////////////////////////////////////////////////// | |
// straight (spline) line requires 4 points | |
// given 1st & last points of line, | |
// create spline w/ 3 points | |
// do NOT add 1st point, it already exists | |
string lineSegment3Points(float x1, float y1, float x2, float y2) { | |
//float pnewX[1], pnewY[1], pnewX[2], pnewY[2]; | |
print("// lineSegment3Points called with >>", x1, ",", y1, " ",x2,",",y2,"<<"); | |
rslt=" " + (string)(x1+(.33*(x2-x1))) + "," + (string)(y1+(.33*(y2-y1))); | |
rslt+=" " + (string)(x1+(.67*(x2-x1))) + "," + (string)(y1+(.67*(y2-y1))) + " "; | |
// now add point #2 (last point) | |
rslt+=(string)x2 + "," + (string)y2 + " "; | |
print("// lineSegment3Points returning >>", rslt,"<<"); | |
return rslt; | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
string ortho2CalcDirection(string D) { | |
string ret1, ret2; | |
MSG="ortho2 DIRECTION tail2headDeltaX " + (string)tail2headDeltaX + " "+ (string)tail2headDeltaY; | |
doMsg(MSG); | |
if (tail2headDeltaX>0 && tail2headDeltaY>0) { // upper right quadrant | |
ret1="NE"; | |
ret2="EN"; | |
} else if (tail2headDeltaX<0 && tail2headDeltaY>0) { // upper left quadrant | |
ret1="WN"; | |
ret2="NW"; | |
} else if (tail2headDeltaX>0 && tail2headDeltaY<0) { // lower right quadrant | |
ret1="ES"; | |
ret2="SE"; | |
} else { // lower left quadrant | |
ret1="SW"; | |
ret2="WS"; | |
} | |
MSG="ortho2 DIRECTION before " + D + " "+ ret1; | |
doMsg(MSG); | |
if (D=="ccw") { | |
ret1=ret2; | |
MSG="ortho2 DIRECTION after " + D + " " + ret1; | |
doMsg(MSG); | |
} | |
MSG="ortho2 RETURNING " + ret1; | |
doMsg(MSG); | |
return ret1; | |
} /////////////////////////////////////////////////////////////////////////// | |
string ortho3CalcDirection(string D) { | |
string ret1, ret2; | |
MSG="DIRECTION tail2headDeltaX " + (string)tail2headDeltaX + " "+ (string)tail2headDeltaY; | |
doMsg(MSG); | |
if (abs(tail2headDeltaX)>=abs(tail2headDeltaY)) { // primarily east/west | |
if (tail2headDeltaX>=0) { // primarily east | |
ret1="nes"; | |
ret2="sen"; | |
} else { // primarily west | |
ret1="swn"; | |
ret2="nws"; | |
} | |
} else { // primarily north/south | |
if (tail2headDeltaY>=0) { // primarily north | |
ret1="wne"; | |
ret2="enw"; | |
} else { // primarily south | |
ret1="esw"; | |
ret2="wse"; | |
} | |
} | |
MSG="DIRECTION before " + D + " "+ ret1; | |
doMsg(MSG); | |
if (D=="ccw") { | |
ret1=ret2; | |
MSG="DIRECTION after " + D + " " + ret1; | |
doMsg(MSG); | |
} | |
return ret1; | |
} | |
////////////////////////////////////////////////////////////////////////////// | |
void debugDir(string D) { | |
print("// debug ",D," ",arrowStart, " ",oldX[arrowStart], " ",oldY[arrowStart]); | |
print("// ",D," ",arrowEnd, " ",oldX[arrowEnd], " ",oldY[arrowEnd]); | |
print("// ",D," ",arrowSize["s"], " ",arrowSize["e"]); | |
} | |
} | |
////////////////////// end of BEGIN //////////////////////////////////////// | |
BEG_G{ | |
Root=$G; | |
} | |
////////////////////////////////////////////////////////////// | |
E{ | |
int DIR, hasType, hasOffset, hasDirection; | |
string useDirection; | |
print("/////////////////////////////////////////////////////////"); | |
if (!hasAttr($,"edgeType") || $.edgeType=="") { | |
print("// edgeType not set for ", $.name,", skipping this edge"); | |
continue; | |
} | |
//////////// check attributes | |
if (hasAttr($,"edgeType") && $.edgeType=="(ortho2|ortho3|curved|straight)") { | |
hasType=1; | |
} else { | |
MSG="Edge " + $.name + ", has bad value for edgeType (" + $.edgeType + ")"; | |
doErr(MSG); | |
hasType=0; | |
} | |
if (hasAttr($,"edgeOffset") && $.edgeOffset!="") { // optional | |
hasOffset=1; | |
} else { | |
hasOffset=0; | |
} | |
if (hasAttr($,"edgeDirection") && $.edgeDirection!="") { // required | |
hasDirection=1; | |
} else { | |
hasDirection=0; | |
} | |
////////////////////////////////////////////////////// | |
unset(newX); | |
unset(newY); | |
$.oldPos=$.pos; | |
// remove pos for all edge labels, let neato set correct pos | |
if (hasAttr($,"lp") && $.lp!="") | |
$.lp=""; | |
if (hasAttr($,"xlp") && $.xlp!="") | |
$.xlp=""; | |
if (hasAttr($,"head_lp") && $.head_lp!="") | |
$.head_lp=""; | |
if (hasAttr($,"tail_lp") && $.tail_lp!="") | |
$.tail_lp=""; | |
// there is a bug in dot (dot output format only), sometimes it messes up the pos value | |
// it produces pos="s,... instead of pos="e,... | |
// OR | |
// it produces pos="e,... instead of pos="s,... | |
if (!hasAttr($,"dir") || $.dir=="" || $.dir=="forward") | |
DIR=1; | |
else | |
switch($.dir) { | |
case "forward": | |
DIR=1; | |
break; | |
case "back": | |
DIR=2; | |
break; | |
case "both": | |
DIR=3; | |
break; | |
case "none": | |
DIR=4; | |
break; | |
default: | |
MSG="Edge " + $.name + ", bad value for dir (" + $.dir + ")"; | |
doErr(MSG); | |
break; | |
} | |
print("// DIR: ",DIR); | |
Offset=.5; // default to 50% of point-to-point distance | |
if ($.edgeType!="" && $.edgeType!="(straight|ortho2|ortho3|curved)") { | |
MSG="Edge " + $.name + ", bad value for edgeType (" + $.edgeType + ")"; | |
doErr(MSG); | |
continue; | |
} | |
print("// edge: ", $.name," >", $.pos, "<< "); | |
cnt=tokens($.pos, point); | |
// initialize these four points | |
arrowStart=0; | |
nextToarrowStart=arrowStart+1; | |
arrowEnd=cnt-1; | |
nextToarrowEnd=arrowEnd-1; | |
arrow["s"]=0; | |
arrow["e"]=0; | |
/**************************************************** | |
now we try to "fix" the dot pos bug (see above) | |
do we need to check ""both"" ????????? | |
*****************************************************/ | |
if ((point[0]=="s,*" && DIR==1) || (point[0]=="e,*" && DIR==2)) { | |
string ts[]; | |
int ti; | |
for (ti=1; ti<cnt; ti++) { | |
ts[ti]=point[cnt-ti]; | |
} | |
for (ti=1; ti<cnt; ti++) { | |
point[ti]=ts[ti]; | |
print("// ti: ", ti," point: ", point[ti]); | |
} | |
print("// before: >",point[0]); | |
if (point[0]=="s,*" && DIR==1) | |
point[0]="e," + substr(point[0],2); | |
else | |
point[0]="s," + substr(point[0],2); | |
print("// after: >",point[0]); | |
print("//FIXED backwards arrowhead"); | |
} // no else ??? HELP | |
for (i=0; i<cnt; i++) { | |
print("// ",i," ",point[i]); | |
ptStr=point[i]; | |
// arrowheads? | |
if (point[i]=="[se]*") { | |
print("// arrowhead : ",point[i]); | |
ptStr=substr(point[i],2); | |
if (point[i]=="s*") { | |
arrowStart=i; | |
nextToarrowStart=arrowStart+1; | |
print("// START: ",arrowStart," arrowEnd: ", arrowEnd); | |
arrow["s"]=1; | |
} else if (point[i]=="e*") { | |
arrowEnd=i; | |
nextToarrowEnd=cnt-1; | |
if (arrowStart==arrowEnd) { // i.e. there is no starting arrow | |
arrowStart++; | |
nextToarrowStart=arrowStart+1; | |
} | |
if (nextToarrowStart==i) | |
nextToarrowStart++; | |
print("// END: ", arrowEnd, " START: ",arrowStart); | |
arrow["e"]=1; | |
} | |
} | |
// do we need trimmed version of point later on ?? | |
// yes, we will have to adjust the arrowheads, too | |
oldX[i]=xOf(ptStr); | |
oldY[i]=yOf(ptStr); | |
print("// ",i," ",point[i], " ", oldX[i], " ", oldY[i]); | |
} // end of loop across pos points | |
////////////////////////////////////////////////////////////////////// | |
// tail-to-head | |
tail2headDeltaX=(float)oldX[arrowEnd] - (float)oldX[arrowStart]; // delta X | |
tail2headDeltaY=(float)oldY[arrowEnd] - (float)oldY[arrowStart]; // delta Y | |
print("// tail2headDeltaX: ", tail2headDeltaX, " tail2headDeltaY: ", tail2headDeltaY); | |
//////////////////////////////////////////////////////////////// | |
// get arrowhead sizes (if arrowheads specified) | |
arrowSize["s"]=0.; | |
arrowSize["e"]=0.; | |
whichWay="s"; | |
if (arrow[whichWay]) { | |
// need arrowhead length/distance | |
// therefore, need "next" point | |
// whichWay is point[????????] | |
arrowSize[whichWay]=distance(oldX[arrowStart], oldY[arrowStart], oldX[nextToarrowStart], oldY[nextToarrowStart]); | |
print("// arrow ", whichWay, " ", arrowSize[whichWay]); | |
} | |
whichWay="e"; | |
if (arrow[whichWay]) { | |
// need arrowhead length/distance | |
// therefore, need "previous" point | |
// whichWay is point[cnt-1] | |
arrowSize[whichWay]=distance(oldX[arrowEnd], oldY[arrowEnd], oldX[nextToarrowEnd], oldY[nextToarrowEnd]); | |
print("// arrow ", whichWay, " ", arrowSize[whichWay]); | |
} | |
//////////////////////////////////////////////////////////////// | |
print("// ArrowStart: ", arrowStart," nextToarrowStart: ", nextToarrowStart, " nextToarrowEnd: ", nextToarrowEnd, " arrowEnd: ", arrowEnd); | |
deltaX=oldX[arrowStart] - oldX[arrowEnd]; | |
deltaY=oldY[arrowStart] - oldY[arrowEnd]; | |
Distance=distance(oldX[arrowStart], oldY[arrowStart], oldX[arrowEnd], oldY[arrowEnd]); | |
print("// DISTANCE: ", Distance); | |
if (hasOffset) { | |
doMsg("OFFSET >" + $.edgeOffset +"<"); | |
Percent=-1; | |
Offset=-1; | |
////////////////////////////////////////////////////////// | |
// add fractional value (9 to 1) | |
if ($.edgeOffset==numstr+ "%") { // "(+([0-9])\%)") { | |
Percent=.01*(float)sub($.edgeOffset,"%"); | |
Offset=Percent*Distance; | |
doMsg("PERCENT: " + (string) Percent + " " + (string)Offset + " %%% "); | |
} else if ($.edgeOffset==numstr) { // points "+([0-9])") { | |
Offset=(float)$.edgeOffset; | |
Percent=Offset/Distance; | |
doMsg("PT (default): "+(string)Offset+" pt " + "Percent: " + (string) Percent); | |
} else if ($.edgeOffset==numstr + "pt") { // points, explicitly "(+([0-9])pt)") { | |
Offset=(float)sub($.edgeOffset,"pt"); | |
Percent=Offset/Distance; | |
doMsg("PT: " + (string)Offset + " pt " + "Percent: " + (string) Percent); | |
} else if ($.edgeOffset==numstr + "in") { // inches, explicitly "(*([0-9]?(.)+([0-9])in)") { | |
// convert inches to points | |
Offset=((float)sub($.edgeOffset,"in"))*72.; | |
Percent=Offset/Distance; | |
doMsg("IN : "+(string)Offset+" in " + "Percent: " + (string) Percent); | |
} else { | |
MSG="Edge " + $.name + ", has bad value for offset (" + $.edgeOffset + "). Must be number optionally followed by \"%|in|pt\"."; | |
doErr(MSG); | |
continue; | |
} | |
} else { | |
print("// setting edgeOffset to default of 36 points (.5 inches)"); | |
Offset=36; | |
Percent=Offset/Distance; | |
} | |
print("// FINAL Percent: ", Percent," Offset: ", Offset); | |
clockWise=1; // default to clockwise from tail to head | |
goodDirection=0; | |
useDirection=""; | |
useDirection="SKIPskipSKIP"; | |
if (hasAttr($,"edgeDirection") && $.edgeDirection!="" && hasAttr($,"edgeType") && $.edgeType=="(ortho2|ortho3|curved)") { | |
print("// EDGE DIRECTION: ", $.edgeDirection); | |
goodDirection=1; | |
} | |
if ($.edgeType=="ortho3" && $.edgeDirection=="(cw|ccw)") | |
useDirection=ortho3CalcDirection($.edgeDirection); | |
else | |
useDirection=$.edgeDirection; | |
if ($.edgeType=="ortho2" && $.edgeDirection=="(cw|ccw)") | |
useDirection=ortho2CalcDirection($.edgeDirection); | |
if ($.edgeType=="straight" && useDirection!="") { | |
MSG="Edge " + $.name + ", edgeType==" + $.edgeType + ", ignoring value for direction (" + $.edgeDirection + ")"; | |
doErr(MSG); | |
} | |
//$.label=useDirection; //// TEMPORARY | |
switch(useDirection) { | |
case "cw": | |
clockWise=1; | |
break; | |
case "ccw": | |
clockWise=0; | |
break; | |
///////////////////// ortho2 cases //////////////////////////////////// | |
case "EN": // east then north | |
newX[1]=oldX[arrowStart] + arrowSize["s"]; | |
newY[1]=oldY[arrowStart]; | |
newX[2]=newX[1]+tail2headDeltaX - arrowSize["s"]; | |
newY[2]=newY[1]; | |
newX[3]=newX[2]; | |
newY[3]=oldY[arrowEnd] - arrowSize["e"]; | |
debugDir($.edgeDirection); | |
break; | |
case "ES": // east then south | |
newX[1]=oldX[arrowStart]+arrowSize["s"]; | |
newY[1]=oldY[arrowStart]; | |
newX[2]=newX[1]+tail2headDeltaX - arrowSize["s"]; | |
newY[2]=newY[1]; | |
newX[3]=newX[2]; | |
newY[3]=oldY[arrowEnd] + arrowSize["e"]; | |
debugDir($.edgeDirection); | |
break; | |
case "WN": // west then north | |
newX[1]=oldX[arrowStart]-arrowSize["s"]; | |
newY[1]=oldY[arrowStart]; | |
newX[2]=newX[1]+tail2headDeltaX + arrowSize["s"]; | |
newY[2]=newY[1]; | |
newX[3]=newX[2]; | |
newY[3]=oldY[arrowEnd] - arrowSize["e"]; | |
debugDir($.edgeDirection); | |
break; | |
case "WS": // west then south | |
newX[1]=oldX[arrowStart]-arrowSize["s"]; | |
newY[1]=oldY[arrowStart]; | |
newX[2]=newX[1]+tail2headDeltaX + arrowSize["s"]; | |
newY[2]=newY[1]; | |
newX[3]=newX[2]; | |
newY[3]=oldY[arrowEnd] + arrowSize["e"]; | |
debugDir($.edgeDirection); | |
break; | |
case "NE": // north then east | |
newX[1]=oldX[arrowStart]; | |
newY[1]=oldY[arrowStart]+arrowSize["s"]; | |
newX[2]=newX[1]; | |
newY[2]=newY[1]+tail2headDeltaY - arrowSize["s"]; | |
newX[3]=oldX[arrowEnd]-arrowSize["e"]; | |
newY[3]=newY[2]; | |
debugDir($.edgeDirection); | |
break; | |
case "NW": // north then west | |
newX[1]=oldX[arrowStart]; | |
newY[1]=oldY[arrowStart]+arrowSize["s"]; | |
newX[2]=newX[1]; | |
newY[2]=newY[1]+tail2headDeltaY - arrowSize["s"]; | |
newX[3]=oldX[arrowEnd]+arrowSize["e"]; | |
newY[3]=newY[2]; | |
debugDir($.edgeDirection); | |
break; | |
case "SE": // south then east // bugs at head ??? | |
newX[1]=oldX[arrowStart]; | |
newY[1]=oldY[arrowStart]-arrowSize["s"]; | |
newX[2]=newX[1]; | |
newY[2]=newY[1]+tail2headDeltaY + arrowSize["s"]; | |
newX[3]=oldX[arrowEnd]-arrowSize["e"]; | |
newY[3]=newY[2]; | |
debugDir($.edgeDirection); | |
break; | |
case "SW": // south then west | |
newX[1]=oldX[arrowStart]; | |
newY[1]=oldY[arrowStart]-arrowSize["s"]; | |
newX[2]=newX[1]; | |
newY[2]=newY[1]+tail2headDeltaY + arrowSize["s"]; | |
newX[3]=oldX[arrowEnd]+arrowSize["e"]; | |
newY[3]=newY[2]; | |
debugDir($.edgeDirection); | |
break; | |
///////////////////// ortho3 cases //////////////////////////////////// | |
case "nes": // primarily east | |
newX[1]=oldX[arrowStart]; | |
newY[1]=oldY[arrowStart]+arrowSize["s"]; | |
newX[2]=oldX[arrowStart]; | |
newY[2]=MAX(oldY[arrowStart],oldY[arrowEnd]) + Offset; | |
newX[3]=oldX[arrowEnd]; | |
newY[3]=newY[2]; | |
newX[4]=newX[3]; | |
newY[4]=oldY[arrowEnd] + arrowSize["e"]; | |
debugDir($.edgeDirection); | |
break; | |
case "sen": // primarily east | |
newX[1]=oldX[arrowStart]; | |
newY[1]=oldY[arrowStart]-arrowSize["s"]; | |
newX[2]=oldX[arrowStart]; | |
newY[2]=MIN(oldY[arrowStart],oldY[arrowEnd]) - Offset; | |
newX[3]=oldX[arrowEnd]; | |
newY[3]=newY[2]; | |
newX[4]=newX[3]; | |
newY[4]=oldY[arrowEnd] - arrowSize["e"]; | |
debugDir($.edgeDirection); | |
break; | |
case "nws": // primarily west | |
newX[1]=oldX[arrowStart]; | |
newY[1]=oldY[arrowStart]+arrowSize["s"]; | |
newX[2]=oldX[arrowStart]; | |
newY[2]=MAX(oldY[arrowStart],oldY[arrowEnd]) + Offset; | |
newX[3]=oldX[arrowEnd]; | |
newY[3]=newY[2]; | |
newX[4]=newX[3]; | |
newY[4]=oldY[arrowEnd] +arrowSize["e"]; | |
debugDir($.edgeDirection); | |
break; | |
case "swn": // primarily west | |
newX[1]=oldX[arrowStart]; | |
newY[1]=oldY[arrowStart]-arrowSize["s"]; | |
newX[2]=oldX[arrowStart]; | |
newY[2]=MIN(oldY[arrowStart],oldY[arrowEnd]) - Offset; | |
newX[3]=oldX[arrowEnd]; | |
newY[3]=newY[2]; | |
newX[4]=newX[3]; | |
newY[4]=oldY[arrowEnd] - arrowSize["e"]; | |
debugDir($.edgeDirection); | |
break; | |
case "enw": // primarily north | |
newX[1]=oldX[arrowStart]+arrowSize["s"]; | |
newY[1]=oldY[arrowStart]; | |
newX[2]=MAX(oldX[arrowStart],oldX[arrowEnd]) + Offset; | |
newY[2]=oldY[arrowStart]; | |
newX[3]=newX[2]; | |
newY[3]=oldY[arrowEnd]; | |
newX[4]=oldX[arrowEnd] +arrowSize["e"]; | |
newY[4]=newY[3]; | |
debugDir($.edgeDirection); | |
break; | |
case "esw": // primarily south | |
newX[1]=oldX[arrowStart]+arrowSize["s"]; | |
newY[1]=oldY[arrowStart]; | |
newX[2]=MAX(oldX[arrowStart],oldX[arrowEnd]) + Offset; | |
newY[2]=oldY[arrowStart]; | |
newX[3]=newX[2]; | |
newY[3]=oldY[arrowEnd]; | |
newX[4]=oldX[arrowEnd] + arrowSize["e"]; | |
newY[4]=newY[3]; | |
debugDir($.edgeDirection); | |
break; | |
case "wne": // primarily north | |
newX[1]=oldX[arrowStart] - arrowSize["s"]; | |
newY[1]=oldY[arrowStart]; | |
newX[2]=MIN(oldX[arrowStart],oldX[arrowEnd]) - Offset; | |
newY[2]=oldY[arrowStart]; | |
newX[3]=newX[2]; | |
newY[3]=oldY[arrowEnd]; | |
newX[4]=oldX[arrowEnd] - arrowSize["e"]; | |
newY[4]=newY[3]; | |
debugDir($.edgeDirection); | |
break; | |
case "wse": // primarily south | |
newX[1]=oldX[arrowStart] - arrowSize["s"]; | |
newY[1]=oldY[arrowStart]; | |
newX[2]=MIN(oldX[arrowStart],oldX[arrowEnd]) - Offset; | |
newY[2]=oldY[arrowStart]; | |
newX[3]=newX[2]; | |
newY[3]=oldY[arrowEnd]; | |
newX[4]=oldX[arrowEnd] - arrowSize["e"]; | |
newY[4]=newY[3]; | |
debugDir($.edgeDirection); | |
break; | |
case "SKIPskipSKIP": // do nothing | |
break; | |
default: | |
goodDirection=0; | |
MSG="Edge " + $.name + ", bad value for direction (" + $.edgeDirection + ")"; | |
doErr(MSG); | |
break; | |
} | |
print("/////////// edgeType: ", $.edgeType); | |
if ($.edgeType=="straight") { | |
string tmpS; | |
tmpS=reposition(oldX[arrowStart], oldY[arrowStart], oldX[arrowEnd], oldY[arrowEnd], arrowSize["s"]); | |
newX[1]=xOf(tmpS); | |
newY[1]=yOf(tmpS); | |
newX[2]=newX[1]; | |
newY[2]=newY[1]; | |
tmpS=reposition(oldX[arrowEnd], oldY[arrowEnd], oldX[arrowStart], oldY[arrowStart], arrowSize["e"]); | |
newX[3]=xOf(tmpS); | |
newY[3]=yOf(tmpS); | |
newX[4]=newX[3]; | |
newY[4]=newY[3]; | |
} else if ($.edgeType=="curved") { | |
string newArrowhead; | |
// need to re-think newX[2]/newY[2] + newX[3]/newY[3] | |
// given arrowsizes & a calculated angle | |
newX[1]=oldX[arrowStart]; | |
newY[1]=oldY[arrowStart]; | |
newX[4]=oldX[arrowEnd]; | |
newY[4]=oldY[arrowEnd]; | |
aPoint=rightAnglePoint(oldX[arrowStart], oldY[arrowStart], oldX[arrowEnd], oldY[arrowEnd], Percent, clockWise); | |
print("// aPoint: ", aPoint); | |
newX[2]=xOf(aPoint); | |
newY[2]=yOf(aPoint); | |
print("// newX[2]/newY[2] :", newX[2],",",newY[2]); | |
deltaX=newX[2]-oldX[arrowStart]; | |
deltaY=newY[2]-oldY[arrowStart]; | |
newX[3]=deltaX+oldX[arrowEnd]; | |
newY[3]=deltaY+oldY[arrowEnd]; | |
print("// newX[3]/newY[3] :", newX[3],",",newY[3]); | |
if (point[arrowStart]=="s*") { | |
newArrowhead=arrowheadCalc(newX[2], newY[2], newX[3], newY[3], oldX[arrowStart], oldY[arrowStart], arrowSize["s"], .09); | |
newX[1]=xOf(newArrowhead); | |
newY[1]=yOf(newArrowhead); | |
print("// NEW START: ", newArrowhead); | |
} | |
if (point[arrowEnd]=="e*") { | |
newArrowhead=arrowheadCalc(newX[3], newY[3], newX[2], newY[2], oldX[arrowEnd], oldY[arrowEnd], arrowSize["e"], .09); | |
newX[4]=xOf(newArrowhead); | |
newY[4]=yOf(newArrowhead); | |
print("// NEW END: ", newArrowhead); | |
} | |
print ("// cnt, start, end ",cnt," ",arrowStart," ",arrowEnd); | |
} | |
/***************** finally, draw some edges **************************/ | |
outStr=""; | |
if (point[arrowStart]=="s*") | |
outStr+=point[arrowStart] + " "; | |
if (point[arrowEnd]=="e*") | |
outStr+=point[arrowEnd] + " "; | |
outStr+=" "; | |
if ($.edgeType=="straight") { // straight line | |
// 4 points (after any arrowheads) | |
// CHANGE to loop through X[] & Y[] values ?? | |
outStr+=(string)newX[1] +"," + (string)newY[1] + " "; | |
outStr+=(string)newX[2] +"," + (string)newY[2] + " "; | |
outStr+=(string)newX[3] +"," + (string)newY[3] + " "; | |
outStr+=(string)newX[4] +"," + (string)newY[4] + " "; | |
print("// straight outStr >", outStr, "<"); | |
$.pos=outStr; | |
} else if ($.edgeType=="(ortho2|ortho3)") { // ortho* layout | |
print("// ORTHO2 or ORTHO3"); | |
// 1st point (after arrowheads) | |
outStr+=(string)newX[1] +"," + (string)newY[1] + " "; | |
// add rest of points (3 points) of each line segment | |
for (newX[i]) { | |
print("// ORTHO2/3 ", i); | |
if (i+1 in newX) { | |
print("// ORTHO2/3 ", i, " ", i+1); | |
outStr+=lineSegment3Points(newX[i],newY[i], newX[i+1], newY[i+1]); | |
outStr+=" "; | |
} | |
} | |
/*************************************************************** | |
// add 3 points of 2nd line segment | |
outStr+=lineSegment3Points(newX[2], newY[2], newX[3], newY[3]); | |
outStr+=" "; | |
// add 3 points of 3rd (last) line segment | |
outStr+=lineSegment3Points(newX[3], newY[3], newX[4], newY[4]); | |
***********************************************************/ | |
print("// B outStr >", outStr, "<"); | |
$.pos=outStr; | |
} else if ($.edgeType=="curved") { | |
print("// CURVED"); | |
// arrowheads first (duped from ortho3, clean it up) | |
print("// Ac outStr >", outStr, "<"); | |
// loop through X[] & Y[] values | |
outStr+=mkPoint(newX[1], newY[1]); | |
outStr+=mkPoint(newX[2], newY[2]); | |
outStr+=mkPoint(newX[3], newY[3]); | |
outStr+=mkPoint(newX[4], newY[4]); | |
print("// B outStr >", outStr, "<"); | |
$.pos=outStr; | |
} | |
} | |
STopstOP | |
echo writing alter.d/alterTest1.gv | |
cat >alter.d/alterTest1.gv <<'STopstOP' | |
digraph S{ | |
//rankdir=LR | |
edge [edgeType=ortho3 edgeOffset="24"] | |
subgraph clusterAAn { ///// NORTH | |
label="cw + 24pt" | |
{rank=sink | |
AA1n[height=2] | |
AA6n[height=2] | |
edge [dir=forward edgeDirection=cw penwidth=3 color=blue] | |
AA1n:n -> AA2n:n | |
AA3n:se -> AA4n:sw [xlabel=XLABEL1 edgeDirection=ccw] | |
AA5n:n -> AA6n:n | |
AA1n:n -> AA4n:n | |
AA1n:n -> AA6n:n [xlabel=XLABEL2] | |
} | |
} | |
subgraph clusterAAs { //// SOUTH | |
label="ccw - 24pt" | |
{rank=sink | |
AA1s[height=2] | |
AA6s[height=2] | |
edge [dir=forward edgeDirection=ccw style=dotted color=purple] | |
AA1s:s -> AA2s:s | |
AA3s:se -> AA4s:sw [label=LABEL1] | |
AA5s:s -> AA6s:s | |
AA1s:s -> AA4s:s [label=LABEL2] | |
AA1s:s -> AA6s:s | |
{edge[style=invis edgeType="" edgeDirection=""] AA1s->AA2s->AA3s->AA4s->AA5s->AA6s } | |
} | |
} | |
edge [edgeOffset="37"] | |
edge [dir=forward edgeDirection=cw style=dashed color=red ] | |
AA5n:n ->AA1s:s | |
AA1n -> AA5s | |
} | |
STopstOP | |
echo writing alter.d/alterTest2.gv | |
cat >alter.d/alterTest2.gv <<'STopstOP' | |
digraph S{ | |
edge [edgeType=ortho3] | |
edge[ edgeOffset="33%"] | |
subgraph clusterBBn { //// NORTH | |
label="cw + 33%" | |
{rank=source | |
BB1n[height=2] | |
BB6n[height=2] | |
edge [dir=forward edgeDirection=cw style=bold color=cyan] | |
BB1n:n -> BB2n:n [color=green] | |
BB3n:se -> BB4n:sw | |
BB5n:n -> BB6n:n | |
BB1n:n -> BB4n:n [color=blue] | |
BB1n:n -> BB6n:n | |
{edge[style=invis edgeType="" edgeDirection=""] BB1n->BB2n->BB3n->BB4n->BB5n->BB6n } | |
} | |
} | |
subgraph clusterBBs { //// SOUTH | |
label="ccw + 33%" | |
{rank=source | |
BB1s[height=2] | |
BB6s[height=2] | |
edge [dir=forward edgeDirection=ccw penwidth=4 style=tapered color=red] | |
BB1s:s -> BB2s:s | |
BB3s:se -> BB4s:sw | |
BB5s:s -> BB6s:s | |
BB1s:s -> BB4s:s | |
BB1s:s -> BB6s:s [color=brown edgeOffset="77" ] | |
{edge[style=invis edgeType="" edgeDirection=""] BB1s->BB2s->BB3s->BB4s->BB5s->BB6s } | |
} | |
} | |
edge [edgeOffset="77"] | |
edge [dir=forward edgeDirection=cw style=dashed color=green ] | |
BB5n:n -> BB1s:s | |
BB1n -> BB5s | |
} | |
STopstOP | |
echo writing alter.d/alterTest20.gv | |
cat >alter.d/alterTest20.gv <<'STopstOP' | |
digraph S{ | |
rankdir=LR | |
nodesep=1.0 | |
edge [edgeType=ortho3] | |
node [shape=rect] //record] | |
A [shape=record label="{<p1>123|<p2>45 54|<p3>a e i o u}"] | |
CDE [shape=record label="<p1>C|<p2>D|<p3>E"] | |
edge [edgeDirection=cw edgeOffset="44"] | |
A:p1:n -> CDE:p2:n | |
"struct1" [ shape =record, label = "a|b|<p1>c" ]; | |
"struct2" [ shape =record, label = "a|{<p1>b1|b2}|c" ]; | |
struct1:p1 -> struct2:p1 [xlabel=XLABEL] | |
{ edge [edgeType=curved] | |
Ax [shape=record label="{<p1>123|<p2>45 54|<p3>a e i o u}"] | |
CDEx [shape=record label="<p1>C|<p2>D|<p3>E"] | |
edge [edgeDirection=ccw edgeOffset="44"] | |
Ax:p1 -> CDEx:p2 | |
"struct1x" [ shape =record, label = "a|b|<p1>c" ]; | |
"struct2x" [ shape =record, label = "a|{<p1>b1|b2}|c" ]; | |
struct1x:p1 -> struct2x:p1 [label=LABEL] | |
} | |
a1:n -> a2:n [ edgeDirection=cw edgeOffset="24"] | |
a3:se -> a4:sw [ edgeDirection=ccw edgeOffset="24"] | |
a5:s -> a6:s [ edgeDirection=ccw edgeOffset="24"] | |
a7:s -> a8:s [ edgeDirection=ccw edgeOffset="24"] | |
edge [edgeType=curved] | |
SS1:n -> SS2:n [edgeDirection=cw edgeOffset="24" color=red] | |
SS3:se -> SS4:sw [dir=back edgeDirection=ccw edgeOffset="24"] | |
// 3 edges from same two nodes but different ports | |
SS5:e -> SS6:w [dir=both edgeDirection=ccw edgeOffset="24"] | |
SS5:se -> SS6:sw [dir=both edgeDirection=ccw edgeOffset="40"] | |
SS5:s -> SS6:s [dir=both edgeDirection=ccw edgeOffset="60"] | |
edge [edgeType=curved] | |
YY1:n -> YY2:n [ edgeDirection=cw edgeOffset="24"] | |
YY3:se -> YY4:sw [dir=back edgeDirection=ccw edgeOffset="24"] | |
// 3 edges from same two nodes and same ports | |
YY5:s -> YY6:s -> YY7:s [dir=both edgeDirection=ccw edgeOffset="24"] | |
YY5:s -> YY6:s [dir=both edgeDirection=ccw edgeOffset="34"] | |
edge [dir=both edgeDirection=ccw edgeOffset="64"] | |
YY5:s -> YY6:s -> YY7:s | |
YY7:s -> YY8:s [dir=both edgeDirection=ccw edgeOffset="24"] | |
YY2:n -> YY2:e [ edgeDirection=cw edgeOffset="34"] | |
YY2:e -> YY2:s [ edgeDirection=cw edgeOffset="34"] | |
YY2:s -> YY2:n [ edgeDirection=cw edgeOffset="64"] | |
SS4:e -> SS2:e [constraint=false edgeDirection=cw edgeOffset="44" color=green] | |
SS1:se -> SS4:nw [constraint=false edgeDirection=cw edgeOffset="24" color=yellow] | |
SS1:se -> SS4:nw [constraint=false edgeDirection=ccw edgeOffset="24" color=teal] | |
edge [edgeType=straight color=purple] | |
SS1:e -> SS2:nw | |
SS1:s -> SS3:ne | |
} | |
STopstOP | |
echo writing alter.d/alterTest21.gv | |
cat >alter.d/alterTest21.gv <<'STopstOP' | |
digraph S{ | |
//rankdir=LR | |
nodesep=.6 | |
edge [edgeType=ortho3 color=green] | |
subgraph clustera{ | |
a1:c -> a2:n [ edgeDirection=ccw edgeOffset="24" tailclip=false] | |
a3:sw -> a4:sw [ edgeDirection=ccw edgeOffset="44"] | |
a5:c -> a6:c [ edgeDirection=cw edgeOffset="24" tailclip=false headclip=false] | |
a7:s -> a8:s [ edgeDirection=cw edgeOffset="54"] | |
a8:s -> a7:s [edgeType=curved edgeDirection=cw edgeOffset="24"] | |
a7:n -> a8:n [edgeType=curved edgeDirection=cw edgeOffset="24"] | |
} | |
subgraph clusterS{ | |
{rank=min //source | |
edge [edgeType=curved] | |
SS1:n -> SS2:n [edgeDirection=cw edgeOffset="24" label=OKOK color=red] | |
SS3:se -> SS4:sw [dir=back edgeDirection=ccw edgeOffset="24"] | |
// 3 edges from same two nodes but different ports | |
SS5:e -> SS6:w [dir=both edgeDirection=ccw edgeOffset="24"] | |
SS5:se -> SS6:sw [dir=both edgeDirection=ccw edgeOffset="40" label=lmnop] | |
SS5:s -> SS6:s [dir=both edgeDirection=ccw edgeOffset="60"] | |
SS4:e -> SS2:e [constraint=false edgeDirection=cw edgeOffset="44" label=popcorn color=purple] | |
SS1:se -> SS4:nw [constraint=false edgeDirection=cw edgeOffset="24" color=green] | |
SS1:se -> SS4:nw [constraint=false edgeDirection=ccw edgeOffset="24" color=teal] | |
edge [edgeType=straight dir=forward style=dashed color=purple ] | |
SS1:se -> SS2:nw | |
SS1:s -> SS3:ne | |
} | |
} | |
subgraph clusterY{ | |
{XXXrank=sink | |
edge [edgeType=curved penwidth=3 color=red] | |
YY1:n -> YY2:n [ edgeDirection=cw edgeOffset="24"] | |
YY3:c -> YY4:c [dir=back edgeDirection=ccw edgeOffset="24" tailclip=false headclip=false] | |
// 3 edges from same two nodes and same ports | |
YY5:s -> YY6:s [dir=both edgeDirection=ccw edgeOffset="34"] | |
edge [dir=both edgeDirection=ccw edgeOffset="64"] | |
YY5:w -> YY6:w -> YY7:w | |
YY7:e -> YY8:e [dir=both edgeDirection=cw edgeOffset="24"] | |
YY2:n -> YY2:e [ edgeDirection=cw edgeOffset="34" color=red] | |
YY2:e -> YY2:s [ edgeDirection=cw edgeOffset="34" style=dotted] | |
YY2:s -> YY2:n [ edgeDirection=cw edgeOffset="64" color=blue] | |
} | |
} | |
SS5 -> a7 [edgeType=""] | |
a4 -> YY5 [edgeType=""] | |
} | |
STopstOP | |
echo writing alter.d/alterTest22.gv | |
cat >alter.d/alterTest22.gv <<'STopstOP' | |
digraph S{ | |
rankdir=LR | |
nodesep=1.0 | |
edge [edgeType=curved ] | |
node [shape=record] | |
A [shape=record label="{<p1>123|<p2>45 54|<p3>a e i o u}"] | |
CDE [shape=record label="<p1>C|<p2>D|<p3>E"] | |
A:p1:n -> CDE:p2 | |
A:p2:c -> CDE:p2 | |
A:p3:s -> CDE:p2 [edgeDirection=ccw] | |
struct1 [ shape =record, label = "<p1>a|<p2>b|<p3>c" ]; | |
struct2 [ shape =record, label = "a|{<p1>b1|b2}|c" ]; | |
struct1:p1:n -> struct2:p1 | |
struct1:p1:n -> struct2:p1 [edgeDirection=ccw] | |
edge[edgeDirection=ccw] | |
struct1:p1:w -> struct1:p2:w | |
struct1:p2:w -> struct1:p3:w | |
struct1:p1:w -> struct1:p3:w [edgeOffset="54"] | |
/////////////////////////////////////////////////////////////////// | |
edge [edgeType=ortho3 edgeDirection=cw] | |
A1 [shape=record label="{<p1>123|<p2>45 54|<p3>a e i o u}"] | |
B1 [shape=record label="{<p1>C|<p2>D|<p3>E}"] | |
A1:p1:n -> B1:p2:n | |
A1:p2:n -> B1:p2:n | |
A1:p3:s -> B1:p2:s [edgeDirection=ccw] | |
S1 [ shape =record, label = "<p1>a|<p2>b|<p3>c" ]; | |
S2 [ shape =record, label = "<p0>a|{<p1>b1|b2}|c" ]; | |
S1:p1:n -> S2:p0:n | |
S1:p1:n -> S2:p0:n [edgeType=curved] | |
edge[edgeDirection=ccw] | |
S1:p1:w -> S1:p2:w | |
S1:p2:w -> S1:p3:w | |
// old struct node | |
edge[edgeDirection=ccw] | |
struct1:p1:w -> struct1:p2:w | |
struct1:p2:w -> struct1:p3:w | |
node [shape=rect] | |
edge [edgeType=straight color=green style=dashed] | |
{ rank=same | |
r:s -> s [dir=both] | |
r:s -> t [dir=back] | |
r:s -> u [dir=none] | |
r:s -> v [dir=forward] | |
} | |
t:e -> E [dir=both] | |
t:e -> F [dir=back] | |
t:e -> G [dir=none] | |
t:e -> H [dir=forward] | |
} | |
STopstOP | |
echo writing alter.d/alterTest3.gv | |
cat >alter.d/alterTest3.gv <<'STopstOP' | |
digraph S { | |
rankdir=LR | |
subgraph clusterAAn { ///// WEST | |
label="cw + 38pt" | |
edge [edgeType=ortho3 edgeOffset="38" color=purple style=bold] | |
edge [dir=forward edgeDirection=cw ] | |
{rank=same | |
AA1w[height=2] | |
AA6w[height=2] | |
AA1w:w -> AA2w:w [label=a301] | |
AA3w:sw -> AA4w:sw | |
AA5w:w -> AA6w:w [label=a302] | |
} | |
} | |
subgraph clusterAAe { //// EAST | |
label="ccw - 38pt" | |
{rank=same | |
AA1e[height=2] | |
AA6e[height=2] | |
edge [edgeType=ortho3 edgeOffset="38" color=green style=bold] | |
edge [dir=forward edgeDirection=ccw penwidth=5 style=tapered] | |
AA1e:e -> AA2e:e [label=bb3aa] | |
AA3e:ne -> AA4e:e | |
AA5e:e -> AA6e:e [label=b3bb] | |
AA1e:e -> AA4e:e | |
AA1e:e -> AA6e:e [label=b3cc] | |
} | |
} | |
AA5w -> AA5e [style=invis] | |
} | |
STopstOP | |
echo writing alter.d/alterTest32.gv | |
cat >alter.d/alterTest32.gv <<'STopstOP' | |
digraph S{ | |
ranksep=1.1 | |
nodesep=1.1 | |
subgraph cluster1 { //// counter clockwise | |
label="clock-wise" | |
{rank=same | |
a1 [group=1] a2 [group=2] a3 [group=3] | |
a1 -> a2 -> a3 -> a4 -> a5 -> a6 [style=invis] | |
} | |
{rank=same | |
b1 [group=1] b2 [group=2] b3 [group=3] | |
b1 -> b2 -> b3 -> b4 -> b5 -> b6[style=invis] | |
} | |
{rank=same | |
c1 [group=1] c2 [group=2] c3 [group=3] c4 [group=4] c5 [group=5] | |
c1 -> c2 -> c3 -> c4 -> c5 -> c6 [style=invis] | |
} | |
{rank=same | |
d1 [group=1] d2 [group=2] d3 [group=3] | |
d1 -> d2 -> d3 -> d4 -> d5 -> d6 [style=invis] | |
} | |
{rank=same | |
e1 [group=1] e2 [group=2] e3 [group=3] | |
e1 -> e2 -> e3 -> e4 -> e5 -> e6 [style=invis] | |
} | |
{rank=same | |
f1 [group=1] f2 [group=2] f3 [group=3] | |
f1 -> f2 -> f3 -> f4 -> f5 -> f6 [style=invis] | |
} | |
a1 ->b1->c1->d1->e1->f1 [style=invis] | |
a2 ->b2->c2->d2->e2->f2 [style=invis] | |
a3 ->b3->c3->d3->e3->f3 [style=invis] | |
a4 ->b4->c4->d4->e4->f4 [style=invis] | |
a5 ->b5->c5->d5->e5->f5 [style=invis] | |
a6 ->b6->c6->d6->e6->f6 [style=invis] | |
edge [edgeType=ortho2] | |
edge [dir=forward edgeDirection=cw style=bold color=cyan] | |
edge [dir=both arrowtail=diamond arrowhead=normal] // temporary ??? | |
a1 -> b2 [label="\E" color=green] | |
c2 -> d3 [dir=both arrowtail=dot color=red] | |
//edge[dir=back] | |
d3 -> a1 [color=blue] | |
b2 -> a3 [color=cyan] | |
b2 -> a1 | |
b4 -> a5 [color=blue] | |
a5 -> b4 [color=lime] | |
c5->b3 | |
c4->d3 | |
c1->b2 [dir=both arrowtail=diamond color=red] | |
c4->d5 | |
a5->b6 | |
d1 -> e2 [color=blue dir=none] | |
e2 -> d1 [color=lime dir=none] | |
f3 -> e4 [color=brown dir=none] | |
e4 -> f3 [color=orange dir=none] | |
} | |
} | |
STopstOP | |
echo writing alter.d/alterTest33.gv | |
cat >alter.d/alterTest33.gv <<'STopstOP' | |
digraph S{ | |
ranksep=1.1 | |
nodesep=1.1 | |
subgraph cluster1 { //// counter clockwise | |
label="counter clock wise" | |
{rank=same | |
a1 [group=1] a2 [group=2] a3 [group=3] | |
a1 -> a2 -> a3 -> a4 -> a5 -> a6 [style=invis] | |
} | |
{rank=same | |
b1 [group=1] b2 [group=2] b3 [group=3] | |
b1 -> b2 -> b3 -> b4 -> b5 -> b6[style=invis] | |
} | |
{rank=same | |
c1 [group=1] c2 [group=2] c3 [group=3] c4 [group=4] c5 [group=5] | |
c1 -> c2 -> c3 -> c4 -> c5 -> c6 [style=invis] | |
} | |
{rank=same | |
d1 [group=1] d2 [group=2] d3 [group=3] | |
d1 -> d2 -> d3 -> d4 -> d5 -> d6 [style=invis] | |
} | |
{rank=same | |
e1 [group=1] e2 [group=2] e3 [group=3] | |
e1 -> e2 -> e3 -> e4 -> e5 -> e6 [style=invis] | |
} | |
{rank=same | |
f1 [group=1] f2 [group=2] f3 [group=3] | |
f1 -> f2 -> f3 -> f4 -> f5 -> f6 [style=invis] | |
} | |
a1 ->b1->c1->d1->e1->f1 [style=invis] | |
a2 ->b2->c2->d2->e2->f2 [style=invis] | |
a3 ->b3->c3->d3->e3->f3 [style=invis] | |
a4 ->b4->c4->d4->e4->f4 [style=invis] | |
a5 ->b5->c5->d5->e5->f5 [style=invis] | |
a6 ->b6->c6->d6->e6->f6 [style=invis] | |
edge [edgeType=ortho2] | |
edge [dir=forward edgeDirection=ccw edgeOffset=99] | |
edge [style=bold color=cyan] | |
edge [dir=both arrowtail=diamond arrowhead=normal] // temporary ??? | |
a1 -> b2 [label="\E" color=green] | |
c2 -> d3 [dir=both arrowtail=dot color=red] | |
//edge[dir=back] | |
d3 -> a1 [color=blue] | |
b2 -> a3 [color=cyan] | |
b2 -> a1 | |
b4 -> a5 [color=blue] | |
a5 -> b4 [color=lime] | |
c5->b3 | |
c4->d3 | |
c1->b2 [dir=both arrowtail=diamond color=red] | |
c4->d5 | |
a5->b6 | |
d1 -> e2 [color=blue dir=none] | |
e2 -> d1 [color=lime dir=none] | |
f3 -> e4 [color=brown dir=none] | |
e4 -> f3 [color=orange dir=none] | |
} | |
} | |
STopstOP | |
echo writing alter.d/alterTest35.gv | |
cat >alter.d/alterTest35.gv <<'STopstOP' | |
digraph S{ | |
ranksep=1.1 | |
nodesep=1.1 | |
subgraph cluster1 { //// counter clockwise | |
label="ortho3 clock-wise" | |
{rank=same | |
a1 [group=1] a2 [group=2] a3 [group=3] | |
a1 -> a2 -> a3 -> a4 -> a5 -> a6 [style=invis] | |
} | |
{rank=same | |
b1 [group=1] b2 [group=2] b3 [group=3] | |
b1 -> b2 -> b3 -> b4 -> b5 -> b6[style=invis] | |
} | |
{rank=same | |
c1 [group=1] c2 [group=2] c3 [group=3] c4 [group=4] c5 [group=5] | |
c1 -> c2 -> c3 -> c4 -> c5 -> c6 [style=invis] | |
} | |
{rank=same | |
d1 [group=1] d2 [group=2] d3 [group=3] | |
d1 -> d2 -> d3 -> d4 -> d5 -> d6 [style=invis] | |
} | |
{rank=same | |
e1 [group=1] e2 [group=2] e3 [group=3] | |
e1 -> e2 -> e3 -> e4 -> e5 -> e6 [style=invis] | |
} | |
{rank=same | |
f1 [group=1] f2 [group=2] f3 [group=3] | |
f1 -> f2 -> f3 -> f4 -> f5 -> f6 [style=invis] | |
} | |
a1 ->b1->c1->d1->e1->f1 [style=invis] | |
a2 ->b2->c2->d2->e2->f2 [style=invis] | |
a3 ->b3->c3->d3->e3->f3 [style=invis] | |
a4 ->b4->c4->d4->e4->f4 [style=invis] | |
a5 ->b5->c5->d5->e5->f5 [style=invis] | |
a6 ->b6->c6->d6->e6->f6 [style=invis] | |
edge [edgeType=ortho3] | |
edge [dir=forward edgeDirection=cw style=bold color=cyan] | |
edge [dir=both arrowtail=diamond arrowhead=normal] // temporary ??? | |
a1 -> b1 [color=green] | |
c1 -> c2 [dir=both arrowtail=dot color=red] | |
//edge[dir=back] | |
b2 -> a3 [color=cyan] | |
b4 -> a5 [color=blue] | |
a5 -> b4 [color=lime] | |
c5->b3 | |
c4->d3 | |
c1->b2 [dir=both arrowtail=diamond color=red] | |
c4->d5 | |
a5->b6 | |
d1 -> e2 [color=blue dir=none] | |
e2 -> d1 [color=lime dir=none] | |
f3 -> e4 [color=brown dir=none] | |
e4 -> f3 [color=orange dir=none] | |
} | |
} | |
STopstOP | |
echo writing alter.d/alterTest36.gv | |
cat >alter.d/alterTest36.gv <<'STopstOP' | |
digraph S{ | |
ranksep=1.1 | |
nodesep=1.1 | |
subgraph cluster1 { //// counter clockwise | |
label="ortho3 counter-clock-wise" | |
{rank=same | |
a1 [group=1] a2 [group=2] a3 [group=3] | |
a1 -> a2 -> a3 -> a4 -> a5 -> a6 [style=invis] | |
} | |
{rank=same | |
b1 [group=1] b2 [group=2] b3 [group=3] | |
b1 -> b2 -> b3 -> b4 -> b5 -> b6[style=invis] | |
} | |
{rank=same | |
c1 [group=1] c2 [group=2] c3 [group=3] c4 [group=4] c5 [group=5] | |
c1 -> c2 -> c3 -> c4 -> c5 -> c6 [style=invis] | |
} | |
{rank=same | |
d1 [group=1] d2 [group=2] d3 [group=3] | |
d1 -> d2 -> d3 -> d4 -> d5 -> d6 [style=invis] | |
} | |
{rank=same | |
e1 [group=1] e2 [group=2] e3 [group=3] | |
e1 -> e2 -> e3 -> e4 -> e5 -> e6 [style=invis] | |
} | |
{rank=same | |
f1 [group=1] f2 [group=2] f3 [group=3] | |
f1 -> f2 -> f3 -> f4 -> f5 -> f6 [style=invis] | |
} | |
a1 ->b1->c1->d1->e1->f1 [style=invis] | |
a2 ->b2->c2->d2->e2->f2 [style=invis] | |
a3 ->b3->c3->d3->e3->f3 [style=invis] | |
a4 ->b4->c4->d4->e4->f4 [style=invis] | |
a5 ->b5->c5->d5->e5->f5 [style=invis] | |
a6 ->b6->c6->d6->e6->f6 [style=invis] | |
edge [edgeType=ortho3 ] | |
edge [dir=forward edgeDirection=ccw edgeOffset=99] | |
edge [style=bold color=cyan] | |
edge [dir=both arrowtail=diamond arrowhead=normal] // temporary ??? | |
a1 -> b1 [color=green] | |
c1 -> c2 [dir=both arrowtail=dot color=red] | |
//edge[dir=back] | |
b2 -> a3 [color=cyan] | |
b4 -> a5 [color=blue] | |
a5 -> b4 [color=lime] | |
c5->b3 | |
c4->d3 | |
c1->b2 [dir=both arrowtail=diamond color=red] | |
c4->d5 | |
a5->b6 | |
d1 -> e2 [color=blue dir=none] | |
e2 -> d1 [color=lime dir=none] | |
f3 -> e4 [color=brown dir=none] | |
e4 -> f3 [color=orange dir=none] | |
} | |
} | |
STopstOP | |
echo writing alter.d/alterTest4.gv | |
cat >alter.d/alterTest4.gv <<'STopstOP' | |
digraph S{ | |
rankdir=LR | |
edge [edgeType=ortho3] | |
edge[ edgeOffset="45%"] | |
subgraph clusterBBn { | |
label="ccw + 45%" | |
{rank=source | |
BB1n[height=2] | |
BB6n[height=2] | |
edge [dir=forward edgeDirection=ccw ] | |
BB1n:n -> BB2n:n [label=a123] | |
BB3n:se -> BB4n:sw | |
BB5n:n -> BB6n:n | |
BB1n:n -> BB4n:n [label=a12] | |
BB1n:n -> BB6n:n [label=a13] | |
{edge[style=invis edgeType="" edgeDirection=""] BB1n->BB2n->BB3n->BB4n->BB5n->BB6n } | |
} | |
} | |
subgraph clusterBBs { | |
label="cw + 45%" | |
{rank=source | |
BB1s[height=2] | |
BB6s[height=2] | |
edge [dir=forward edgeDirection=cw color=red] | |
BB1s:s -> BB2s:s [label=a23] | |
BB3s:se -> BB4s:sw | |
BB5s:s -> BB6s:s [label=a2a3] | |
BB1s:s -> BB4s:s | |
BB1s:s -> BB6s:s [label=a333] | |
{edge[style=invis edgeType="" edgeDirection=""] BB1s->BB2s->BB3s->BB4s->BB5s->BB6s } | |
} | |
} | |
} | |
STopstOP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Modest code clean-up plus bug fixes.