X
Right Ear Results
Left Ear Results
/**********************************************************************************
*
* Project Name: jsDraw2D (Graphics Library for JavaScript)
* Version: Beta 1.1.0 (17-August-2009) (Uncompressed)
* Project Homepage: http://jsdraw2d.jsfiction.com
* Author: Sameer Burle
* Copyright 2009: jsFiction.com (http://www.jsfiction.com)
* Licensed Under: LGPL
*
* This program (library) is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see
.
*
************************************************************************************/
//jsColor class holds the color information and provides some color related basic functions.
function jsColor()
{
//Member variables
var hex="#000000";
switch(arguments.length)
{
//Hexadecimal Color
case 1:
setHex(arguments[0]);
break;
//RGB Color
case 3:
var red=arguments[0];
var green=arguments[1];
var blue=arguments[2];
hex=rgbToHex(red,green,blue);
if(hex==false)
hex="#000000";
break;
}
//Public Methods
//Set color by specifying the hexa-decimal value.
this.setHex=setHex;
function setHex(hexColor)
{
if(hexColor.charAt(0)=="#")
{
hex=hexColor;
}
else
{
if(isNaN(hexColor))
{
setNamedColor(hexColor.toLowerCase());
}
else
{
hex="#" + hexColor;
}
}
var rgbArray=hexToRgb(hex);
if(!rgbArray)
{
hex="#000000"
}
}
//Get the hexa-decimal value of the object
this.getHex=getHex;
function getHex()
{
return hex;
}
//Set color by specifying the RGB values.
this.setRGB=setRGB;
function setRGB(redValue,greenValue,blueValue)
{
hex=rgbToHex(redValue,greenValue,blueValue);
if(hex==false)
hex="#000000";
}
//Get the RGB values of the object
this.getRGB=getRGB;
function getRGB()
{
return hexToRgb(hex);
}
//Returns new jsColor object with darker color shade
this.getDarkerShade=getDarkerShade;
function getDarkerShade(value)
{
var redValue,greenValue,blueValue;
var resArray=getRGB();
if(!isNaN(value))
{
redValue=parseInt(resArray[0]-value);
greenValue=parseInt(resArray[1]-value);
blueValue=parseInt(resArray[2]-value);
}
if(redValue<0)
redvalue=0;
if(greenvalue<0)
greenvalue=0;
if(bluevalue<0)
bluevalue=0;
return new jscolor(redvalue,greenvalue,bluevalue);
}
//Returns new jscolor object with lighter color shade
this.getlightershade=getLighterShade;
function getlightershade(value)
{
var redvalue,greenvalue,bluevalue;
var resarray=getRGB();
if(!isnan(value))
{
redvalue=parseInt(resArray[0]+value);
greenvalue=parseInt(resArray[1]+value);
bluevalue=parseInt(resArray[2]+value);
}
if(redvalue>255)
redvalue=255;
if(greenvalue>255)
greenvalue=255;
if(bluevalue>255)
bluevalue=255;
return new jscolor(redvalue,greenvalue,bluevalue);
}
//Static-Shared utility methods
//Convert rgb color to hex color
this.rgbtohex=rgbToHex;
function rgbtohex(redvalue, greenvalue, bluevalue)
{
//Check argument values
if(redvalue<0 || redvalue>255 || greenvalue<0 || greenvalue>255 || bluevalue<0 || bluevalue>255)
{
return false;
}
var colordec = math.round(bluevalue) + 256 * math.round(greenvalue) + 65536 * math.round(redvalue);
return "#" + zeropad(colordec.tostring(16),6);
}
//Convert hex color to rgb color
this.hextorgb=hexToRgb;
function hextorgb(hexvalue)
{
var redvalue,greenvalue,bluevalue;
if(hexvalue.charat(0)=="#")
{
hexvalue=hexValue.substring(1,7);
}
redvalue=parseInt(hexValue.substring(0,2),16);
greenvalue=parseInt(hexValue.substring(2,4),16);
bluevalue=parseInt(hexValue.substring(4,6),16);
//Check argument values
if(redvalue<0 || redvalue>255 || greenvalue<0 || greenvalue>255 || bluevalue<0 || bluevalue>255)
{
return false;
}
return new array(redvalue,greenvalue,bluevalue);
}
//Private methods
//Set the color using specified name of the color out of 16 web colors.
function setnamedcolor(colorname)
{
switch(colorname)
{
case "aqua":
hex="#00FFFF";
break;
case "black":
hex="#000000";
break;
case "blue":
hex="#0000FF";
break;
case "fuchsia":
hex="#FF00FF";
break;
case "green":
hex="#008000";
break;
case "gray":
hex="#808080";
break;
case "lime":
hex="#00FF00";
break;
case "maroon":
hex="#800000";
break;
case "navy":
hex="#000080";
break;
case "olive":
hex="#808000";
break;
case "purple":
hex="#800080";
break;
case "red":
hex="#FF0000";
break;
case "silver":
hex="#C0C0C0";
break;
case "teal":
hex="#008080";
break;
case "white":
hex="#FFFFFF";
break;
case "yellow":
hex="#FFFF00";
break;
}
}
//Add zero padding to the left. used for building hexa-decimal string.
function zeropad(val,count)
{
var valzeropad = val + "";
while(valzeropad.length < count)
{
valzeropad = "0" + valzeropad;
}
return valzeropad;
}
}
//jsFont class holds the font information which can be used by other objects in object oriented way.
function jsfont(family,weight,size,style,variant)
{
//Properties: family, weight, size, style and varient with default value null
this.family=null;
this.weight=null;
this.size=null;
this.style=null;
this.variant=null;
if(family && family!="")
this.family=family;
if(weight && weight!="")
this.weight=weight;
if(size && size!="")
this.size=size;
if(style && style!="")
this.style=style;
if(variant && variant!="")
this.variant=variant;
}
//jsPen class holds the drawing pen/stroke information. mainly it holds the color and width values to be used for 2d drawing.
//All draw methods take jspen object as a parameter. acts like a pen for drawing.
function jspen(color,width)
{
this.color=new jscolor(); //color proprty of jscolor type
this.width="1px"; //width property with 1px default value
if(arguments.length>0)
{
this.color=color;
}
if(arguments.length>=2)
{
this.width=width;
}
if(!isnan(width))
{
this.width=width+"px";
}
}
//jsPoint class holds the 2d drawing point information. it holds values of x and y coordinates of the point.
function jspoint(x,y)
{
this.x=0;
this.y=0;
if(arguments.length==2)
{
this.x=x;
this.y=y;
}
}
function jsgraphics(canvasdivelement)
{
//Private member variables
var origin=new jspoint(0,0);
var scale=1;
var coordinatesystem="default"; //Possible values "default" or "cartecian"
var canvasdiv;
if(canvasdivelement)
canvasdiv=canvasDivElement;
else
canvasdiv=document.body; //Document will be used directly for drawing
var griddiv=null;
//Public methods
this.drawline=drawLine;
this.drawrectangle=drawRectangle;
this.fillrectangle=fillRectangle;
this.drawcircle=drawCircle;
this.drawellipse=drawEllipse;
this.fillcircle=fillCircle;
this.fillellipse=fillEllipse;
this.fillarc=fillArc;
this.drawarc=drawArc;
this.drawpolyline=drawPolyline;
this.drawpolygon=drawPolygon;
this.fillpolygon=fillPolygon;
this.drawbezier=drawBezier;
this.drawpolybezier=drawPolyBezier;
this.drawcurve=drawCurve;
this.drawclosedcurve=drawClosedCurve;
this.fillclosedcurve=fillClosedCurve;
this.drawtext=drawText;
this.drawimage=drawImage;
this.clear=clear;
this.showgrid=showGrid;
this.hidegrid=hideGrid;
this.setorigin=setOrigin;
this.getorigin=getOrigin;
this.setscale=setScale;
this.getscale=getScale;
this.setcoordinatesystem=setCoordinateSystem;
this.getcoordinatesystem=getCoordinateSystem;
this.logicaltophysicalpoint=logicalToPhysicalPoint;
//Initialization
//Grid initialization
griddiv=document.createElement("div");
griddiv.style.left="0px";
griddiv.style.top="0px";
if(canvasdiv.clientwidth>0 && canvasdiv.clientheight>0)
{
griddiv.style.width=(parseInt(canvasDiv.clientWidth)-1) + "px";
griddiv.style.height=(parseInt(canvasDiv.clientHeight)-1) + "px";
}
else
{
griddiv.style.width="0px";
griddiv.style.height="0px";
}
griddiv.style.zindex=0;
griddiv.style.position="absolute";
griddiv.style.display="none";
canvasdiv.appendchild(griddiv);
//Origin
function setorigin(point)
{
origin=point;
}
function getorigin()
{
return origin;
}
//Scale
function setscale(value)
{
scale=value;
}
function getscale()
{
return scale;
}
//Coordinate system
function setcoordinatesystem(name)
{
name=name.toLowerCase()
if(name.tolowercase() != "default" && name.tolowercase() != "cartecian")
{
coordinatesystem="default";
}
else
{
coordinatesystem=name;
}
}
function getcoordinatesystem()
{
return coordinatesystem=name;
}
//Conversion of logical point to physical point based on coordinate system, origin and scale.
function logicaltophysicalpoint(point)
{
if(coordinatesystem=="cartecian")
{
return new jspoint(point.x*scale+origin.x,origin.y-point.y*scale)
}
else
{
return new jspoint(point.x*scale+origin.x,point.y*scale+origin.y)
}
}
//Display background grid
function showgrid(range,showrange,color)
{
if(showrange==null)
showrange=true; //range is grid interval. the values will be shown if showrange is true.
var x0,x1,y0,y1;
var isleft=false; //range display on left side of y-axis if true otherwise right side.
var isup=false; //range display above the x-axis if true otherwise below.
griddiv.innerhtml="";
if(!color)
color=new jscolor(200,200,200);
if(!range)
range=Math.round(parseInt(gridDiv.style.width)/10); //If range not specified, use grid with devided by 10 as range.
else
range=range*scale;
var hexcolor=color.getHex();
//If grid height or width is not available, the grid will not be displayed.
if(parseint(griddiv.style.width)<=0 || parseint(griddiv.style.height)<=0)
return;
else
griddiv.style.display="";
x0=parseInt(gridDiv.style.left)
x1=parseInt(gridDiv.style.left)+parseInt(gridDiv.style.width);
y0=parseInt(gridDiv.style.top);
y1=parseInt(gridDiv.style.top)+parseInt(gridDiv.style.height);
//On which side of the axis the range to be displayed is decided based on position of the origin in the canvas.
//Range is displyed on opposite side of the largest section(out of 4 section divided by the 2 axis)
if(origin.x-parseint(griddiv.style.left)<=parseInt(gridDiv.style.left)+gridDiv.offsetWidth-origin.x)
isleft=true
if(origin.y-parseint(griddiv.style.top)<=parseInt(gridDiv.style.top)+gridDiv.offsetHeight-origin.y)
isup=true
var ihtml=new array(); //Holds inner html
var rangefont=new jsfont("arial",null,"9px");
var rangecolor=color.getDarkerShade(150);
var hexrangecolor=rangeColor.getHex();
//Draw the border grids
ihtml[ihtml.length]="
";
ihtml[ihtml.length]="
";
ihtml[ihtml.length]="
";
ihtml[ihtml.length]="
";
var gridheight=gridDiv.offsetHeight;
var gridwidth=gridDiv.offsetWidth;
var lastrangediv; //previous range div
var currentrangediv //current range div
//Draw vertical grid lines
for(var x=(origin.x-x0)
ange;x
=x0)
{
if(x>=x0 && x<=x1)
ihtml[ihtml.length]="";
}
else
{
ihtml[ihtml.length]="";
}
if(showrange && x>=x0 && x y1)
currentRangeDiv.style.top=y1-currentRangeDiv.offsetHeight-1;
}
else
{
if(parseInt(currentRangeDiv.style.top)-currentRangeDiv.offsetHeight-1>y0)
currentRangeDiv.style.top=parseInt(currentRangeDiv.style.top)-currentRangeDiv.offsetHeight-1;
if(parseInt(currentRangeDiv.style.top)<=y0)
currentrangediv.style.top=y0 + 1;
}
currentrangediv.style.visibility="visible";
lastrangediv = currentrangediv;
}
currentrangediv=null;
}
}
lastrangediv = null;
//Draw horizontal grid lines
for(var y=(origin.y-y0)
ange;y<=y1;y+=range)
{
if(y==origin.y)
{
if(y>=y0 && y<=y1)
ihtml[ihtml.length]="";
}
else
iHtml[iHtml.length]="";
if(showRange && y!=origin.y && y>=y0 && y x0)
currentRangeDiv.style.left=parseInt(currentRangeDiv.style.left)-currentRangeDiv.offsetWidth-2;
else
currentRangeDiv.style.left=parseInt(currentRangeDiv.style.left)+1;
if(parseInt(currentRangeDiv.style.left)<=x0)
currentrangediv.style.left=x0 + 1;
}
currentrangediv.style.visibility="visible";
//Hide the overlapping range.
if(isup && parseint(currentrangediv.style.top)+currentrangediv.offsetheight>origin.y-currentRangeDiv.offsetHeight && parseInt(currentRangeDiv.style.top)origin.y && parseInt(currentRangeDiv.style.top)origin.y)
currentrangediv.style.visibility="hidden";
if(origin.y>y1 && parseint(currentrangediv.style.top)+currentrangediv.offsetheight>y1-currentrangediv.offsetheight)
currentrangediv.style.visibility="hidden";
if(!isup && parseint(currentrangediv.style.top)origin.y)
currentrangediv.style.visibility="hidden";
if(!isup && parseint(currentrangediv.style.top)origin.y && parseint(currentrangediv.style.top)";
else if(x0>x1)
linediv.innerhtml="
";
return linediv;
}
//For vertical line
if(x0==x1)
{
if(y0<=y1)
linediv.innerhtml="
";
else if(y0>y1)
linediv.innerhtml="
";
return linediv;
}
var ihtml=new array();
var yarray=new array();
///Pixel height width start
var dx=Math.abs(x1-x0);
var dy=Math.abs(y1-y0);
var pixheight,pixwidth;
var penwidth=parseInt(pen.width);
pixheight=Math.round(Math.sqrt((penWidth*penWidth)/((dy*dy)/(dx*dx)+1)));
pixwidth=Math.round(Math.sqrt(penWidth*penWidth-pixHeight*pixHeight));
if(pixwidth==0)
{
pixwidth=1;
}
if(pixheight==0)
{
pixheight=1;
}
///Pixel height width end
var steep = math.abs(y1 - y0) > Math.abs(x1 - x0);
if (steep)
{
// swap
var tmp=x0;
x0=y0;
y0=tmp;
tmp=x1;
x1=y1;
y1=tmp;
}
if (x0 > x1)
{
// swap
var tmp=x0;
x0=x1;
x1=tmp;
tmp=y0;
y0=y1;
y1=tmp;
}
var deltax = x1 - x0;
var deltay = Math.abs(y1 - y0);
var error = deltax/2;
var ystep;
var y = y0;
if (y0
";
divheight=0;
xp=y;
yp=x;
}
}
if(x==x1)
{
if(divheight!=0)
{
divheight=divHeight+pixHeight;
ihtml[ihtml.length]="