Blob Blame History Raw
//The scripts for the tooltip and moveobj are based on work from
//SVG - Learning By Coding - http://www.datenverdrahten.de/svglbc/
//Author: Dr. Thomas Meinike 11/03 - thomas@handmadecode.de
var svgdoc,svgroot,paths,revert;
var collapsed = new Array(2);
var name = new Array(%i);
var clickStatus = new Array(%i);
var redCount = new Array(%i);
var salmonCount = new Array(%i);
var moveObj,rect,x,y,attr1,attr2,wert1,wert2,zoom=1,active=false;

function MoveObj(evt)
{
    if (active) {
	var roundx, roundy;
	var curtrans=svgroot.currentTranslate;
	var ctx=curtrans.x;
	var cty=curtrans.y;

	x=evt.clientX()
	y=evt.clientY()
	wert1=(x-ctx)*zoom*%.2f+%.2f+attr1-5;
	wert2=(y-cty)*zoom*%.2f+%.2f+attr2-5;
	roundx=Math.round(wert1*100)/100;
	roundy=Math.round(wert2*100)/100;

	moveObj.setAttribute("transform","translate("+roundx+","+roundy+")");
    }
}

function ClickObj(evt)
{
    rect=evt.target.parentNode.getElementsByTagName("rect").item(0);
    moveObj=evt.target.parentNode;
    attr1=rect.getAttribute("width")/2;
    attr2=rect.getAttribute("height")/2;
    active=true;
}

function OutOfObj(evt)
{
    if (active) {
	active=false;
	findAdjacentEdges();
    }
}

function findAdjacentEdges()
{
    var rectl, rectlid, i, nodenames;
    rectl = rect;
    rectlid = rectl.getAttribute("id");
    for (i=0; i<paths.length; i++) {
	nodenames = paths.item(i).getAttribute("id").split("-");
	if (nodenames[0] == rectlid || nodenames[1] == rectlid) {
	    repaintEdge(paths.item(i), nodenames, i);
	}
    }
}

function repaintEdge(edge, nodenames, j)
{
    var startnode, endnode, attr, i, k, l, m, alpha, beta;
    var nodesx, nodesy, nodeex, nodeey, nodesw, nodesh, nodeew, nodeeh;
    var edgesx, edgesy, edgeex, edgeey, sx, sy, ex, ey;

    //extract node coordinates and dimensions
    startnode = svgdoc.getElementById(nodenames[0]);
    nodesw=startnode.getAttribute("width");
    nodesh=startnode.getAttribute("height");
    attr = startnode.parentNode.attributes;
    for (i=0;i<attr.length;i++) {
        if (attr.item(i).nodeName == "transform") {
	    k = attr.item(i).nodeValue.indexOf("(");
	    l = attr.item(i).nodeValue.indexOf(",");
	    m = attr.item(i).nodeValue.indexOf(")");
	    nodesx = parseFloat(attr.item(i).nodeValue.substring(k+1,l));
	    nodesy = parseFloat(attr.item(i).nodeValue.substring(l+1,m));
	}
    }
    endnode = svgdoc.getElementById(nodenames[1]);
    nodeew=endnode.getAttribute("width");
    nodeeh=endnode.getAttribute("height");
    attr = endnode.parentNode.attributes;
    for (i=0;i<attr.length;i++) {
        if (attr.item(i).nodeName == "transform") {
	    k = attr.item(i).nodeValue.indexOf("(");
	    l = attr.item(i).nodeValue.indexOf(",");
	    m = attr.item(i).nodeValue.indexOf(")");
	    nodeex = parseFloat(attr.item(i).nodeValue.substring(k+1,l));
	    nodeey = parseFloat(attr.item(i).nodeValue.substring(l+1,m));
	}
    }

    alpha = Math.atan((nodesy-nodeey)/(nodesx-nodeex));
    if (alpha < 0)
	alpha += Math.PI;

    //calculate intersection of edge and startNode
    beta = Math.atan(nodesh/nodesw);
    if (alpha < beta
	|| (alpha > Math.PI-beta && alpha < Math.PI+beta)
	|| alpha > 2*Math.PI-beta) {
	//intersection at left or right border
	if (nodesx < nodeex) {
	    edgesx = nodesx - 0 + nodesw/2;
	} else {
	    edgesx = nodesx - nodesw/2;
	}
	if (nodesy < nodeey) {
	    edgesy = nodesy - 0 + Math.abs(nodesw*Math.tan(alpha)/2);
	} else {
	    edgesy = nodesy - Math.abs(nodesw*Math.tan(alpha)/2);
	}
    } else {
	//intersection at top or bottom border
	if (nodesy < nodeey) {
	    edgesy = nodesy - 0 + nodesh/2;
	} else {
	    edgesy = nodesy - nodesh/2;
	}
	if (nodesx < nodeex) {
	    edgesx = nodesx - 0 + Math.abs(nodesh/(2*Math.tan(alpha)));
	} else {
	    edgesx = nodesx - Math.abs(nodesh/(2*Math.tan(alpha)));
	}
    }

    //calculate intersection of edge and endNode
    beta = Math.atan(nodeeh/nodeew);
    if (alpha < beta
	|| (alpha > Math.PI-beta && alpha < Math.PI+beta)
	|| alpha > 2*Math.PI-beta) {
	//intersection at left or right border
	if (nodesx > nodeex) {
	    edgeex = nodeex - 0 + nodeew/2;
	} else {
	    edgeex = nodeex - nodeew/2;
	}
	if (nodesy > nodeey) {
	    edgeey = nodeey - 0 + Math.abs(nodeew*Math.tan(alpha)/2);
	} else {
	    edgeey = nodeey - Math.abs(nodeew*Math.tan(alpha)/2);
	}
    } else {
	//intersection at top or bottom border
	if (nodesy > nodeey) {
	    edgeey = nodeey - 0 + nodeeh/2;
	} else {
	    edgeey = nodeey - nodeeh/2;
	}
	if (nodesx > nodeex) {
	    edgeex = nodeex - 0 + Math.abs(nodeeh/(2*Math.tan(alpha)));
	} else {
	    edgeex = nodeex - Math.abs(nodeeh/(2*Math.tan(alpha)));
	}
    }

    //set new edge coordinates
    sx=Math.round(edgesx*100)/100;
    ex=Math.round(edgeex*100)/100;
    sy=Math.round(edgesy*100)/100;
    ey=Math.round(edgeey*100)/100;

    if (sx < ex) {
	if (revert[j] == 1) {
	    revert[j] = 0;
	    flipEdgeMarks(edge);
	}
	edge.setAttribute("d","M "+sx+" "+sy+" "+ex+" "+ey);
    } else {
	if (revert[j] == 0) {
	    revert[j] = 1;
	    flipEdgeMarks(edge);
	}
	edge.setAttribute("d","M "+ex+" "+ey+" "+sx+" "+sy);
    }
}

function flipEdgeMarks(edge)
{
    var attr, i, j, done, textpaths, pathnamei, offset;

    //revert start- and end-markers
    attr = edge.attributes;
    done = 0;
    for (i=0;i<attr.length;i++) {
        if (attr.item(i).nodeName == "marker-start") {
	    for (j=i;j<attr.length;j++) {
		if (attr.item(j).nodeName == "marker-end") {
		    done = 1;
		}
	    }
	    if (done == 0) {
		//start->end
		edge.removeAttribute("marker-start");
		edge.setAttribute("marker-end","url(#arrowend)");
		break;
	    }
	}
        if (attr.item(i).nodeName == "marker-end") {
	    for (j=i;j<attr.length;j++) {
		if (attr.item(j).nodeName == "marker-start") {
		    done = 1;
		}
	    }
	    if (done == 0) {
		//end->start
		edge.removeAttribute("marker-end");
		edge.setAttribute("marker-start","url(#arrowstart)");
		break;
	    }
	}
    }

    //revert cardinalities
    textpaths = svgdoc.getElementsByTagName("textPath");
    for (i=0;i<textpaths.length;i++) {
	pathname = textpaths.item(i).getAttribute("xlink:href").replace(/#/,"");
	if (pathname == edge.getAttribute("id")) {
	    offset = textpaths.item(i).getAttribute("startOffset").substr(0,2);
	    textpaths.item(i).setAttribute("startOffset",100 - offset + "%")
	}
    }
}

function getSVGDoc(load_evt)
{
    svgdoc=load_evt.target.ownerDocument;
    svgroot=svgdoc.documentElement;
    texte=svgdoc.getElementById("tooltip").getElementsByTagName("text");
    for (i=1; i<%i; i++) {
	textNode=texte.item(1).cloneNode("true");
	svgdoc.getElementById("tooltip").appendChild(textNode);
    }
    texte=svgdoc.getElementById("tooltip").getElementsByTagName("text");
}

function ShowTooltipMZ(mousemove_event,txt)
{
    var ttrelem,tttelem,ttline,posx,posy,curtrans,ctx,cty,txt;
    var maxbreite,tmp,i;
    ttrelem=svgdoc.getElementById("ttr");
    tttelem=svgdoc.getElementById("ttt");
    ttline=svgdoc.getElementById("ttl");
    posx=mousemove_event.clientX;
    posy=mousemove_event.clientY;
    for (i=1;i<=%i;i++)
	texte.item(i).firstChild.data="";
    tttelem.childNodes.item(0).data="";
    tmp=txt.split("\n");
    maxbreite=0;
    for (i=0;i<tmp.length;i++) {
	if (tmp[i]=="")
	    continue;
	tttelem.childNodes.item(0).data=tmp[i];
	if (maxbreite<tttelem.getComputedTextLength())
	    maxbreite=tttelem.getComputedTextLength();
    }
    curtrans=svgroot.currentTranslate;
    ctx=curtrans.x;
    cty=curtrans.y;
    ttrelem.setAttribute("x",posx-ctx+10);
    ttrelem.setAttribute("y",posy-cty-20+10);
    ttrelem.setAttribute("width",maxbreite*0.92+10);
    ttrelem.setAttribute("height",tmp.length*15+3);
    ttrelem.setAttribute("style",
			    "fill: #FFC; stroke: #000; stroke-width: 0.5px");
    for (i=1; i<=tmp.length; i++) {
	if (tmp[i-1]=="-- -- --") {
	    ttline.setAttribute("x1", posx-ctx+10);
	    ttline.setAttribute("y1", parseInt(i-1)*15+posy-cty);
	    ttline.setAttribute("x2", posx-ctx+10+maxbreite*0.92+10);
	    ttline.setAttribute("y2", parseInt(i-1)*15+posy-cty);
	    ttline.setAttribute("style", "stroke: #000; stroke-width: 0.5px");
	} else {
	    texte.item(i).firstChild.data=tmp[i-1];
	    texte.item(i).setAttribute("x",posx-ctx+15);
	    texte.item(i).setAttribute("y",parseInt(i-1)*15+posy-cty+3);
	    texte.item(i).setAttribute("style","fill: #00E; font-size: 11px");
	}
    }
    svgdoc.getElementById("tooltip").style.setProperty("visibility","visible");
}

function HideTooltip()
{
    svgdoc.getElementById("ttl").style.setProperty("visibility","hidden");
    svgdoc.getElementById("tooltip").style.setProperty("visibility","hidden");
}

function ZoomControl()
{
    var curzoom;
    curzoom=svgroot.currentScale;
    svgdoc.getElementById("tooltip").setAttribute("transform",
							"scale("+1/curzoom+")");
    zoom=1/curzoom;
}

function collapse(evt)
{
    var i, k, l, m, svgdoc, obj, targetID, targetX, targetY, attr;
    obj = evt.getTarget();
    svgdoc = obj.ownerDocument;
    //extract coordinates and id of the clicked text
    attr = obj.parentNode.parentNode.attributes;
    for (i=0;i<attr.length;i++) {
        if (attr.item(i).nodeName == "transform") {
            k = attr.item(i).nodeValue.indexOf("(");
            l = attr.item(i).nodeValue.indexOf(",");
            m = attr.item(i).nodeValue.indexOf(")");
            targetX = attr.item(i).nodeValue.substring(k+1,l);
            targetY = attr.item(i).nodeValue.substring(l+1,m);
        }
        if (attr.item(i).nodeName == "id") {
            targetID = attr.item(i).nodeValue.substr(2);
        }
    }
    //decide if we are collapsing or uncollapsing
    if (collapsed[0][targetID] == 0) {
        hideInfos(evt, obj, svgdoc, targetX, targetY, targetID, attr);
        collapsed[0][targetID] = 1;
    } else {
        showHiddenInfos(evt, obj, svgdoc, targetX, targetY, targetID, attr);
        collapsed[0][targetID] = 0;
    }
}

function showHiddenInfos(evt, obj, svgdoc, targetX, targetY, targetID, attr)
{
    var i, k, l, m, nextObj, nextX, nextY, gapY=0, clickedID;
    //change clicked text
    obj.firstChild.data="--";
    targetID++;
    nextObj = svgdoc.getElementById("MI"+targetID);
    if (nextObj == null)
        return;
    //show child texts again
    for (;;) {
        attr = nextObj.attributes;
        for (i=0;i<attr.length;i++) {
            if (attr.item(i).nodeName == "transform") {
                k = attr.item(i).nodeValue.indexOf("(");
                l = attr.item(i).nodeValue.indexOf(",");
                m = attr.item(i).nodeValue.indexOf(")");
                nextX = attr.item(i).nodeValue.substring(k+1,l);
                nextY = attr.item(i).nodeValue.substring(l+1,m);
            }
        }
        if (nextX > targetX) {
            nextObj.style.setProperty("visibility","visible");
            gapY += 15;
            if (collapsed[0][targetID] == 1) {
                targetID = collapsed[1][targetID];
            } else {
                targetID++;
            }
            nextObj = svgdoc.getElementById("MI"+targetID);
            if (nextObj == null)
                break;
        } else {
            break;
        }
    }
    if (nextObj == null)
        return;
    //move following texts downwards
    while (nextObj != null) {
        attr = nextObj.attributes;
        for (i=0;i<attr.length;i++) {
            if (attr.item(i).nodeName == "transform") {
                k = attr.item(i).nodeValue.indexOf("(");
                l = attr.item(i).nodeValue.indexOf(",");
                m = attr.item(i).nodeValue.indexOf(")");
                nextX = attr.item(i).nodeValue.substring(k+1,l);
                nextY = attr.item(i).nodeValue.substring(l+1,m);
            }
        }
        nextY = nextY - 1 + gapY + 1;
        nextObj.setAttribute("transform","translate("+nextX+","+nextY+")");
        targetID++;
        nextObj = svgdoc.getElementById("MI"+targetID);
    }
}

function hideInfos(evt, obj, svgdoc, targetX, targetY, targetID, attr)
{
    var i, k, l, m, nextObj, nextX, nextY, gapY=0;
    clickedID = targetID;
    //change clicked text
    obj.firstChild.data="+";
    targetID++;
    nextObj = svgdoc.getElementById("MI"+targetID);
    if (nextObj == null)
        return;
    //wipe out child texts
    for (;;) {
        attr = nextObj.attributes;
        for (i=0;i<attr.length;i++) {
            if (attr.item(i).nodeName == "transform") {
                k = attr.item(i).nodeValue.indexOf("(");
                l = attr.item(i).nodeValue.indexOf(",");
                m = attr.item(i).nodeValue.indexOf(")");
                nextX = attr.item(i).nodeValue.substring(k+1,l);
                nextY = attr.item(i).nodeValue.substring(l+1,m);
            }
        }
        if (nextX > targetX) {
            nextObj.style.setProperty("visibility","hidden");
            gapY += 15;
            if (collapsed[0][targetID] == 1) {
                targetID = collapsed[1][targetID];
            } else {
                targetID++;
            }
            nextObj = svgdoc.getElementById("MI"+targetID);
            if (nextObj == null)
                break;
        } else {
            break;
        }
    }
    //save next uncollapsed element in array
    collapsed[1][clickedID] = targetID;
    if (nextObj == null)
        return;
    //move following texts upwards
    while (nextObj != null) {
        attr = nextObj.attributes;
        for (i=0;i<attr.length;i++) {
            if (attr.item(i).nodeName == "transform") {
                k = attr.item(i).nodeValue.indexOf("(");
                l = attr.item(i).nodeValue.indexOf(",");
                m = attr.item(i).nodeValue.indexOf(")");
                nextX = attr.item(i).nodeValue.substring(k+1,l);
                nextY = attr.item(i).nodeValue.substring(l+1,m);
            }
        }
        nextY -= gapY;
        nextObj.setAttribute("transform","translate("+nextX+","+nextY+")");
        targetID++;
        nextObj = svgdoc.getElementById("MI"+targetID);
    }
}

function init(evt)
{
    var nodenames, startnode, endnode, attr, i, j, k, l, m, nodesx, nodeex;
    collapsed[0] = new Array(%i);
    collapsed[1] = new Array(%i);
    for (i=0; i<%i; i++) {
        collapsed[0][i] = 0;
        collapsed[1][i] = 0;
    }
    for (i=0; i<%i; i++) {
	name[i] = "";
	clickStatus[i] = 0;
	redCount[i] = 0;
	salmonCount[i] = 0;
    }
    getSVGDoc(evt);

    //check which edges are printed from right to left
    paths = svgdoc.getElementsByTagName("path");
    revert = new Array(paths.length);
    for (j=0; j<paths.length; j++) {
	nodenames = paths.item(j).getAttribute("id").split("-");
	startnode = svgdoc.getElementById(nodenames[0]);
	attr = startnode.parentNode.attributes;
	for (i=0;i<attr.length;i++) {
	    if (attr.item(i).nodeName == "transform") {
		k = attr.item(i).nodeValue.indexOf("(");
		l = attr.item(i).nodeValue.indexOf(",");
		m = attr.item(i).nodeValue.indexOf(")");
		nodesx = parseFloat(attr.item(i).nodeValue.substring(k+1,l));
	    }
	}
	endnode = svgdoc.getElementById(nodenames[1]);
	attr = endnode.parentNode.attributes;
	for (i=0;i<attr.length;i++) {
	    if (attr.item(i).nodeName == "transform") {
		k = attr.item(i).nodeValue.indexOf("(");
		l = attr.item(i).nodeValue.indexOf(",");
		m = attr.item(i).nodeValue.indexOf(")");
		nodeex = parseFloat(attr.item(i).nodeValue.substring(k+1,l));
	    }
	}
	if (nodesx > nodeex) {
	    revert[j] = 1;
	} else {
	    revert[j] = 0;
	}
    }
}

function setStatus(evt, color1, color2)
{
    var clickObj = evt.getTarget();
    var clickObjName = clickObj.getAttribute('id');

    //find i corresponding to the clicked object
    for (i=0; i<%i; i++) {
	if (name[i] == "") {
	    name[i] = clickObjName;
	    break;
	}
	if (name[i] != clickObjName)
	    continue;
	break;
    }

    //toggle click status, color clicked object
    if (clickStatus[i] == 0) {
	clickStatus[i] = 1;
	clickObj.setAttribute("style","fill: "+color1);
    } else {
	clickStatus[i] = 0;
	clickObj.setAttribute("style","fill: "+color2);
    }

    //adjust color-counter
    if (color1 == 'red') {
	if (clickStatus[i] == 1) {
	    redCount[i]++;
	} else {
	    redCount[i]--;
	}
    }
    if (color1 == 'salmon') {
	if (clickStatus[i] == 1) {
	    salmonCount[i]++;
	} else {
	    salmonCount[i]--;
	}
    }

    if (clickStatus[i] == 0 && salmonCount[i] > 0) {
	clickObj.setAttribute("style","fill: salmon");
    }
}

function changeColor(evt, targetObjName, color1, color2)
{
    var clickObj = evt.getTarget();
    var clickObjName = clickObj.getAttribute('id');
    var targetObj = svgDocument.getElementById(targetObjName);

    //find i corresponding to the clicked object
    for (i=0; i<%i; i++) {
	if (name[i] != clickObjName)
	    continue;
	break;
    }

    //find j corresponding to the target object
    for (j=0; j<%i; j++) {
	if (name[j] == "") {
	    name[j] = targetObjName;
	    break;
	}
	if (name[j] != targetObjName)
	    continue;
	break;
    }

    //adjust color-counter
    if (color1 == 'red') {
	if (clickStatus[i] == 1) {
	    redCount[j]++;
	} else {
	    redCount[j]--;
	}
    }
    if (color1 == 'salmon') {
	if (clickStatus[i] == 1) {
	    salmonCount[j]++;
	} else {
	    salmonCount[j]--;
	}
    }
}

function colorText(targetObjName, color)
{
    var targetObj = svgDocument.getElementById(targetObjName);

    //find i corresponding to the target object
    for (i=0; i<%i; i++) {
	if (name[i] != targetObjName)
	    continue;
	break;
    }

    //color text
    if (i == %i) {
	targetObj.setAttribute("style","fill: "+color);
	return;
    }
    if (redCount[i] == 0 && salmonCount[i] == 0) {
	targetObj.setAttribute("style","fill: "+color);
    }
    if (salmonCount[i] > 0) {
	if (color == 'red') {
	    targetObj.setAttribute("style","fill: red");
	} else {
	    if (redCount[i] > 0) {
		targetObj.setAttribute("style","fill: red");
	    } else {
		targetObj.setAttribute("style","fill: salmon");
	    }
	}
    }
}