Imported Upstream version 0.4.8
[platform/upstream/libsmi.git] / tools / dump-svg-script.js
1 //The scripts for the tooltip and moveobj are based on work from
2 //SVG - Learning By Coding - http://www.datenverdrahten.de/svglbc/
3 //Author: Dr. Thomas Meinike 11/03 - thomas@handmadecode.de
4 var svgdoc,svgroot,paths,revert;
5 var collapsed = new Array(2);
6 var name = new Array(%i);
7 var clickStatus = new Array(%i);
8 var redCount = new Array(%i);
9 var salmonCount = new Array(%i);
10 var moveObj,rect,x,y,attr1,attr2,wert1,wert2,zoom=1,active=false;
11
12 function MoveObj(evt)
13 {
14     if (active) {
15         var roundx, roundy;
16         var curtrans=svgroot.currentTranslate;
17         var ctx=curtrans.x;
18         var cty=curtrans.y;
19
20         x=evt.clientX()
21         y=evt.clientY()
22         wert1=(x-ctx)*zoom*%.2f+%.2f+attr1-5;
23         wert2=(y-cty)*zoom*%.2f+%.2f+attr2-5;
24         roundx=Math.round(wert1*100)/100;
25         roundy=Math.round(wert2*100)/100;
26
27         moveObj.setAttribute("transform","translate("+roundx+","+roundy+")");
28     }
29 }
30
31 function ClickObj(evt)
32 {
33     rect=evt.target.parentNode.getElementsByTagName("rect").item(0);
34     moveObj=evt.target.parentNode;
35     attr1=rect.getAttribute("width")/2;
36     attr2=rect.getAttribute("height")/2;
37     active=true;
38 }
39
40 function OutOfObj(evt)
41 {
42     if (active) {
43         active=false;
44         findAdjacentEdges();
45     }
46 }
47
48 function findAdjacentEdges()
49 {
50     var rectl, rectlid, i, nodenames;
51     rectl = rect;
52     rectlid = rectl.getAttribute("id");
53     for (i=0; i<paths.length; i++) {
54         nodenames = paths.item(i).getAttribute("id").split("-");
55         if (nodenames[0] == rectlid || nodenames[1] == rectlid) {
56             repaintEdge(paths.item(i), nodenames, i);
57         }
58     }
59 }
60
61 function repaintEdge(edge, nodenames, j)
62 {
63     var startnode, endnode, attr, i, k, l, m, alpha, beta;
64     var nodesx, nodesy, nodeex, nodeey, nodesw, nodesh, nodeew, nodeeh;
65     var edgesx, edgesy, edgeex, edgeey, sx, sy, ex, ey;
66
67     //extract node coordinates and dimensions
68     startnode = svgdoc.getElementById(nodenames[0]);
69     nodesw=startnode.getAttribute("width");
70     nodesh=startnode.getAttribute("height");
71     attr = startnode.parentNode.attributes;
72     for (i=0;i<attr.length;i++) {
73         if (attr.item(i).nodeName == "transform") {
74             k = attr.item(i).nodeValue.indexOf("(");
75             l = attr.item(i).nodeValue.indexOf(",");
76             m = attr.item(i).nodeValue.indexOf(")");
77             nodesx = parseFloat(attr.item(i).nodeValue.substring(k+1,l));
78             nodesy = parseFloat(attr.item(i).nodeValue.substring(l+1,m));
79         }
80     }
81     endnode = svgdoc.getElementById(nodenames[1]);
82     nodeew=endnode.getAttribute("width");
83     nodeeh=endnode.getAttribute("height");
84     attr = endnode.parentNode.attributes;
85     for (i=0;i<attr.length;i++) {
86         if (attr.item(i).nodeName == "transform") {
87             k = attr.item(i).nodeValue.indexOf("(");
88             l = attr.item(i).nodeValue.indexOf(",");
89             m = attr.item(i).nodeValue.indexOf(")");
90             nodeex = parseFloat(attr.item(i).nodeValue.substring(k+1,l));
91             nodeey = parseFloat(attr.item(i).nodeValue.substring(l+1,m));
92         }
93     }
94
95     alpha = Math.atan((nodesy-nodeey)/(nodesx-nodeex));
96     if (alpha < 0)
97         alpha += Math.PI;
98
99     //calculate intersection of edge and startNode
100     beta = Math.atan(nodesh/nodesw);
101     if (alpha < beta
102         || (alpha > Math.PI-beta && alpha < Math.PI+beta)
103         || alpha > 2*Math.PI-beta) {
104         //intersection at left or right border
105         if (nodesx < nodeex) {
106             edgesx = nodesx - 0 + nodesw/2;
107         } else {
108             edgesx = nodesx - nodesw/2;
109         }
110         if (nodesy < nodeey) {
111             edgesy = nodesy - 0 + Math.abs(nodesw*Math.tan(alpha)/2);
112         } else {
113             edgesy = nodesy - Math.abs(nodesw*Math.tan(alpha)/2);
114         }
115     } else {
116         //intersection at top or bottom border
117         if (nodesy < nodeey) {
118             edgesy = nodesy - 0 + nodesh/2;
119         } else {
120             edgesy = nodesy - nodesh/2;
121         }
122         if (nodesx < nodeex) {
123             edgesx = nodesx - 0 + Math.abs(nodesh/(2*Math.tan(alpha)));
124         } else {
125             edgesx = nodesx - Math.abs(nodesh/(2*Math.tan(alpha)));
126         }
127     }
128
129     //calculate intersection of edge and endNode
130     beta = Math.atan(nodeeh/nodeew);
131     if (alpha < beta
132         || (alpha > Math.PI-beta && alpha < Math.PI+beta)
133         || alpha > 2*Math.PI-beta) {
134         //intersection at left or right border
135         if (nodesx > nodeex) {
136             edgeex = nodeex - 0 + nodeew/2;
137         } else {
138             edgeex = nodeex - nodeew/2;
139         }
140         if (nodesy > nodeey) {
141             edgeey = nodeey - 0 + Math.abs(nodeew*Math.tan(alpha)/2);
142         } else {
143             edgeey = nodeey - Math.abs(nodeew*Math.tan(alpha)/2);
144         }
145     } else {
146         //intersection at top or bottom border
147         if (nodesy > nodeey) {
148             edgeey = nodeey - 0 + nodeeh/2;
149         } else {
150             edgeey = nodeey - nodeeh/2;
151         }
152         if (nodesx > nodeex) {
153             edgeex = nodeex - 0 + Math.abs(nodeeh/(2*Math.tan(alpha)));
154         } else {
155             edgeex = nodeex - Math.abs(nodeeh/(2*Math.tan(alpha)));
156         }
157     }
158
159     //set new edge coordinates
160     sx=Math.round(edgesx*100)/100;
161     ex=Math.round(edgeex*100)/100;
162     sy=Math.round(edgesy*100)/100;
163     ey=Math.round(edgeey*100)/100;
164
165     if (sx < ex) {
166         if (revert[j] == 1) {
167             revert[j] = 0;
168             flipEdgeMarks(edge);
169         }
170         edge.setAttribute("d","M "+sx+" "+sy+" "+ex+" "+ey);
171     } else {
172         if (revert[j] == 0) {
173             revert[j] = 1;
174             flipEdgeMarks(edge);
175         }
176         edge.setAttribute("d","M "+ex+" "+ey+" "+sx+" "+sy);
177     }
178 }
179
180 function flipEdgeMarks(edge)
181 {
182     var attr, i, j, done, textpaths, pathnamei, offset;
183
184     //revert start- and end-markers
185     attr = edge.attributes;
186     done = 0;
187     for (i=0;i<attr.length;i++) {
188         if (attr.item(i).nodeName == "marker-start") {
189             for (j=i;j<attr.length;j++) {
190                 if (attr.item(j).nodeName == "marker-end") {
191                     done = 1;
192                 }
193             }
194             if (done == 0) {
195                 //start->end
196                 edge.removeAttribute("marker-start");
197                 edge.setAttribute("marker-end","url(#arrowend)");
198                 break;
199             }
200         }
201         if (attr.item(i).nodeName == "marker-end") {
202             for (j=i;j<attr.length;j++) {
203                 if (attr.item(j).nodeName == "marker-start") {
204                     done = 1;
205                 }
206             }
207             if (done == 0) {
208                 //end->start
209                 edge.removeAttribute("marker-end");
210                 edge.setAttribute("marker-start","url(#arrowstart)");
211                 break;
212             }
213         }
214     }
215
216     //revert cardinalities
217     textpaths = svgdoc.getElementsByTagName("textPath");
218     for (i=0;i<textpaths.length;i++) {
219         pathname = textpaths.item(i).getAttribute("xlink:href").replace(/#/,"");
220         if (pathname == edge.getAttribute("id")) {
221             offset = textpaths.item(i).getAttribute("startOffset").substr(0,2);
222             textpaths.item(i).setAttribute("startOffset",100 - offset + "%")
223         }
224     }
225 }
226
227 function getSVGDoc(load_evt)
228 {
229     svgdoc=load_evt.target.ownerDocument;
230     svgroot=svgdoc.documentElement;
231     texte=svgdoc.getElementById("tooltip").getElementsByTagName("text");
232     for (i=1; i<%i; i++) {
233         textNode=texte.item(1).cloneNode("true");
234         svgdoc.getElementById("tooltip").appendChild(textNode);
235     }
236     texte=svgdoc.getElementById("tooltip").getElementsByTagName("text");
237 }
238
239 function ShowTooltipMZ(mousemove_event,txt)
240 {
241     var ttrelem,tttelem,ttline,posx,posy,curtrans,ctx,cty,txt;
242     var maxbreite,tmp,i;
243     ttrelem=svgdoc.getElementById("ttr");
244     tttelem=svgdoc.getElementById("ttt");
245     ttline=svgdoc.getElementById("ttl");
246     posx=mousemove_event.clientX;
247     posy=mousemove_event.clientY;
248     for (i=1;i<=%i;i++)
249         texte.item(i).firstChild.data="";
250     tttelem.childNodes.item(0).data="";
251     tmp=txt.split("\n");
252     maxbreite=0;
253     for (i=0;i<tmp.length;i++) {
254         if (tmp[i]=="")
255             continue;
256         tttelem.childNodes.item(0).data=tmp[i];
257         if (maxbreite<tttelem.getComputedTextLength())
258             maxbreite=tttelem.getComputedTextLength();
259     }
260     curtrans=svgroot.currentTranslate;
261     ctx=curtrans.x;
262     cty=curtrans.y;
263     ttrelem.setAttribute("x",posx-ctx+10);
264     ttrelem.setAttribute("y",posy-cty-20+10);
265     ttrelem.setAttribute("width",maxbreite*0.92+10);
266     ttrelem.setAttribute("height",tmp.length*15+3);
267     ttrelem.setAttribute("style",
268                             "fill: #FFC; stroke: #000; stroke-width: 0.5px");
269     for (i=1; i<=tmp.length; i++) {
270         if (tmp[i-1]=="-- -- --") {
271             ttline.setAttribute("x1", posx-ctx+10);
272             ttline.setAttribute("y1", parseInt(i-1)*15+posy-cty);
273             ttline.setAttribute("x2", posx-ctx+10+maxbreite*0.92+10);
274             ttline.setAttribute("y2", parseInt(i-1)*15+posy-cty);
275             ttline.setAttribute("style", "stroke: #000; stroke-width: 0.5px");
276         } else {
277             texte.item(i).firstChild.data=tmp[i-1];
278             texte.item(i).setAttribute("x",posx-ctx+15);
279             texte.item(i).setAttribute("y",parseInt(i-1)*15+posy-cty+3);
280             texte.item(i).setAttribute("style","fill: #00E; font-size: 11px");
281         }
282     }
283     svgdoc.getElementById("tooltip").style.setProperty("visibility","visible");
284 }
285
286 function HideTooltip()
287 {
288     svgdoc.getElementById("ttl").style.setProperty("visibility","hidden");
289     svgdoc.getElementById("tooltip").style.setProperty("visibility","hidden");
290 }
291
292 function ZoomControl()
293 {
294     var curzoom;
295     curzoom=svgroot.currentScale;
296     svgdoc.getElementById("tooltip").setAttribute("transform",
297                                                         "scale("+1/curzoom+")");
298     zoom=1/curzoom;
299 }
300
301 function collapse(evt)
302 {
303     var i, k, l, m, svgdoc, obj, targetID, targetX, targetY, attr;
304     obj = evt.getTarget();
305     svgdoc = obj.ownerDocument;
306     //extract coordinates and id of the clicked text
307     attr = obj.parentNode.parentNode.attributes;
308     for (i=0;i<attr.length;i++) {
309         if (attr.item(i).nodeName == "transform") {
310             k = attr.item(i).nodeValue.indexOf("(");
311             l = attr.item(i).nodeValue.indexOf(",");
312             m = attr.item(i).nodeValue.indexOf(")");
313             targetX = attr.item(i).nodeValue.substring(k+1,l);
314             targetY = attr.item(i).nodeValue.substring(l+1,m);
315         }
316         if (attr.item(i).nodeName == "id") {
317             targetID = attr.item(i).nodeValue.substr(2);
318         }
319     }
320     //decide if we are collapsing or uncollapsing
321     if (collapsed[0][targetID] == 0) {
322         hideInfos(evt, obj, svgdoc, targetX, targetY, targetID, attr);
323         collapsed[0][targetID] = 1;
324     } else {
325         showHiddenInfos(evt, obj, svgdoc, targetX, targetY, targetID, attr);
326         collapsed[0][targetID] = 0;
327     }
328 }
329
330 function showHiddenInfos(evt, obj, svgdoc, targetX, targetY, targetID, attr)
331 {
332     var i, k, l, m, nextObj, nextX, nextY, gapY=0, clickedID;
333     //change clicked text
334     obj.firstChild.data="--";
335     targetID++;
336     nextObj = svgdoc.getElementById("MI"+targetID);
337     if (nextObj == null)
338         return;
339     //show child texts again
340     for (;;) {
341         attr = nextObj.attributes;
342         for (i=0;i<attr.length;i++) {
343             if (attr.item(i).nodeName == "transform") {
344                 k = attr.item(i).nodeValue.indexOf("(");
345                 l = attr.item(i).nodeValue.indexOf(",");
346                 m = attr.item(i).nodeValue.indexOf(")");
347                 nextX = attr.item(i).nodeValue.substring(k+1,l);
348                 nextY = attr.item(i).nodeValue.substring(l+1,m);
349             }
350         }
351         if (nextX > targetX) {
352             nextObj.style.setProperty("visibility","visible");
353             gapY += 15;
354             if (collapsed[0][targetID] == 1) {
355                 targetID = collapsed[1][targetID];
356             } else {
357                 targetID++;
358             }
359             nextObj = svgdoc.getElementById("MI"+targetID);
360             if (nextObj == null)
361                 break;
362         } else {
363             break;
364         }
365     }
366     if (nextObj == null)
367         return;
368     //move following texts downwards
369     while (nextObj != null) {
370         attr = nextObj.attributes;
371         for (i=0;i<attr.length;i++) {
372             if (attr.item(i).nodeName == "transform") {
373                 k = attr.item(i).nodeValue.indexOf("(");
374                 l = attr.item(i).nodeValue.indexOf(",");
375                 m = attr.item(i).nodeValue.indexOf(")");
376                 nextX = attr.item(i).nodeValue.substring(k+1,l);
377                 nextY = attr.item(i).nodeValue.substring(l+1,m);
378             }
379         }
380         nextY = nextY - 1 + gapY + 1;
381         nextObj.setAttribute("transform","translate("+nextX+","+nextY+")");
382         targetID++;
383         nextObj = svgdoc.getElementById("MI"+targetID);
384     }
385 }
386
387 function hideInfos(evt, obj, svgdoc, targetX, targetY, targetID, attr)
388 {
389     var i, k, l, m, nextObj, nextX, nextY, gapY=0;
390     clickedID = targetID;
391     //change clicked text
392     obj.firstChild.data="+";
393     targetID++;
394     nextObj = svgdoc.getElementById("MI"+targetID);
395     if (nextObj == null)
396         return;
397     //wipe out child texts
398     for (;;) {
399         attr = nextObj.attributes;
400         for (i=0;i<attr.length;i++) {
401             if (attr.item(i).nodeName == "transform") {
402                 k = attr.item(i).nodeValue.indexOf("(");
403                 l = attr.item(i).nodeValue.indexOf(",");
404                 m = attr.item(i).nodeValue.indexOf(")");
405                 nextX = attr.item(i).nodeValue.substring(k+1,l);
406                 nextY = attr.item(i).nodeValue.substring(l+1,m);
407             }
408         }
409         if (nextX > targetX) {
410             nextObj.style.setProperty("visibility","hidden");
411             gapY += 15;
412             if (collapsed[0][targetID] == 1) {
413                 targetID = collapsed[1][targetID];
414             } else {
415                 targetID++;
416             }
417             nextObj = svgdoc.getElementById("MI"+targetID);
418             if (nextObj == null)
419                 break;
420         } else {
421             break;
422         }
423     }
424     //save next uncollapsed element in array
425     collapsed[1][clickedID] = targetID;
426     if (nextObj == null)
427         return;
428     //move following texts upwards
429     while (nextObj != null) {
430         attr = nextObj.attributes;
431         for (i=0;i<attr.length;i++) {
432             if (attr.item(i).nodeName == "transform") {
433                 k = attr.item(i).nodeValue.indexOf("(");
434                 l = attr.item(i).nodeValue.indexOf(",");
435                 m = attr.item(i).nodeValue.indexOf(")");
436                 nextX = attr.item(i).nodeValue.substring(k+1,l);
437                 nextY = attr.item(i).nodeValue.substring(l+1,m);
438             }
439         }
440         nextY -= gapY;
441         nextObj.setAttribute("transform","translate("+nextX+","+nextY+")");
442         targetID++;
443         nextObj = svgdoc.getElementById("MI"+targetID);
444     }
445 }
446
447 function init(evt)
448 {
449     var nodenames, startnode, endnode, attr, i, j, k, l, m, nodesx, nodeex;
450     collapsed[0] = new Array(%i);
451     collapsed[1] = new Array(%i);
452     for (i=0; i<%i; i++) {
453         collapsed[0][i] = 0;
454         collapsed[1][i] = 0;
455     }
456     for (i=0; i<%i; i++) {
457         name[i] = "";
458         clickStatus[i] = 0;
459         redCount[i] = 0;
460         salmonCount[i] = 0;
461     }
462     getSVGDoc(evt);
463
464     //check which edges are printed from right to left
465     paths = svgdoc.getElementsByTagName("path");
466     revert = new Array(paths.length);
467     for (j=0; j<paths.length; j++) {
468         nodenames = paths.item(j).getAttribute("id").split("-");
469         startnode = svgdoc.getElementById(nodenames[0]);
470         attr = startnode.parentNode.attributes;
471         for (i=0;i<attr.length;i++) {
472             if (attr.item(i).nodeName == "transform") {
473                 k = attr.item(i).nodeValue.indexOf("(");
474                 l = attr.item(i).nodeValue.indexOf(",");
475                 m = attr.item(i).nodeValue.indexOf(")");
476                 nodesx = parseFloat(attr.item(i).nodeValue.substring(k+1,l));
477             }
478         }
479         endnode = svgdoc.getElementById(nodenames[1]);
480         attr = endnode.parentNode.attributes;
481         for (i=0;i<attr.length;i++) {
482             if (attr.item(i).nodeName == "transform") {
483                 k = attr.item(i).nodeValue.indexOf("(");
484                 l = attr.item(i).nodeValue.indexOf(",");
485                 m = attr.item(i).nodeValue.indexOf(")");
486                 nodeex = parseFloat(attr.item(i).nodeValue.substring(k+1,l));
487             }
488         }
489         if (nodesx > nodeex) {
490             revert[j] = 1;
491         } else {
492             revert[j] = 0;
493         }
494     }
495 }
496
497 function setStatus(evt, color1, color2)
498 {
499     var clickObj = evt.getTarget();
500     var clickObjName = clickObj.getAttribute('id');
501
502     //find i corresponding to the clicked object
503     for (i=0; i<%i; i++) {
504         if (name[i] == "") {
505             name[i] = clickObjName;
506             break;
507         }
508         if (name[i] != clickObjName)
509             continue;
510         break;
511     }
512
513     //toggle click status, color clicked object
514     if (clickStatus[i] == 0) {
515         clickStatus[i] = 1;
516         clickObj.setAttribute("style","fill: "+color1);
517     } else {
518         clickStatus[i] = 0;
519         clickObj.setAttribute("style","fill: "+color2);
520     }
521
522     //adjust color-counter
523     if (color1 == 'red') {
524         if (clickStatus[i] == 1) {
525             redCount[i]++;
526         } else {
527             redCount[i]--;
528         }
529     }
530     if (color1 == 'salmon') {
531         if (clickStatus[i] == 1) {
532             salmonCount[i]++;
533         } else {
534             salmonCount[i]--;
535         }
536     }
537
538     if (clickStatus[i] == 0 && salmonCount[i] > 0) {
539         clickObj.setAttribute("style","fill: salmon");
540     }
541 }
542
543 function changeColor(evt, targetObjName, color1, color2)
544 {
545     var clickObj = evt.getTarget();
546     var clickObjName = clickObj.getAttribute('id');
547     var targetObj = svgDocument.getElementById(targetObjName);
548
549     //find i corresponding to the clicked object
550     for (i=0; i<%i; i++) {
551         if (name[i] != clickObjName)
552             continue;
553         break;
554     }
555
556     //find j corresponding to the target object
557     for (j=0; j<%i; j++) {
558         if (name[j] == "") {
559             name[j] = targetObjName;
560             break;
561         }
562         if (name[j] != targetObjName)
563             continue;
564         break;
565     }
566
567     //adjust color-counter
568     if (color1 == 'red') {
569         if (clickStatus[i] == 1) {
570             redCount[j]++;
571         } else {
572             redCount[j]--;
573         }
574     }
575     if (color1 == 'salmon') {
576         if (clickStatus[i] == 1) {
577             salmonCount[j]++;
578         } else {
579             salmonCount[j]--;
580         }
581     }
582 }
583
584 function colorText(targetObjName, color)
585 {
586     var targetObj = svgDocument.getElementById(targetObjName);
587
588     //find i corresponding to the target object
589     for (i=0; i<%i; i++) {
590         if (name[i] != targetObjName)
591             continue;
592         break;
593     }
594
595     //color text
596     if (i == %i) {
597         targetObj.setAttribute("style","fill: "+color);
598         return;
599     }
600     if (redCount[i] == 0 && salmonCount[i] == 0) {
601         targetObj.setAttribute("style","fill: "+color);
602     }
603     if (salmonCount[i] > 0) {
604         if (color == 'red') {
605             targetObj.setAttribute("style","fill: red");
606         } else {
607             if (redCount[i] > 0) {
608                 targetObj.setAttribute("style","fill: red");
609             } else {
610                 targetObj.setAttribute("style","fill: salmon");
611             }
612         }
613     }
614 }