Adds Caching, Variable Sized Graphs and some minor tweaks
| Project: | Mathematics Filter |
| Version: | 5.x-1.0.x-dev |
| Component: | Code |
| Category: | task |
| Priority: | normal |
| Assigned: | dwees |
| Status: | closed |
Please find attached a patch that:
1) implements variable sized graphs
2) caching of images of equations
3) added default of cgi-bin/mimetex.cgi since that is the standard place and extension
4) added default for height/width
5) fixed errors from graphframe.php when max/min wasn't specified, and added some sanity checking
6)a removed "case 'prepare':" from _filter
6)b changed "case 'list':" to return "Mathfilter instead of "Mathematics" for consistency
7) one or two other slight changes in language
Short comment:
2) In a high(er) load environment (including shared hosting) lowering the load on the server is more than just desirable. Since running a cgi program causes *much* higher load than just getting a simple gif, saving the gif would provide this performance benefit.
I'd also recommend, since the graph is hardcoded as a square in the js, that the user defined height/width for the graph be changed to one field. This is _not_ included in this patch and would require a few simple changes to the things I've done here if this recommendation is accepted.
I've fairly liberally documented the code I've written. So, it shouldn't be entirely Greek ;)
Please review and comment.
| Attachment | Size |
|---|---|
| mathfilter.patch | 9.51 KB |

#1
I'll add this code, looks like serious improvements. Caching is a huge improvement.
I made attempt to use the PEAR Php library to create the graphs, but I ran into some bugs and gave up. I'll post my attempt up here, it's basically a PHP port of the wz_grapher.js and creates a solid image. This has the advantage of allowing for caching, and avoids problems with pesky users not enabling JavaScript or using some horrible weird browser.
We have a slight difficulty with the chdir at the beginning, since we can guarantee the location of the module (we'd need to find out what it was first, then do the chdir because the module could be sites/all/modules sites/default/modules or modules).
Dave
#2
Here is the Php version of the grapher I was talking about.
Dave
#3
Thanks :)
Oops. I thought that directory structure was guaranteed.
I'm not sure how to get the web root in a nice way from PHP. But, changing the chdir to the below works and should account for the situations that you listed.
foreach (array("../../..", "../..", "..") as $value) {if (file_exists($value . "/index.php")) {
chdir($value);
break;
}
}
I don't think that I've ever used PEAR before. But, I'll give it a look within the next couple days.
Are you thinking of having caching for graphs like what I've implemented for equations i.e. optional? Because, I was going to suggest, if possible, taking the graph out of iframe's and into there own div's. I have something in mind, but I haven't done any js scripting for some time. So, it may or may not work. But, I won't try it if you're planing structural changes that'll make it moot.
Let me know :)
#4
Yeah, it would certainly help site performance some if we could move the graphs into divs instead of iframes. The only issue I had with that was that I was hacking Walter Zorn's JavaScript grapher, and I wasn't sure how to account for the different ids of the graphs (somehow the graph would have to auto-generate its own id, and not involve the user in the process).
I think a better plan is to have PHP create the graphs as images, and then we can implement caching solutions, etc... AND have the graphs be cross-browser. I had the code working to create the graphs 95% completed, but then I couldn't work out some minor bugs, and couldn't get the support I needed.
The code I'm using requires the PEAR php package (which you should have in your 'include' path) and Image_Graph and its dependents. It was reasonably straight forward to set it up, and I don't think Image_graph has changed much since I did it (I wrote this code almost a year ago).
I wasn't intending to work on it any further because of a lack of time, but see if you can figure out the bug. Basically, when your function you draw exceeds your maximum y value, it draws a nasty straight line at the top of the graph. Yech.
Dave
#5
I have some ideas. I'll try them out and let you know how it goes.
In principle I agree. It would definitely be nice to have PHP generate an image instead of js. But, at the same time, "better" is a very subject thing.
For instance, increasing dependancies isn't necessarily the best way to go. Especially when they are compile time options that can be disabled (e.g. pear) and /especially/ if they are add-ons that might not be installed (e.g. Image_graph). Add on top of all that someone not having the ability to install missing packages, and you have someone locked out of using Mathfilter (or a portion thereof depending on how it's structured). Quite frankly, I'd expect this situation to be far more common (i.e. difficult hosters) than people not having js enabled and/or running some archaic/exotic browser.
This is pretty much the reason why I used sha1() for generating the filename for the equation's image; sha1() is a built-in function. Though the ideal would have been using SHA256, that is only available through mhash which can be disabled and as such unavailable.
My suggestion would be to have both and provide the option like the way mimetex is done through this patch. That way, there'll be something to fallback on.
#6
I just took a quick look through your graph producing code. I gotta say that because of the lack of documentation, and how cryptic the code itself is, I can't really tell what's going on.
But, based on the symptom you described, I think that there is a good chance that the bug isn't in your code, but image_graph itself. It almost seems as though that image_graph doesn't know where to place the "out of range" data points and just puts it at the max value. If this is the case, then the below untested code/pseudo code would be /a/ solution. Though how effective/good (or even viable) is up to you. But, it should get the point across. Of course this is all moot if the bug has already been fixed or it really is in your code.
//assumption
//each data point is an array(x, y) and has been pre-calculated
// and is held here
$datapoints;
//this the cleansed array of arrays of data points
$curve_array = array();
// here is our temporary holding array
$temp_datapoints = array();
//go through each data point and toss out what is not
// within our y min/max
// i.e. we do clipping on the data set
foreach($datapoints as $datapoint) {
//is it a valid point?
if (!($datapoint[1] > $ymax || $datapoint[1] < $ymin)) {
$temp_datapoints append $datapoint
} else {
// it exceeds, we toss it
if ($temp_datapoints is NOT empty) {
//if something has come before, we need to
// truncate that part of the data-set
make $temp_datapoints an element of $curve_array
clear $temp_datapoints
}
//if our $temp_datapoints IS empty we do nothing as
// we are just continuing on the part of the data-set
// that we aren't going to display
}
}
//tidy up the remaining peices should they exist
if ($temp_datapoints is NOT empty) {
make $temp_datapoints an element of $curve_array
}
//at this point we have $curve_array which each element of it,
// a part of the curve that we will display i.e. it has been
// clipped
//Now we may display the curve in its individual part(s)
foreach($curve_array as $curve) {
draw the curve
}
Hope that helps.
#7
This code has made it into the newest version of Mathfilter and seems to be working fine, so I'm marking this issue as closed. A future of release may see graph caching of some sort.