/* ===================================================================================================*/
/* xymeter-Applet */
/* V. 1.0 15.07.1997 */
/* JaR:/ R. Moros : */
/* University of Leipzig */
/* Inst. of Technical Chemistry (ITC-Leipzig) */
/* e-mail: moros@sonne.tachemie.uni-leipzig.de */
/* Home-Page: http://techni.tachemie.uni-leipzig.de/~jar/ */
/* ITC-Page: http://techni.tachemie.uni-leipzig.de */
/* */
/* --------------------------------------------------------------------------------------------------- */
/* */
/* */
/* Permission to use, copy, modify and distribute this software or a part of this */
/* and its documentation without fee for NON-COMMERCIAL purposes is hereby */
/* granted provided that this notice with a reference to the original source */
/* andthe author appears in all copies or derivatives of this software. */
/* */
/* -----------------------------------------------------------------------------------------------------*/
/* Set the main parameters of the XY-Meter by using */
/* 1)Applet-Parameter */
/* NAME TYPE DEFAULT */
/* header [String] "" */
/* xtitle [String] "" */
/* ytitle [String] "" */
/* onlyy [String] true: only y-values are false */
/* x is calculated based on the */
/* xold + Period */
/* false:x-y-pairs are used */
/* yfrom [float] begin of range y (Y-Min) 0 */
/* yto [float] end of range y (Y-Max) 100 */
/* xfrom [float] begin of range x 0 */
/* xto [float] end of range x 100 */
/* xperiod[float] set the period of x (if onlyy=true) 1 */
/* hbgcol [String] backgr.-color header "lightgray" */
/* hfgcol [String] foregroundcol. header "black" */
/* abgcol [String] backgroundcol. analog "lightgray" */
/* afgcol [String] foregroundcol. analog "black" */
/* maxlin [int] number of lines 1 */
/* lincol [String] color of lines xy-pairs "blue" */
/* example: maxlin=3 lincol="blue,red,green" */
/* */
/* 2) - a number of methods that can be used via JavaScript */
/* SetParameter, SetColors, SetLineColor, .. */
/* detailed description http://techni.tachemie.uni-leipzig.de/~jar/jjsappl_e.html */
/* */
/* LIST of COLORS are used for SetLineColor, SetColors : */
/* "white","black","lightgray","gray","darkgray","red","green","blue" */
/* "yellow","magenta","cyan","pink","orange" */
/* */
/* */
/* -------------------------------------------------------------------------------- */
/* Draw a function */
/* Using the methods SetMeterXY, SetMeterY, DrawMeterXY, DrawMeterY via JavaScript */
/* detailed description: http://techni.tachemie.uni-leipzig.de/~jar/jjsappl_e.html */
/* */
/* 1) document.utmeter.DrawMeterXY(int lin, double x, double y); */
/* draw from xold, yold to x,y / lin: number of line */
/* */
/* 2) document.utmeter.DrawMeterY(int lin, double y); */
/* if the mode is "onlyy=true" (Set by using SetXYMode) then this methode is be used for drawing*/
/* x will be calculated by using the former value of x and the "XPeriod" x=xold+XPeriod */
/* */
/* ==================================================================================================== */
import java.awt.*;
import java.applet.Applet;
import java.util.StringTokenizer;
public class xymeter extends Applet implements Runnable
{
Thread runner;
int delayGlb= 0; // the refresh/update time
int Mhe;
int Mwi;
int Hhe; //height of Header
int Hhemax = 20;
int Ahe; // height of Analog
//the borders of the y-axis and x-axis
int borderY0; //Y-down
int borderY1; //Y-up
int borderX0; //X-left
int borderX1; //X-right
int wborder_l,wborder_r; //free space left,right
int hborder; // free space top
int xaroot = 0; //the point 0,0 of the analog part
int yaroot = 0;
int xs0,ys0;
int xs1,ys1;
int xs2,ys2;
int XMarkerSpace = 0; //between 2 x-markers
int XMarkerLength = 0;
int YMarkerSpace = 0; //between 2 y-markers
int YMarkerLength = 0;
double YMin;
double YMax;
double DeltaY; //the range of y
double yfak; // to transsform WC->BC
double DeltaX;
double XMin;
double XMax;
double XPeriod; //if onlyy=true -> memory of the period between 2 x
double xfak; //to transform WC->BC
boolean WHeader = true; // true : with header
boolean WXTitle = false; // true: with X-Title
boolean WYTitle = false; // true: with Y-Title
boolean WFloatingX= true; // true:
boolean XYPairs = true; // true: x-y pairs
String Header;
String XTitle;
String YTitle;
String iStr;
boolean CHANGED;
boolean ALLPOINTS; //true: print all points
//Colors
Color HBGColor; // Header Background
Color HFGColor; // Header Foreground
Color ABGColor; // Analog Background
Color AFGColor; // Analog Foreground;
Color LINColor[]; // Color of the lines between the xy-pairs
//double-buffering
Image oimg;
Graphics og;
//the memory of the value
int maxLines=1; // number of lines/functions
int maxPairs=100; // = 400; // the max. numbers of XY-pairs
double YArr[]; // = new double [maxPairs]; // the Y-Memory
double XArr[]; // = new double [maxPairs]; // the X-Memory
int Index[]; // the index of xy(k)
int IBegin[];
int IEnd[];
double YNew[];
double YOld[];
double XNew[];
double XOld[];
// Applet Info
public String getAppletInfo() {
return "xymeter.java, V 1.0 07.97 by Ralf Moros / JaR, http://techni.tachemie.uni-leipzig.de/~jar/";
}
//init 1
public void InitGlobalPar1()
{
if (WHeader==true) {Hhe = Mhe / 6;
if (Hhe>Hhemax) {Hhe=Hhemax;}
} // height of the header
else Hhe=0;
//Analog
Ahe = Mhe - Hhe; // height of the analog instrument
xaroot = 0; // lower left corner x
yaroot = Hhe+Ahe-1; // lower left corner y
wborder_l = Mwi/8; // calculate all ness. variables
wborder_r = Mwi/12; // in order to print the analog values
hborder = Ahe / 10; // into the yt-system
xs0 = xaroot + wborder_l; // borders & corners
ys0 = yaroot - hborder;
xs1 = Mwi - wborder_r;
ys1 = ys0;
xs2 = xs0;
ys2 = yaroot - (9*hborder);
XMarkerSpace = (xs1-xs0)/10; // between 2 marker sticks
XMarkerLength = 5; // the length of a marker stick
if (XMarkerLength > (hborder/2)) {XMarkerLength=hborder/2;}
YMarkerSpace = (ys0-ys2)/10; //between 2 marker sticks
YMarkerLength = 5; //the length of a marker stick
if (YMarkerLength > (wborder_l/2)) {YMarkerLength= wborder_l/2;}
borderX0 = xs0;
borderX1 = xs0+10*XMarkerSpace;
borderY0 = ys0;
borderY1 = ys0-10*YMarkerSpace;
//calculate the faktors tfak, yfak
//in order to transform twc->tbc ywc->ybc
xfak = (borderX1 - borderX0) / DeltaX;
yfak = (borderY0 - borderY1) / DeltaY;
}//End InitGlobalPar1
//INIT GENERAL
public void init()
{ StringTokenizer st;
String st1;
// Set Colors
HBGColor = Color.lightGray;
ABGColor = Color.lightGray;
HFGColor = Color.black;
AFGColor = Color.black;
// INIT - PARAMETER
iStr = getParameter("header");
if (iStr != null) {WHeader = true;
Header = iStr;
}
else {WHeader = false;
Header = "";
}
iStr = getParameter("xtitle");
if (iStr != null) {XTitle = iStr;WXTitle=true;}
else {XTitle = "";WXTitle=false;}
iStr = getParameter("ytitle");
if (iStr != null) {YTitle = iStr; WYTitle=true;}
else {YTitle = "";WYTitle=false;}
iStr = getParameter("onlyy");
if (iStr != null) {if (iStr.equals("false")) XYPairs = true;
else XYPairs = false;
}
else {XYPairs = true;}
iStr = getParameter("yfrom");
if (iStr != null) {YMin = Float.valueOf(iStr).floatValue();}
else {YMin = 0;}
iStr = getParameter("yto");
if (iStr != null) {YMax = Float.valueOf(iStr).floatValue();}
else {YMax = 100;}
//Calc. the range of Y --> DeltaY
if ((YMax>=0) & (YMin>=0)) {DeltaY = YMax-YMin;}
else {if ((YMax>=0) & (YMin<0)) {DeltaY = YMax-YMin;
}
else {DeltaY = Math.abs(YMin-YMax);
}
}
iStr = getParameter("xfrom");
if (iStr != null) {XMin = Float.valueOf(iStr).floatValue();}
else {XMin = 0;}
iStr = getParameter("xto");
if (iStr != null) {XMax = Float.valueOf(iStr).floatValue();}
else {XMax = 100;}
//Calc. the range of X --> DeltaX
if ((XMax>=0) & (XMin>=0)) {DeltaX = XMax-XMin;}
else {if ((XMax>=0) & (XMin<0)) {DeltaX = XMax-XMin;
}
else {DeltaX = Math.abs(XMin-XMax);
}
}
iStr = getParameter("xperiod");
if (iStr != null) {XPeriod = Float.valueOf(iStr).floatValue();}
else {XPeriod = 1;}
iStr = getParameter("xypairs");
if (iStr != null) {maxPairs= Integer.valueOf(iStr).intValue();}
else {maxPairs = 100;}
// COLOR-Parameters
iStr = getParameter("hbgcol");
if (iStr != null) {HBGColor = WhichColor(HBGColor,iStr);}
iStr = getParameter("hfgcol");
if (iStr != null) {HFGColor = WhichColor(HFGColor,iStr);}
iStr = getParameter("abgcol");
if (iStr != null) {ABGColor = WhichColor(ABGColor,iStr);}
iStr = getParameter("afgcol");
if (iStr != null) {AFGColor = WhichColor(AFGColor,iStr);}
iStr = getParameter("maxlin");
if (iStr != null) {maxLines= Integer.valueOf(iStr).intValue();}
else {maxLines=1;}
LINColor = new Color [maxLines];
for (int i=0; i DeltaY
if ((YMax>=0) & (YMin>=0)) {DeltaY = YMax-YMin;}
else {if ((YMax>=0) & (YMin<0)) {DeltaY = YMax-YMin;
}
else {DeltaY = Math.abs(YMin-YMax);
}
}
//Recalc. the range of X --> DeltaX
if ((XMax>=0) & (XMin>=0)) {DeltaX = XMax-XMin;}
else {if ((XMax>=0) & (XMin<0)) {DeltaX = XMax-XMin;
}
else {DeltaX = Math.abs(XMin-XMax);
}
}
//Recalculation
InitGlobalPar1();
//
CHANGED = false;
repaint();
} // End of SetParameter
public void SetParameter(String head,
String xtitle,
String ytitle,
float xfrom,
float xto,
float yfrom,
float yto,
String onlyy,
float xperiod,
int maxXY,
int maxLin,
String lincols,
String seperator
)
{StringTokenizer st;
String st1;
maxLines = maxLin;
LINColor = new Color [maxLines];
st = new StringTokenizer(lincols,seperator);
for (int i=0; i DeltaY
if ((YMax>=0) & (YMin>=0)) {DeltaY = YMax-YMin;}
else {if ((YMax>=0) & (YMin<0)) {DeltaY = YMax-YMin;
}
else {DeltaY = Math.abs(YMin-YMax);
}
}
//Recalc. the range of X --> DeltaX
if ((XMax>=0) & (XMin>=0)) {DeltaX = XMax-XMin;}
else {if ((XMax>=0) & (XMin<0)) {DeltaX = XMax-XMin;
}
else {DeltaX = Math.abs(XMin-XMax);
}
}
//Recalc. of the scaling factors
xfak = (borderX1 - borderX0) / DeltaX;
yfak = (borderY0 - borderY1) / DeltaY;
//Repaint
CHANGED = false;
repaint();
}//End of SetXYRange
//SetXYMode
//this methode is used to set the mode of xy
// onlyy=true -> x is calculated based on xold + xperiod
//using via Javascript: document.meter.SetXYMode(onlyy,xperiod)
public void SetXYMode(String onlyy,
float xperiod
)
{if (onlyy.equals("false")==true) XYPairs=true;
else XYPairs=false;
XPeriod = xperiod;
}//End of SetXYMode
//SetHeader
//this methode is used to set and change the header of the meter..
//using via Javascript: document.meter.SetHeader(header)
public void SetHeader(String head)
{ Header = head;
if (Header.length()==0) WHeader=false;
else WHeader=true;
//Recalculation
InitGlobalPar1();
//
CHANGED = false;
repaint();
}//End of SetHeader
//SetXYTitle
//this methode is used to set and change the title of the x and/or y axis
//using via Javascript: document.meter.SetXYTitle(xtitle,ytitle)
public void SetXYTitle(String xtitle, String ytitle)
{ XTitle = xtitle;
if (XTitle.length()==0) WXTitle=false;
else WXTitle=true;
YTitle = ytitle;
if (YTitle.length()==0) WYTitle=false;
else WYTitle=true;
CHANGED = false;
repaint();
}//End of SetXYTitle
/* ================= TRANSFORM WC-> BC ======================== */
// TransformX
// transform X[double] -> X[int] ::: from xwc -> to xbc
public int TransformX(double xwc)
{ int xn = 0;
double x = 0;
xn = borderX0 + (int) Math.round(xfak * (xwc-XMin));
return xn;
}//End of TransformT
// TransformY
// transform Y[bouble] -> Y[int] ::: ywc -> ybc
public int TransformY(double ywc)
{ int yn = 0;
double y = 0;
yn = borderY0 - (int) Math.round(yfak*(ywc-YMin));
return yn;
} //End of TransformY
/* ============== Set the Meter ======================================== */
// DRAWMETERY
//
// Set the y value of line "line" and draw the line
// document.meter.DrawMeterY(int line,double V) (JavaScript)
// if onlyy=true -> x is calculated
public void DrawMeterY(int line,double V)
{ YNew[line-1] = V;
XNew[line-1] = XOld[line-1] + XPeriod;
ALLPOINTS = false;
if (Index[line-1] == (maxPairs-1)) {Index[line-1]=0;} // too many points
else {Index[line-1]++;}
int i=Index[line-1]+((line-1)*maxPairs);
YArr[i]=YNew[line-1];
XArr[i]=XNew[line-1];
CHANGED =true;
repaint();
}// END of DRAWMETERY
// SETMETERY
// Set the y value (number of line is "line") of the meter without drawing
// document.meter.SetMeterY(int line, double V) (JavaScript)
// if onlyy=true -> x is calculated
public void SetMeterY(int line,double V)
{ YNew[line-1] = V;
XNew[line-1] = XOld[line-1] + XPeriod;
ALLPOINTS = false;
if (Index[line-1] == (maxPairs-1)) {Index[line-1]=0;} // too many points
else {Index[line-1]++;}
int i=Index[line-1]+((line-1)*maxPairs);
YArr[i]=YNew[line-1];
XArr[i]=XNew[line-1];
CHANGED = true;
}// END of SETMETERY
// DRAWMETERXY
// Set a (x,y)-pair (number of line: "line") of the xy-meter via and draw the line
// document.meter.DrawMeterXY(int line,double x, double y) (JavaScript)
public void DrawMeterXY(int line, double x, double y)
{ YNew[line-1] = y;
XNew[line-1] = x;
ALLPOINTS = false;
if (Index[line-1]== (maxPairs-1)) {Index[line-1] = 0; //too many ponts
}
else {Index[line-1]++;}
int i=Index[line-1]+((line-1)*maxPairs);
YArr[i]=YNew[line-1];
XArr[i]=XNew[line-1];
CHANGED = true;
repaint();
}//End of DrawMeterYT
// SETMETERXY
// Set a (x,y)-pair (from line "line") of the xy-meter via without drawing
// document.meter.SetMeterXY(int line, double x, double y) (JavaScript)
public void SetMeterXY(int line, double x, double y)
{
YNew[line-1] = y;
XNew[line-1] = x;
ALLPOINTS = false;
if (Index[line-1]== (maxPairs-1)) {Index[line-1] = 0; //too many ponts
}
else {Index[line-1]++;}
int i=Index[line-1]+((line-1)*maxPairs);
YArr[i]=YNew[line-1];
XArr[i]=XNew[line-1];
CHANGED = true;
}//End of SetMeterYT
//ResetMeter
//Clear Analog & Reset Index-1, YNew, YOld, XNew, XOld
public void ResetMeter()
{CHANGED = true;
ALLPOINTS = false;
YNew = new double [maxLines];
YOld = new double [maxLines];
XNew = new double [maxLines];
XOld = new double [maxLines];
Index = new int [maxLines];
IBegin = new int [maxLines];
IEnd = new int [maxLines];
YArr = new double [maxLines*maxPairs]; // the Y-Memory : Bildkoordinaten
XArr = new double [maxLines*maxPairs]; // the X-Memory : Bildkoordinaten
for (int i=0;i0) & (line<=maxLines))
{if (lincolor.length()!=0) LINColor[line-1] = WhichColor(LINColor[line-1],lincolor);
repaint();
}
}//End of SETLINECOLOR I
//SETLINECOLOR II
public void SetLineColor(int maxLin,
String lincols,
String seperator)
{ StringTokenizer st;
String st1;
maxLines = maxLin;
LINColor = new Color [maxLines];
st = new StringTokenizer(lincols,seperator);
for (int i=0; iymax) {Top0 = true;Outside=true;}
else {if (y < ymin) {Bottom0=true;Outside=true;}}
if (x>xmax) {Right0=true;Outside=true;}
else {if (xymax) {Top1 = true;Outside=true;}
else {if (y < ymin) {Bottom1=true;Outside=true;}}
if (x>xmax) {Right1=true;Outside=true;}
else {if (xHhe);
// print the header
x = (Mwi/2) - (fm.stringWidth(Header)/2);
y = (Hhe/2) + (fhe/2) - 2;
if (x>0) {og.setColor(HFGColor);
og.drawString(Header,x,y);
}
} // End of HEADER
/* ============================== ANALOG - Yt ================ */
// analog
og.setColor(AFGColor);
//Draw the x-axis
og.drawLine(xs0-2,ys0,xs1,ys1);
//Draw the marker sticks
dx = XMarkerSpace; // between 2 marker sticks
dy = XMarkerLength; // the length of a marker stick
//draw 10 markers
y = ys0+dy;
x = xs1;
for (i=1; i<=10;i++)
{x = xs0+i*dx;
og.drawLine(x,ys0,x,y);
}
xe = x;
ye = y;
//Draw the arrow
if (((xs1+6)8))
{ax[0] = xs1; ay[0]=ys1-3;
ax[1] = xs1+5; ay[1]=ys1;
ax[2] = xs1; ay[2]=ys1+3;
og.fillPolygon(ax,ay,3);
}
//print min/max-values onto the t-axis
dy = hborder - dy;
Fhe++; // Calculate the font
do
{ Fhe--;
f = new Font("TimesRoman",Font.PLAIN,Fhe);
og.setFont(f);
fm = getFontMetrics(f);
fhe= fm.getHeight();
} while (fhe>dy);
x = xs0;
y = yaroot-3;
s = String.valueOf(XMin);
og.drawString(s,x,y);
if (WXTitle==true)
{usedSpace = fm.stringWidth(s);}
x = xe;
y = yaroot-3;
s = String.valueOf(XMax);
og.drawString(s,x,y);
if (WXTitle==true)
{usedSpace=usedSpace+fm.stringWidth(s);}
//print the title of the x axis
if (WXTitle==true)
{freeSpace= borderX1 - borderX0 - usedSpace;
needSpace= fm.stringWidth(XTitle);
if (needSpace< freeSpace)
{y = yaroot-3;
x = borderX0 + ((borderX1-borderX0)/2) - (needSpace/2);
og.drawString(XTitle,x,y);
}
}
//Draw the y-axis
og.drawLine(xs0,ys0+3,xs2,ys2);
//Draw the marker sticks
dy = YMarkerSpace; //between 2 marker sticks
dx = YMarkerLength; //the length of a marker stick
//draw 10 markers
x = xs0-dx;
for (i=1;i<=10;i++)
{y = ys0-i*dy;
og.drawLine(x,y,xs0,y);
}
ye = y;
//Draw the arrow
if (((xs1+6)8))
{ax[0] = xs0-3; ay[0]=ys2;
ax[1] = xs0; ay[1]=ys2-6;
ax[2] = xs0+3; ay[2]=ys2;
og.fillPolygon(ax,ay,3);
}
//print min/max-values onto the y-axis
x = xaroot +3;
y = ys0;
s = String.valueOf(YMin);
if ((x+fm.stringWidth(s))= fhe ))
{og.drawString(YTitle,x,y);
}
}
//print the curves
int j=0;
for (int m=0;m0)
{ for (k=1;k<=Index[m];k++)
{ j = (m*maxPairs)+k;
yk = TransformY(YArr[j]);
yk1 = TransformY(YArr[j-1]);
xk = TransformX(XArr[j]);
xk1 = TransformX(XArr[j-1]);
if (LineClip(xk,yk,xk1,yk1,borderX0,borderX1,borderY1,borderY0)==true)
{og.drawLine(xc1,yc1,xc0,yc0);}
}//End of for
}//End of Index>1
}//End of ALLPOINTS=true
else
{if (Index[m]>0)
{ for (k=1;k<=Index[m];k++)
{ j = (m*maxPairs)+k;
yk = TransformY(YArr[j]);
yk1 = TransformY(YArr[j-1]);
xk = TransformX(XArr[j]);
xk1 = TransformX(XArr[j-1]);
if (LineClip(xk,yk,xk1,yk1,borderX0,borderX1,borderY1,borderY0)==true)
{og.drawLine(xc1,yc1,xc0,yc0);}
}//End of for
ALLPOINTS = true;
}
}//end of ALLPOINTS=false
}//End of for maxlines
//DOUBLE-BUFFERING
g.drawImage(oimg,0,0,this);
}// End of PAINT
}