1 line
14 KiB
JavaScript
1 line
14 KiB
JavaScript
var SVG={};SVG.ns="http://www.w3.org/2000/svg";SVG.xlinkns="http://www.w3.org/1999/xlink";SVG.marginBottom=10;SVG.marginTop=15;SVG.marginLeft=10;SVG.marginRight=10;SVG.rounded=false;SVG.x_axis=false;SVG.parent_holder=false;SVG.holder=false;SVG.g=false;SVG.axis=false;SVG.raw_points=[];SVG.labels=[];SVG.x_callback=false;SVG.init=function(q){if(!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1")){alert("Your browser does not support embedded SVG.")}SVG.parent_holder=document.getElementById(q.id);var o=document.createElementNS(SVG.ns,"svg:svg");o.setAttribute("width",q.width);o.setAttribute("height",q.height);o.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink",SVG.xlinkns);SVG.parent_holder.appendChild(o);SVG.holder=SVG.parent_holder.querySelector("svg");var j=document.createElementNS(SVG.ns,"defs");SVG.holder.appendChild(j);if(q.grid==="small"||q.grid==="both"){var p=document.createElementNS(SVG.ns,"pattern");p.setAttribute("id","smallGrid");p.setAttribute("width",8);p.setAttribute("height",8);p.setAttribute("patternUnits","userSpaceOnUse");var h=document.createElementNS(SVG.ns,"path");h.setAttribute("d","M 8 0 L 0 0 0 8");h.setAttribute("fill","none");h.setAttribute("stroke","gray");h.setAttribute("stroke-width","0.5");p.appendChild(h);j.appendChild(p)}if(q.grid==="big"||q.grid==="both"){var g=document.createElementNS(SVG.ns,"pattern");g.setAttribute("id","grid");g.setAttribute("width",80);g.setAttribute("height",80);g.setAttribute("patternUnits","userSpaceOnUse");if(q.grid==="both"){var f=document.createElementNS(SVG.ns,"rect");f.setAttribute("width",80);f.setAttribute("height",80);f.setAttribute("fill","url(#smallGrid)");g.appendChild(f)}var l=document.createElementNS(SVG.ns,"path");l.setAttribute("d","M 80 0 L 0 0 0 80");l.setAttribute("fill","none");l.setAttribute("stroke","gray");l.setAttribute("stroke-width","1");g.appendChild(l);j.appendChild(g)}SVG.grid=q.grid;var k=document.createElementNS(SVG.ns,"marker");k.setAttribute("id","markerArrow");k.setAttribute("markerWidth",13);k.setAttribute("markerHeight",13);k.setAttribute("refX",2);k.setAttribute("refY",6);k.setAttribute("orient","auto");var e=document.createElementNS(SVG.ns,"path");e.setAttribute("d","M2,2 L2,11 L10,6 L2,2");e.setAttribute("fill","gray");k.appendChild(e);j.appendChild(k);SVG.g=document.createElementNS(SVG.ns,"g");SVG.g.setAttribute("transform","translate(0, "+SVG.parent_holder.offsetHeight+") scale(1, -1)");SVG.holder.appendChild(SVG.g);if(q.x_axis===true){SVG.axis=document.createElementNS(SVG.ns,"line");SVG.axis.setAttribute("x1",SVG.marginLeft);SVG.axis.setAttribute("x2",SVG.parent_holder.offsetWidth-13-SVG.marginRight);SVG.axis.setAttribute("stroke","gray");SVG.axis.setAttribute("stroke-width",3);SVG.axis.setAttribute("marker-end",'url("#markerArrow")');SVG.g.appendChild(SVG.axis)}if(SVG.grid!=="none"){var d=document.createElementNS(SVG.ns,"rect");d.setAttribute("width","100%");d.setAttribute("height","100%");if(SVG.grid==="big"||SVG.grid==="both"){d.setAttribute("fill","url(#grid)")}else{d.setAttribute("fill","url(#smallGrid)")}SVG.g.appendChild(d)}SVG.rounded=q.rounded;SVG.x_axis=q.x_axis;SVG.x_callback=q.x_callback;SVG.parent_holder.addEventListener("mousemove",function(v){var s=v||window.event;var u=false;var t=SVG.holder.querySelectorAll(".over");for(u=0;u<t.length;u++){SVG.holder.getElementById(t[u].getAttribute("id").replace("over","point")).setAttribute("r","4");if(SVG.labels[graph][parseInt(t[u].getAttribute("id").replace("over_",""))]!==""){SVG.holder.getElementById(t[u].getAttribute("id").replace("over","label")).setAttribute("display","none")}}SVG.overEffect(s.clientX,s.clientY)})};SVG.hasClass=function(e,d){return(" "+e.getAttribute("class")+" ").indexOf(" "+d+" ")>-1};SVG.overEffect=function(d,f){if(!document.elementFromPoint(d,f)){return}var e=document.elementFromPoint(d,f);if(!SVG.hasClass(e,"over")){return}SVG.holder.getElementById(e.getAttribute("id").replace("over","point")).setAttribute("r","6");if(SVG.labels[graph][parseInt(e.getAttribute("id").replace("over_",""))]!==""){SVG.holder.getElementById(e.getAttribute("id").replace("over","label")).setAttribute("display","block")}e.setAttribute("display","none");SVG.overEffect(d,f);e.setAttribute("display","block")};SVG.newCoordinates=function(h,f,d,g,j){var e=(j-g)/(d-f);return e*h-e*f+g};SVG.scale=function(o){var h=new Array(),g=new Array();var e=new Array(),d=new Array();var u=0,t=0;var f=false,s=false,v=false;var q=false;var p=0;var l=false;var k=false;for(graph in o){q=false;p=0;l=false;k=false;for(point=0;point<o[graph].data.length;point++){u=o[graph].data[point][0];t=o[graph].data[point][1];if(u<q||q===false){q=u}if(u>l||l===false){l=u}if(t<p){p=t}if(t>k||k===false){k=t}}h.push(q);g.push(p);e.push(l);d.push(k)}h=Math.min.apply(null,h);g=Math.min.apply(null,g);e=Math.max.apply(null,e);d=Math.max.apply(null,d);u=SVG.newCoordinates(h+Math.pow(10,Math.floor(Math.log(e-h)/Math.log(10))),h,e,SVG.marginLeft,SVG.parent_holder.offsetWidth-SVG.marginRight)-SVG.newCoordinates(h,h,e,SVG.marginLeft,SVG.parent_holder.offsetWidth-SVG.marginRight);t=SVG.newCoordinates(g+Math.pow(10,Math.floor(Math.log(d-g)/Math.log(10))),g,d,2*SVG.marginBottom,SVG.parent_holder.offsetHeight-SVG.marginTop)-SVG.newCoordinates(g,g,d,2*SVG.marginBottom,SVG.parent_holder.offsetHeight-SVG.marginTop);if(SVG.grid==="big"||SVG.grid==="both"){SVG.holder.getElementById("grid").setAttribute("width",u);SVG.holder.getElementById("grid").setAttribute("height",t);SVG.holder.getElementById("grid").setAttribute("y",SVG.newCoordinates(Math.floor(g/Math.pow(10,Math.floor(Math.log(d-g)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(d-g)/Math.log(10))),g,d,2*SVG.marginBottom,SVG.parent_holder.offsetHeight-SVG.marginTop));SVG.holder.getElementById("grid").setAttribute("x",SVG.newCoordinates(Math.floor(h/Math.pow(10,Math.floor(Math.log(e-h)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(e-h)/Math.log(10))),h,e,SVG.marginLeft,SVG.parent_holder.offsetWidth-SVG.marginRight));SVG.holder.getElementById("grid").querySelector("path").setAttribute("d","M "+u+" 0 L 0 0 0 "+t);if(SVG.grid==="both"){SVG.holder.getElementById("grid").querySelector("rect").setAttribute("width",u);SVG.holder.getElementById("grid").querySelector("rect").setAttribute("height",t)}}if(SVG.grid==="small"||SVG.grid==="both"){u=u/10;t=t/10;SVG.holder.getElementById("smallGrid").setAttribute("width",u);SVG.holder.getElementById("smallGrid").setAttribute("height",t);if(SVG.grid==="small"){SVG.holder.getElementById("smallGrid").setAttribute("y",SVG.newCoordinates(Math.floor(g/Math.pow(10,Math.floor(Math.log(d-g)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(d-g)/Math.log(10))),g,d,2*SVG.marginBottom,SVG.parent_holder.offsetHeight-SVG.marginTop));SVG.holder.getElementById("smallGrid").setAttribute("x",SVG.newCoordinates(Math.floor(h/Math.pow(10,Math.floor(Math.log(e-h)/Math.log(10))))*Math.pow(10,Math.floor(Math.log(e-h)/Math.log(10))),h,e,SVG.marginLeft,SVG.parent_holder.offsetWidth-SVG.marginRight))}SVG.holder.getElementById("smallGrid").querySelector("path").setAttribute("d","M "+u+" 0 L 0 0 0 "+t)}if(SVG.x_axis===true){t=SVG.newCoordinates(0,g,d,2*SVG.marginBottom,SVG.parent_holder.offsetHeight-SVG.marginTop);SVG.axis.setAttribute("y1",t);SVG.axis.setAttribute("y2",t)}var j=new Array();j.minX=h;j.minY=g;j.maxX=e;j.maxY=d;return j};SVG.addGraph=function(e,d){SVG.raw_points[e]={};SVG.raw_points[e].color=d;SVG.raw_points[e].data=new Array();SVG.labels[e]=new Array()};SVG.addPoints=function(e,d){d.sort(function(g,f){if(g.x<f.x){return -1}else{if(g.x==f.x){return 0}else{return 1}}});for(point=0;point<d.length;point++){SVG.raw_points[e].data.push([d[point].x,d[point].y]);if(d[point].label!=="undefined"){SVG.labels[e].push(d[point].label)}else{SVG.labels[e].push("")}}};SVG.getControlPoints=function(d){p1=new Array();p2=new Array();n=d.length-1;a=new Array();b=new Array();c=new Array();r=new Array();a[0]=0;b[0]=2;c[0]=1;r[0]=d[0]+2*d[1];for(i=1;i<n-1;i++){a[i]=1;b[i]=4;c[i]=1;r[i]=4*d[i]+2*d[i+1]}a[n-1]=2;b[n-1]=7;c[n-1]=0;r[n-1]=8*d[n-1]+d[n];for(i=1;i<n;i++){m=a[i]/b[i-1];b[i]=b[i]-m*c[i-1];r[i]=r[i]-m*r[i-1]}p1[n-1]=r[n-1]/b[n-1];for(i=n-2;i>=0;--i){p1[i]=(r[i]-c[i]*p1[i+1])/b[i]}for(i=0;i<n-1;i++){p2[i]=2*d[i+1]-p1[i+1]}p2[n-1]=0.5*(d[n]+p1[n-1]);return{p1:p1,p2:p2}};SVG.draw=function(){var e=SVG.scale(SVG.raw_points);var u=new Array();var q=new Array();var k=false;var s=false;var w=false;var v=false;var t=false;var A="";for(graph in SVG.raw_points){u=new Array();q=new Array();A="";for(w=0;w<SVG.raw_points[graph].data.length;w++){u.push(SVG.newCoordinates(SVG.raw_points[graph].data[w][0],e.minX,e.maxX,SVG.marginLeft,SVG.parent_holder.offsetWidth-SVG.marginRight));q.push(SVG.newCoordinates(SVG.raw_points[graph].data[w][1],e.minY,e.maxY,2*SVG.marginBottom,SVG.parent_holder.offsetHeight-SVG.marginTop))}if(SVG.rounded===true){v=SVG.getControlPoints(u);t=SVG.getControlPoints(q);for(w=0;w<SVG.raw_points[graph].data.length-1;w++){A+="C "+v.p1[w]+" "+t.p1[w]+" "+v.p2[w]+" "+t.p2[w]+" "+u[w+1]+" "+q[w+1]+" "}}else{for(w=1;w<SVG.raw_points[graph].data.length;w++){A+="L "+u[w]+" "+q[w]+" "}}k=document.createElementNS(SVG.ns,"path");k.setAttribute("class","graph");k.setAttribute("fill",SVG.raw_points[graph].color);k.setAttribute("opacity","0.25");k.setAttribute("stroke","none");k.setAttribute("d","M "+u[0]+" "+2*SVG.marginBottom+" L "+u[0]+" "+q[0]+" "+A+" L "+u[SVG.raw_points[graph].data.length-1]+" "+2*SVG.marginBottom+" Z");SVG.g.insertBefore(k,SVG.g.querySelectorAll(".over")[0]);k=document.createElementNS(SVG.ns,"path");k.setAttribute("class","line");k.setAttribute("stroke",SVG.raw_points[graph].color);k.setAttribute("stroke-width",2);k.setAttribute("fill","none");k.setAttribute("d","M "+u[0]+" "+q[0]+" "+A);SVG.g.appendChild(k);for(w=0;w<SVG.raw_points[graph].data.length;w++){k=document.createElementNS(SVG.ns,"circle");k.setAttribute("class","point");k.setAttribute("id","point_"+w+"_"+graph);k.setAttribute("cx",u[w]);k.setAttribute("cy",q[w]);k.setAttribute("r",4);k.setAttribute("fill","#333");k.setAttribute("stroke",SVG.raw_points[graph].color);k.setAttribute("stroke-width",2);SVG.g.insertBefore(k,SVG.g.querySelectorAll(".label")[0]);if(SVG.labels[graph][w]!==""){var l=document.createElementNS(SVG.ns,"g");l.setAttribute("class","label");l.setAttribute("id","label_"+w+"_"+graph);l.setAttribute("transform","translate(0, "+SVG.parent_holder.offsetHeight+") scale(1, -1)");SVG.g.appendChild(l);k=document.createElementNS(SVG.ns,"text");var z=SVG.labels[graph][w].replace("</sup>","<sup>").split("<sup>");var j=0;var h=false;for(j=0;j<z.length;j++){z[j]=z[j].replace(/(<([^>]+)>)/ig,"").replace("%y",SVG.raw_points[graph].data[w][1]).replace("%x",SVG.raw_points[graph].data[w][0]);if(j%2==0){k.appendChild(document.createTextNode(z[j]))}else{h=document.createElementNS(SVG.ns,"tspan");h.setAttribute("dy","-5");h.appendChild(document.createTextNode(z[j]));k.appendChild(h)}}var A=document.createElementNS(SVG.ns,"path");A.setAttribute("stroke","black");A.setAttribute("stroke-width",2);A.setAttribute("fill","white");A.setAttribute("opacity",0.5);l.appendChild(A);l.appendChild(k);var f=u[w]-k.getBoundingClientRect().width/2;var p=SVG.parent_holder.offsetHeight-q[w]-20;var o=k.getBoundingClientRect().width;var d=k.getBoundingClientRect().height;if(u[w]-k.getBoundingClientRect().width/2<0){f=u[w]+20;p=SVG.parent_holder.offsetHeight-q[w]+5;A.setAttribute("d","M "+(f-5)+" "+(p+5)+" L "+(f-5)+" "+(p-d/2+7.5)+" L "+(f-10)+" "+(p-d/2+5)+" L "+(f-5)+" "+(p-d/2+2.5)+" L "+(f-5)+" "+(p-d+5)+" L "+(f+o+5)+" "+(p-d+5)+" L "+(f+o+5)+" "+(p+5)+" Z")}else{if(q[w]+k.getBoundingClientRect().height+12>SVG.parent_holder.offsetHeight){f=u[w]+20;p=SVG.parent_holder.offsetHeight-q[w]+5;A.setAttribute("d","M "+(f-5)+" "+(p+5)+" L "+(f-5)+" "+(p-d/2+7.5)+" L "+(f-10)+" "+(p-d/2+5)+" L "+(f-5)+" "+(p-d/2+2.5)+" L "+(f-5)+" "+(p-d+5)+" L "+(f+o+5)+" "+(p-d+5)+" L "+(f+o+5)+" "+(p+5)+" Z");if(f+o>SVG.parent_holder.offsetWidth){f=u[w]-o-20;p=SVG.parent_holder.offsetHeight-q[w]+5;A.setAttribute("d","M "+(f-5)+" "+(p+5)+" L "+(f-5)+" "+(p-d+5)+" L "+(f+o+5)+" "+(p-d+5)+" L "+(f+o+5)+" "+(p-d/2+2.5)+" L "+(f+o+10)+" "+(p-d/2+5)+" L "+(f+o+5)+" "+(p-d/2+7.5)+" L "+(f+o+5)+" "+(p+5)+" Z")}}else{if(u[w]+o/2+12>SVG.parent_holder.offsetWidth){f=u[w]-o-20;p=SVG.parent_holder.offsetHeight-q[w]+5;A.setAttribute("d","M "+(f-5)+" "+(p+5)+" L "+(f-5)+" "+(p-d+5)+" L "+(f+o+5)+" "+(p-d+5)+" L "+(f+o+5)+" "+(p-d/2+2.5)+" L "+(f+o+10)+" "+(p-d/2+5)+" L "+(f+o+5)+" "+(p-d/2+7.5)+" L "+(f+o+5)+" "+(p+5)+" Z")}else{A.setAttribute("d","M "+(f-5)+" "+(p+5)+" L "+(f-5)+" "+(p-d+5)+" L "+(f+o+5)+" "+(p-d+5)+" L "+(f+o+5)+" "+(p+5)+" L "+(f+o/2+2.5)+" "+(p+5)+" L "+(f+o/2)+" "+(p+10)+" L "+(f+o/2-2.5)+" "+(p+5)+" Z")}}}k.setAttribute("x",f);k.setAttribute("y",p);l.setAttribute("display","none")}}for(w=0;w<SVG.raw_points[graph].data.length;w++){s=document.createElementNS(SVG.ns,"rect");s.setAttribute("class","over");s.setAttribute("id","over_"+w+"_"+graph);if(w==0){s.setAttribute("x",0)}else{s.setAttribute("x",(u[w]+u[w-1])/2)}s.setAttribute("y",0);s.setAttribute("fill","white");s.setAttribute("opacity","0");if(w==SVG.raw_points[graph].data.length-1){s.setAttribute("width",SVG.parent_holder.offsetWidth-(u[w]+u[w-1])/2)}else{if(w==0){s.setAttribute("width",(u[1]+u[0])/2+SVG.marginLeft)}else{s.setAttribute("width",(u[w+1]-u[w-1])/2)}}s.setAttribute("height","100%");SVG.g.appendChild(s);if(SVG.x_callback!==false){k=document.createElementNS(SVG.ns,"text");k.setAttribute("class","legend_x");k.setAttribute("fill","gray");k.setAttribute("transform","translate(0, "+SVG.parent_holder.offsetHeight+") scale(1, -1)");k.appendChild(document.createTextNode(SVG.x_callback(u[w])));SVG.g.appendChild(k);k.setAttribute("x",u[w]-k.getBoundingClientRect().width/2+2.5);k.setAttribute("y",SVG.parent_holder.offsetHeight-SVG.marginBottom-SVG.newCoordinates(0,e.minY,e.maxY,2*SVG.marginBottom,SVG.parent_holder.offsetHeight-SVG.marginTop));k=document.createElementNS(SVG.ns,"line");k.setAttribute("class","legend_x");k.setAttribute("stroke","gray");k.setAttribute("stroke-width",2);k.setAttribute("x1",u[w]);k.setAttribute("x2",u[w]);k.setAttribute("y1",SVG.newCoordinates(0,e.minY,e.maxY,2*SVG.marginBottom,SVG.parent_holder.offsetHeight-SVG.marginTop)-5);k.setAttribute("y2",SVG.newCoordinates(0,e.minY,e.maxY,2*SVG.marginBottom,SVG.parent_holder.offsetHeight-SVG.marginTop)+5);SVG.g.appendChild(k)}}}};window.onresize=function(){if(SVG.g!==false){SVG.g.setAttribute("transform","translate(0, "+SVG.parent_holder.offsetHeight+") scale(1, -1)");if(SVG.x_axis===true){SVG.axis.setAttribute("x2",SVG.parent_holder.offsetWidth-13-SVG.marginRight)}[].forEach.call(SVG.holder.querySelectorAll(".label, .over, .point, .line, .graph, .legend_x"),function(d){d.parentNode.removeChild(d)});SVG.draw()}}; |