|
Kaye and Geoff's web page documentation
IntroductionThis page is about the dynamic creation of graphics in web pages, in other words displaying a graphic not from a pre-existing image file but creating it in response to the user's actions or maybe the web page environment.Those who run their own web server can do this with graphics packages (for example GD or ImageMagick) or pre-processors (for example Cold Fusion) which run on the server. The graphics packages consist of a collection of routines which can be used stand-alone or called from Perl or PHP or C or some other programming language running as a CGI. Pre-processors interpret and then strip out special instructions included in web pages before they go to the server; these instructions can include commands to access a database and to plot the returned data. In either case, a file is ultimately created in a format (for example GIF) which a web page can reference. If you are running your own server then you can set it up as described above and you do not need the advice on this page. GD is free, includes a Perl interface, and runs on Unix servers. ImageMagick is available for Unix and Windows and has a Perl interface (PerlMagick). Cold Fusion is a commercial product. However, most web page developers do not have their own web server. While we use the Mac "personal web server" for development on our local network, we have no desire to expose it to the world. We have come across at least one hosting service which offers ImageMagick as one of the resources available to its clients, but most do not. So what possibilties are open to developers who want dynamic graphics but who do not have access to a server-based graphics system? We have tried several possibilities, many of which involve writing a CGI, so you could consider this page an extension of our CGI documentation. However we will also discuss some aspects of HTML, Javascript and SVG graphics, have a passing reference to AJAX and the DOM, and even touch on HTTP protocols and MIME types. Which explains why this is a separate page - it has a bit of everything. The information here is a summary of our current experience in dynamic plotting, so there are likely to be other techniques which we have yet to discover or explore. For example CSS may have something to offer, but our (only slightly jaundiced) view of style sheets leads us to put them at the bottom of our list at this stage. Using the img tag We can start by looking at what features of HTML can be used to create graphics. In fact, on its own HTML cannot offer much since it is "hard-coded" and only parsed once, a line at a time, strictly in sequence. However, it does have the ability to scale a picture before displaying it, using the width and height attributes of the image tag. Together with some setting-out using tables or CSS, if we could dynamically set the values of these attributes when the page is loaded or in response to user input, then we could create (admitedly limited) graphics "on-the-fly". As we have already seen, Javascript allows us to add dynamic behaviour to HTML, so we can use it to achieve simple plotting. The document.write() Javascript function is the basis of this technique, since it allows us the create the HTML code as the page is being parsed by the browser. For example: Using the canvas tag HTML5 (in 2009) introduced the <canvas> tag, specifically designed to allow drawing from within HTML. Between the opening and closing canvas tags you can place instructions which define a drawing to be placed within the web page. While this provides a simple and reasonably powerful method of creating graphics, it does have some drawbacks. It is not supported by older browsers, and is not supported directly by Internet Explorer at all. However a number of libraries are available which provide Internet Explorer support (via Flash or by some other method). We have not tried out this approach, since a significant proportion of our client audience is liable to still be using old browsers. If you want more information, these links might get you started:
So there are a few techniques to choose from for plotting, but where do we get the data from? In other words, in our example above, where does Javascript find the values for v1, v2 and v3? Data sources for plotting Javascript is not allowed, for security reasons, to access the host computer except in extremely limited ways via the browser. This is a major limitation on its effectiveness in creating dynamic plots, but depending on your application you might be able to use:
You can see a reasonably sophisticated example of plotting using internally generated values in our population genetics simulation. (If you are not trained in genetics then just push the "simulate" button to produce a plot. Convince yourself that it is generated dynamically by pushing the button as many times as you like). In fact this page illustrates a way of producing a plot using multiple picture substitution rather than the document.write() method described above. The complete picture is built by puting together a collection of pre-existing smaller pictures. It is not elegant but it works. A more elegant approach is to manipulate image objects in the document object model (DOM), inserting or removing them as required to build a more complex image. Because changes to the DOM are reflected immediately on the web page, this technique allows the graphics on the screen to be animated or to respond to input from the keyboard or mouse. This is how our Numero game expands or shrinks a spread of cards on the screen - by the addition or removal of pictures of complete or partial cards - simulating the cards being overlapped on a tabletop. The list of possible data sources above is obviously very limited; generally we have a large body of externally collected data stored on the server from which we want to select a subset to display in graphical form on a web page. Making an image file of every possible graph is too much work, and usually not practical. To solve this problem we need a CGI (Common Gateway Interface). This is a program which runs on the server and creates either the HTML for the page, or an image file (for example a GIF) which can be referenced by the HTML, or both. Writing a CGI requires programming skills - see the page referenced above for a more detailed discussion of the techniques involved - but it gives us almost unlimited freedom in accessing and manipulating the data. Plotting using a CGI A CGI may provide powerful ways to select and organise data, but so far we have only discussed very simple and inflexible ways to display data in a web page, based on manipulating HTML using Javascript. Despite this, in some cases acceptable graphics can be created, for example our weather plotting which uses a simple bar chart and a scatterplot on a fixed-interval X axis. Here the CGI writes an entire web page which is displayed in a pop-up window, but the plot could be included within the originating page by using AJAX and taking advantage of Javascript's ability to interact with the HTML DOM. SVG However to create arbitary graphics we need a generalised graphics package, and SVG (Scalable Vector Graphcs) fills the bill. To use it we are not dependent on our ISP or server administrator since it is text-based and interpreted by the browser (possibly with the help of a plug-in). SVG is an official W3C standard and is pure XML, so its structure is like HTML (well XHTML anyway). Because it is vector-based, it scales without loss of quality or appearance, but unlike most drawing formats it supports drop shadows and other features normally only available with raster image formats. It can even include animation capabilities. The only down-side is that browsers have been very slow to provide support for SVG, so older versions will not display it, or may need a plug-in, or may only implement a subset of the complete specification. This is changing and I believe that the latest versions of all popular browsers understand SVG natively. Traditionally Internet Explorer included SVG graphics in a web page using the non-standard embed tag, but the latest version allows the equivalent standard object tag. For these reasons you need to determine the nature of your audience before committing to relying on SVG graphics in your web pages. If you see a circle below then your browser can display SVG graphics. If it repeatedly (actually, just five times, starting from when the page completes loading/reloading, since it soon gets annoying) grows in size then your browser also supports SMIL (Synchronized Media Integration Language) which integrates with SVG to add the ability to animate the graphical elements. The SVG code to create this picture is as follows: You can see the svg tags which surround the whole picture description, and the circle tags which define the single graphical element - a purple circle centred on cx,cy with a radius of r. The animate tag changes the value of r through time to make the circle grow. Note that following XML rules all tags must be terminated, either using a "standalone" terminating tag (for example </svg>) or with a slash before the closing > (as in the animate tag used above). Because it is just text, creating such a file either with a text editor or from a program is conceptually straight-forward. Our experience with SVG is far too limited to attempt a detailed description of the language, but we do offer some comments below on its use in web pages. Try these links for more specific information on SVG: SVG in the WWW environment There are some practical considerations when using SVG graphics in a web environment. The first is the method used to link the SVG to the HTML. In the example above the SVG file is displayed in an inline frame with the following HTML: but there are other ways to display a SVG file. As already noted, you can use an object tag, or an embed tag, depending on which browsers you think your audience might have; or preferably both, in such a way that only one is actioned: The second consideration arises when you are using a CGI to dynamically create your SVG. Once you have the SVG code, you can either return it to the web server which will deliver it to the browser, or you can create an SVG file and return the HTML (or a reference to an HTML file in the HTTP) which can then include the SVG file using one of the methods discussed above. If you return SVG via the web server, the HTTP header must include the content (or MIME) type. For SVG this is image/svg+xml. So your CGI needs to return: Note that the blank line under the "Content-type" line is absolutely required - it separates the HTTP header (which here consists of just one line containing the content type) from the body (here the SVG code). The limitation of this approach is that the returned graphic will form the entire contents of a page (or possibly a frame or inline frame). Using AJAX might provide a way around this limitation, but we have not tried it. Otherwise, if you want your SVG picture to be displayed inline (for example with the use of an img tag) you need to create an SVG file from your CGI and then ensure that the web page which is displayed on return from the CGI includes the appropriate HTML to reference it. To do this, the CGI can create the HTML, or alternatively can use the "location" HTTP directive to specify the HTML file to be displayed (in this latter case the name of the SVG file would have to be fixed). As you can see from the examples in the CGI page, a web page returned from a CGI (in the example below including an object tag to load the SVG) has the following format: To get the browser to load an HTML file called svgexample.html, the CGI needs to return: In the last case there is no HTTP body, but a blank line below "Location" is still required (failing to do this is a very common source of error when creating HTTP from within a program). After creating your SVG file, you will normally have to undertake a bit of "housekeeping". Most web servers are set up with restrictions on which directories they access. Normally there is a directory for CGIs (on Unix machines typically called cgi-bin) and another for web pages and their associated image, CSS, Javascript and similar files (sometimes called www). For security reasons the web server is usually only allowed to execute CGIs if they are in their correct directory (or one of its sub-directories), and can only serve files from the web directory (or one of its sub-directories). In particular it cannot serve files from the CGI directory. So we normally have to arrange for the SVG file that we create to end up in the web directory, not the CGI directory. How you do this depends on what language you choose to write your CGIs, but if you are using someone else's server then you need to make sure that you can write to the web directory, and possibly also that you can control the ownership and/or permissions of the file you are writing. |
||
|
Top Previous Index Home |