Last updated June 28, 2004
You'll need to download
This parcel provides the ability to run GNUPlot from inside smalltalk, and most importantly, capture the output into aByteArray (or aByteString--I can't always remember which).
I needed (OK, wanted) the ability to create graphs for web pages from inside .SSP files, but I didn't have UI loaded and never used it. In fact, from what I've read you can't use it without having a bunch of stuff loaded.
Anyway, one of my first tries has been saved as #test1 under the class-side methods of GNUPlot. Try evaluating, or debugging, the following:
GNUPlot test1.
A more complicated example from one of my SSPs looks like:
aGNUPlot := GNUPlot new title: 'paidDate-endDate accuracey'; xLabel: 'startDate'; yLabel: 'effectiveDate - endDate'; terminalType: #png; defaultXDateFormat; dataSeries: (Array with: aCollectionOf2ElementArrays); yourself.
To see what the commands to gnuplot will be, send the aGNUPlot #plotCommand. It returns the string.
aGNUPlot plotCommand printOnFileNamed: '/tmp/test.plot'. "this is what I do to test it"
To run gnuplot and create your output send aGNUPlot #plot.
plotData := aGNUPlot plot.
Rather than displaying it immediately inside the HTML that created it, I save the data in the session and provide a link so that both Netscape and IE browsers can see it. Netscape was really good about handling inline images but IE didn't seem to like them. For that matter, neither did Opera. The link I created simply looks like:
<img src="showPlot.ssp?data=plotData" alt="aPlot"/>
Inside the file showPlot.ssp, is simply:
<% response expires: 0. response contentType: 'image/png'. response write: (session at: (request anyParameterValueAt: 'data') asSymbol). %>
That's basically it.
As expected, I've modified things slightly--enough to probably perturb anyone using what they downloaded yesterday.
#smooth: and #dataSeries: have been changed to expect arrays of smooth options and data series. This was done to allow the plotting of multiple data series. For instance, I want to plot the same dataseries twice but with different smoothing. Inside my .ssp I might have:
plotter := GNUPlot new title: 'receipt discount curve'; xLabel: 'days to go'; yLabel: 'discount percentage (%)'; xRangeReverse: true; terminalType: #png; terminalOptions: 'color'; plotTitle: (Array with: 'Bezier' with: 'Unique'); dataSeries: (Array with: dataSeries with: dataSeries); smooth: (Array with: #bezier with: #unique); yourself.which will plot the first series with a bezier curve, and the second with straight lines. An example of the output is below.
![]()
Some other things you may have noticed:
- #terminalOptions: accepts a string which will be added to the "set terminal" command. In this case I know "color" is a valid option for the #png terminal type.
- #plotTitle: accepts arguments similar to #smooth:. In the example above I titled the two plots "Bezier" and "Unique" respectively.
As I've started experimenting with more complex plots I decided the code above was simply too much code. Keeping the collection arguments synchronized was difficult, and cutting/pasting was as well. I was experimenting with a five-plot graph and it just looked nasty.
To simplify things I added two new methods, #initialize and #addPlotTitle:dataSeries:smooth:. Example code is listed below with the resulting graph immediately following.
plotter := GNUPlot new initialize; grid: true; title: 'Median Payment Term v PO Terms'; xLabel: 'effective date'; yLabel: 'median(paymentTerm)'; defaultXDateFormat; terminalType: #png; terminalOptions: 'color'; addPlotTitle: 'start date' dataSeries: series1Data smooth: #sbezier; addPlotTitle: 'end date' dataSeries: series2Data smooth: #sbezier; addPlotTitle: 'payment date' dataSeries: series3Data smooth: #sbezier; addPlotTitle: 'accuracy' dataSeries: series4Data smooth: #unique; addPlotTitle: 'eFinNet contracts' dataSeries: series5Data smooth: #unique; yourself![]()
Nothing much happened today. Just a bug fix in #xzeroaxis which caused error text to appear in the output stream--screwing-up the plot data.
Instead of using showPlot.ssp, I recommend using the GNUShowPlot servelet. There's basically a bug in VWave that adds some text at the end of anything returning from an .SSP saying it was "Created by Cincom Smalltalk", which isn't appropriate for binary output. Luckily, such silliness isn't added to the output of servelets.
Additionally, GNUPlot's #plot command now uses EfiSubProcess methods to spawn gnuplot and pipe commands into and output from it. The handling of the streams, the closing and flushing of their contents is handled much better in the new method and doesn't risk losing output.