advertisement
javaboutique
Search Tips
Articles  |   Tutorials  |   Reviews  |   Tools  |   by Category  |   by Date  |   by Name  |   Submit  |   Source  |   Forums  |  
javaboutique
Browse DevX


Partners & Affiliates











advertisement

GraphReader


Purpose:

Simple and effective data reader of digitized graphs in formats like .xbm, .gif, .jpg, assuming linear coordination (essentially all graphs are linear for your eyes - the only difference is in later interpretation). For anyone who can use a scanner, say good-bye to the terrible work of taking down data from journals using a pencil and a ruler!

Instructions:

Notes:

  • V1.0 (JDK 1.0.2) coded in 1997 for my fiancee. Only Netscape on Sun workstations. Unstable on other platforms. The current version is in JDK 1.1.3, tested on i386 RedHat Linux Netscape 4.61, SGI IRIX Netscape 4.07, Microsoft Internet Explorer 4.x.

  • The pathological interaction between keyboard events intercepted by handleEvent(), and applet top management and input TextField in V1.0, is now resolved by adding a KeyEvent receptor (pseudo-TextField or applet this) that gets all command keys, a bit like two modes of vi. The switch is the return key.

  • It suffices to define just two anchors if the graph is orthogonal and "sitting up." But the scanned image is often slightly rotated, and I don't want this error to exist in the program. To benchmark V2.0's precision, try test.gif generated by test.m. A conservative estimate is 1% relative error for reasonable images. And the larger the image is, the higher the precision.

  • To pick your color for the pointer, refer to rgb.html. My favorite is SteelBlue4. The original width and height of an image can be determined by loading the raw image into the browser, right click on it, and look for Properties or View Page Info. Use magn factor (default=1.0) to enlarge or shrink your graph. If the image is larger than the browser, pressing Up,Down,Left,Right arrow keys when the mouse cursor is outside the applet will force the browser to show scrollbars. You can always regain the focus for KeyEvents by clicking in the graph.

    Background color of the graph is taken to be white but that can be changed. To make sure that the pointer works for transparent gifs like trans.gif, I cover the floor with this color before drawing the real image on it, and the pointer color is what one gets when drawing on that color. In case your image is not transparent and the majority of its dots are red instead of white, then the program should be informed that the background is FF 00 00, in order to gain your desired pointer color when drawing on red.

  • It is against security restrictions to let a Java applet sent by an "untrusted" server - running now on the client browser, to read or write the local file system. It is also against security restrictions to have third-party communication other than between the browser and the server. Thus, embedable Java applets are mostly "blind performers" who need little viewer information. The only viable method is to let reader.htm, reader.class be on the same computer as the digitized graphs. There are, of course, two ways to do this.

  • The programmer writes paint(g), but the applet may pass graphics contexts other than getGraphics() - the whole context you see on the screen - to paint. When an overlapping window is pushed down, the applet may ask paint to draw on a "different" and smaller g, then transfer (copy or simply "on"?) to getGraphics(). Watch the action of a slow IE after we insert a line g=getGraphics(); at the beginning of paint(g) - in this case the entire graph is redrawn every time, whereas previously it only draws in the overlap region, which is more efficient.

    The priority of applet is speed and memory. It does not care about your discomfort with screen flickering. In first download and repaint() - g  is  getGraphics() - and the applet will directly draw on getGraphics() through update(g) to paint(g), unless you override update(g). Double-buffering decreases frame rate but is visually more appealing. One draws on bak_g, then copies to (instead of draws on) g. Management would never do that voluntarily.

    Once we see that g may not be getGraphics(), confusions about setXORMode are cleared. Basically, if the current context color a=g.getColor() [which can be set by g.setColor(a), or to be the initialized black], after which g.setXORMode(b), then if we draw thereafter on g's dot of color c: c -> a (+) b (+) c. Thus, if a is picked or made to be the "background color" of g, where the majority of g's dots have c=a, then it would turn b after we draw on the background once. On other dots (like a yellow circle in mostly white background), the result is unpredictable, but always reversible before setXORMode is changed. The point is, it is important to be sure that a=g.getColor() is what you think it is before running g.setXORMode(b), otherwise you won't get the planned effects - like getting b when drawing on the background of g.


http://mmm.mit.edu/~liju99/Archive/NetApp/JavaScript/Reader/reader.htm stores the newest version of Graph Reader. Java source reader.java is freely available on condition that I am notified of its hacks and upgrades. The author is a follower of the Open Source movement.


Use this JavaScript:


<SCRIPT>

function init()

{

 // Default applet geometries

 var graph_width_pad=10, graph_height_pad=10, panel_height=40;

 // Graph's pathname to be passed to the applet: if it is local,

 // there must not be "file://" tag - just "c:\A\b.gif". If it

 // is remote, it should be like "http://a.b.com/b.gif".

 var graph_file = "";

 // The graph's pathname could be browsed in (local), in which

 // case it already satisfies the required format "c:\A\b.gif".

 graph_file = document.myform.graph_file.value;

 // Or could be typed in, interpreted as relative to this HTML

 // base, and we need to add it back in. However if the document

 // base contains "file://", we need to throw that part out.

 if (graph_file.length == 0) // no input from Browse

  graph_file = document.URL.substring(0,

   document.URL.indexOf("reader.htm")).replace("/\./", "/").

   replace("file://", "").replace("file:", "")

   + document.myform.graph_filename.value;

 // Intended display geometry (width height magnification):

 var graph_geom_splitted = document.myform.graph_geom.value.split(" ");

 var graph_width  = graph_geom_splitted[0];

 var graph_height = graph_geom_splitted[1];

 var graph_mag    = 1.0;

 if (graph_geom_splitted.length >= 3)

  graph_mag = parseFloat (graph_geom_splitted[2]);

 // convert string to integer by multiplication

 graph_width  = Math.round(graph_mag * graph_width);

 graph_height = Math.round(graph_mag * graph_height);

 var applet_width  = 2 * graph_width_pad + graph_width;

 var applet_height = 2 * graph_height_pad + panel_height + graph_height;

 // The pointer is a square rotated by 90 degrees

 var pointer_splitted = document.myform.pointer.value.split(" ");

 var pointer_size = pointer_splitted[0];

 var pointer_R = parseInt(pointer_splitted[1],16)/255.;

 var pointer_G = parseInt(pointer_splitted[2],16)/255.;

 var pointer_B = parseInt(pointer_splitted[3],16)/255.;

 // Font properties

 var graph_fontsize = document.myform.graph_fontsize.value;

 var graph_fontname = document.myform.graph_fontname.

   options[document.myform.graph_fontname.selectedIndex].text;

 // Background color, using which we fill a rectangle before drawing

 // the real image on it

 var graph_background_splitted =

  document.myform.graph_background.value.split(" ");

 var graph_background_R = parseInt(graph_background_splitted[0],16)/255.;

 var graph_background_G = parseInt(graph_background_splitted[1],16)/255.;

 var graph_background_B = parseInt(graph_background_splitted[2],16)/255.;

 // From here on document.myform is invalid ->

 // weblink the graph (simple check of its existence):

 document.write ("<HTML><body bgcolor=#ffffff><center><I><P>" +

                  graph_file.link(graph_file) + "</P>");

 // then invoke the applet with parameters submitted by myform:

 document.write ("<P><applet code=reader.class width=" + applet_width +

       		 " height=" +  applet_height + ">" +

	"<param name=basex value=" + graph_width_pad + ">" +

	"<param name=basey value=" + graph_height_pad + ">" +

	"<param name=graph_file value=" + graph_file + ">" +

	"<param name=graph_width value=" + graph_width + ">" +

	"<param name=graph_height value=" + graph_height + ">" +

	"<param name=pointer_size value=" + pointer_size + ">" +

	"<param name=pointer_R value=" + pointer_R + ">" +

	"<param name=pointer_G value=" + pointer_G + ">" +

	"<param name=pointer_B value=" + pointer_B + ">" +

	"<param name=graph_fontsize  value=" + graph_fontsize + ">" +

	"<param name=graph_fontname  value=" + graph_fontname + ">" +

	"<param name=graph_background_R value=" + graph_background_R + ">" +

	"<param name=graph_background_G value=" + graph_background_G + ">" +

	"<param name=graph_background_B value=" + graph_background_B + ">" +

        "</applet></P>");

 document.write ("<P><a href=reader.htm#open_Java_console>Open "+

    "Java console</a> to view the saved data.</P></center></HTML>");

} // end init()

</SCRIPT>

And use this HTML:

<FORM name=myform>
<TABLE>
<TBODY>
<TR>
<TD>Graph filename</TD><!-- VALUE is ignored in IE4 and N4, and there is no way to -->
<TD><INPUT name=graph_file size=40 type=file></TD>
<!-- suggest file type. N4 inexplicably assumes HTML upload -->
<!-- GRAPH_FILE always local, and full pathname --></TR>
<TR>
<TD align=middle>or</TD><!-- GRAPH_FILENAME may be local, may be remote (through HTTP) -->
<TD><INPUT name=graph_filename size=40 value=example.gif> (type it in)</TD>
<!-- always interpreted as relative to this HTML document -->
<!-- GRAPH_FILE has higher priority than GRAPH_FILENAME field --></TR>
<P>
<TR>
<TD>Width height magn</TD>
<TD><INPUT name=graph_geom value="510 440 1.0"></TD></TR>
<P>
<TR>
<TD>Pointer size R G B</TD>
<TD><INPUT name=pointer value="2 36 64 8B"></TD></TR>
<P>
<TR>
<TD>Font size name</TD>
<TD><INPUT name=graph_fontsize size=3 value=12> <SELECT
name=graph_fontname> <OPTION>Default<OPTION
selected>TimesRoman<OPTION>Dialog<OPTION>SansSerif
<OPTION>Serif<OPTION>Monospaced
<OPTION>Helvetica<OPTION>Courier<OPTION>DialogInput
<OPTION>ZapfDingbats</OPTION></SELECT></TD></TR>
<P>
<TR>
<TD>Background R G B</TD>
<TD><INPUT name=graph_background value="FF FF FF"></TD></TR>
<P>
<TR>
<TD><INPUT onclick=init() type=submit value=Submit></TD>
<TD><INPUT type=reset value=Reset></TD></TR></P></TBODY></TABLE></FORM>


Back to the GraphReader applet page

How to Add Java Applets to Your Site

New on the Java Boutique:

New Review:

Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling API boasts simplicity, ease-of-integration, a well-rounded feature set, and it's free!

New Applet:

Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA sequences into three useful formats.

Elsewhere on internet.com:

WebDeveloper Java
Lots of Java information on webdeveloper.com

WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.

ScriptSearch Java
Hundreds of free Java code files to download.

jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.

 Microsoft RIA Development Center
 IBM Rational Resource Center
 Destination .NET
XML error: not well-formed (invalid token) at line 33
advertisement
Receive Articles via our XML/RSS feed
Receive Articles via our XML/RSS feed

JavaBytes
Internet Cyclone
This powerful, easy-to-use, internet optimizer is for Windows 95, 98, ME, NT, 2000 and XP. It's designed to automatically optimize your Windows settings, boosting your Internet connection up to 200%.

Free VMware Server 2.0 Now Release Candidate
Linux Player Xandros Grabs Storied Rival Linspire
Hey Enterprise: Here Comes the 3G iPhone
MySpace Opens Profile Portability API
Microsoft Jumps Into Virtualization Fray
Eclipse Ganymede Makes It Easier for Devs
Open Source Nokia a Threat to Microsoft, Google?
Salesforce, Google Head for 2nd on Apps
HP Open Sources Unix File System for Linux
Red Hat Opens Its Network to Space

Build a Generic Histogram Generator for SQL Server
Beyond XML and JSON: YAML for Java Developers
Mastering the Windows Mobile Emulators
Avaya AE Services Provide Rapid Telephony Integration with Facebook
Featured Algorithm: Intel Threading Building Blocks: parallel_reduce
Getting Started with Windows Live Admin Center
Eight Key Practices for ASP.NET Deployment
Java ME User Interfaces: Do It with LWUIT!
Talking VPro: Transcript
Bringing Semantic Technology to the Enterprise

Advertising Info  |   Member Services  |   Contact Us  |   Help  |   Feedback  |   Site Map  |   Network Map  |   About



JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Solutions
Whitepapers and eBooks
IBM eBook: Planning a Service Oriented Architecture
IBM eBook: Choosing the Right Architecture--What It Means for You and Your Business
Microsoft Article: Will Hyper-V Make VMware This Decade's Netscape?
Avaya Article: Using Intelligent Presence to Create Smarter Business Applications
Intel Go Parallel Article: Getting Started with TBB on Windows
Microsoft Article: 7.0, Microsoft's Lucky Version?
Avaya Article: How to Feed Data into the Avaya Event Processor
IBM Article: Developing a Software Policy for Your Organization
Microsoft Article: Managing Virtual Machines with Microsoft System Center
Intel Go Parallel Article: Intel Threading Tools and OpenMP
HP eBook: Storage Networking , Part 1
Microsoft Article: Solving Data Center Complexity with Microsoft System Center Configuration Manager 2007
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
Webcasts
HP Video: StorageWorks EVA4400 and Oracle
HP Webcast: Storage Is Changing Fast - Be Ready or Be Left Behind
Microsoft Silverlight Video: Creating Fading Controls with Expression Design and Expression Blend 2
MORE WEBCASTS, PODCASTS, AND VIDEOS
Downloads and eKits
Red Gate Download: SQL Toolbelt and free High-Performance SQL Code eBook
Iron Speed Designer Application Generator
MORE DOWNLOADS, EKITS, AND FREE TRIALS
Tutorials and Demos
Silverlight 2 App and Walkthrough: Leverage Silverlight 2 with SQL Server and XML
IBM Article: Enterprise Search--Do You Know What's Out There?
HP Demo: StorageWorks EVA4400
Microsoft Article: The Progress and Promise of Deep Zoom
Microsoft How-to Article: Get Going with Silverlight and Windows Live
MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES