diff -r 75e825820538 -r 5a4a11ee0b1f GnuplotGraphView.st --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GnuplotGraphView.st Mon Apr 30 22:10:59 2018 +0200 @@ -0,0 +1,251 @@ +"{ Package: 'stx:libwidg2' }" + +"{ NameSpace: Smalltalk }" + +ImageView subclass:#GnuplotGraphView + instanceVariableNames:'script data title' + classVariableNames:'' + poolDictionaries:'' + category:'Views-Misc' +! + +!GnuplotGraphView class methodsFor:'documentation'! + +documentation +" + displays the graph of the data (in model) using a gnuplot script + + [author:] + cg + + [instance variables:] + + [class variables:] + + [see also:] + +" +! + +examples +" + Notice that everything between [exBegin] and [exEnd] is extracted by the html-doc generator + to create nicely formatted and clickable executable examples in the generated html-doc. + (see the browsers class-documentation menu items for more) + + trying the widget as standAlone view: + [exBegin] + GnuplotGraphView new + script:(GnuplotGraphView defaultScript); + model:(ValueHolder with:(Random new next:100)); + open + [exEnd] + + embedded in another view: + [exBegin] + |top v| + + top := StandardSystemView new. + top extent:300@300. + v := GnuplotGraphView new. + v origin:10@10 corner:150@150. + top add:v. + top open + [exEnd] +" +! ! + +!GnuplotGraphView class methodsFor:'defaults'! + +defaultScript + "return a default initial gnuplot script" + + ^ self defaultScriptForHistogram +! + +defaultScriptForHistogram + "a default initial gnuplot script to show a histogram" + + ^ ' +set term %(outputFormat) +set output "%(outputFile)" +set title "%(title)" +plot [-10:110] ''%(data)'' with histogram +' +! ! + +!GnuplotGraphView methodsFor:'accessing'! + +data + ^ data +! + +data:something + data := something. +! + +script + ^ script +! + +script:something + script := something. +! + +title + ^ title +! + +title:something + title := something. +! ! + +!GnuplotGraphView methodsFor:'drawing'! + +generateDataFileIn:aDirectory + "the format of data expected by gnuplot depends on the type of plot: + regular plot: a number of values (each in a separate line) + multiCol plots: a number of lines, each containing a row + here, handle common situations; + however, if the data does not match, the program should have prepared the + data into a string and present it as such. + Strings will be sent as-is to the file" + + |dataFilename printRow| + + dataFilename := (Filename newTemporaryIn:aDirectory) pathName. + dataFilename := dataFilename asFilename withSuffix:'dat'. + + (data isString or:[data isByteArray]) ifTrue:[ + dataFilename contents:data. + ^ dataFilename. + ]. + + data isCollection ifFalse:[ + dataFilename contents:data printString. + ^ dataFilename. + ]. + + printRow := + [:s :eachValueOrRow | + eachValueOrRow isString ifTrue:[ + s nextPutAll:eachValueOrRow + ] ifFalse:[ + eachValueOrRow isAssociation ifTrue:[ + eachValueOrRow key printOn:s. + s space. + eachValueOrRow value printOn:s. + ] ifFalse:[ + eachValueOrRow isCollection ifTrue:[ + eachValueOrRow + do:[:element | element printOn:s] + separatedBy:[ s space] + ] ifFalse:[ + eachValueOrRow printOn:s + ]. + ]. + ]. + s cr. + ]. + + dataFilename writingFileDo:[:s | + data isSequenceable ifTrue:[ + data do:[:eachValueOrRow | + printRow value:s value:eachValueOrRow. + ]. + ] ifFalse:[ + data keysAndValuesDo:[:eachKey :eachValueOrRow | + eachKey printOn:s. + s space. + printRow value:s value:eachValueOrRow. + ]. + ]. + ]. + ^ dataFilename +! + +generateImage + " + self new + script:(GnuplotGraphView defaultScript); + data:(RandomGenerator new next:50); + open + " + |command tmpDir outStream errorStream statusCode ok + dataFilename scriptFilename outFilename argsDict expandedScript + stdout stderr| + + script isNil ifTrue:[^ self]. + + command := 'gnuplot "%1"'. + argsDict := Dictionary new. + + tmpDir := Filename tempDirectory. + + data notEmptyOrNil ifTrue:[ + dataFilename := self generateDataFileIn:tmpDir. + ] ifFalse:[ + dataFilename := ''. + ]. + + outFilename := (Filename newTemporaryIn:tmpDir) withSuffix:'png'. + + argsDict at:'data' put:dataFilename. + argsDict at:'dataSize' put:(data size). + argsDict at:'outputFile' put:(outFilename pathName). + argsDict at:'outputFormat' put:'png'. + argsDict at:'title' put:(title ? ''). + + expandedScript := script bindWithArguments:argsDict. + scriptFilename := (Filename newTemporaryIn:tmpDir). + scriptFilename := scriptFilename asFilename withSuffix:'gnuplot'. + scriptFilename contents:expandedScript. + + command := command bindWith:(scriptFilename pathName). + + outStream := '' writeStream. + errorStream := '' writeStream. + + ok := OperatingSystem + executeCommand:command + inputFrom:Stdin + outputTo:outStream + errorTo:errorStream + environment:nil + inDirectory:tmpDir + lineWise:true + showWindow:false + onError:[:status | + statusCode := status code. + ok := false. + ]. + + ok ifFalse:[ + (stderr := errorStream contents) notEmptyOrNil ifTrue:[ + Transcript showCR:(stderr withColor:Color red). + ]. + ]. + (stdout := outStream contents) notEmpty ifTrue:[ + Transcript showCR:stdout. + ]. + + image := Image fromFile:outFilename. +! + +generateMagnifiedImage + image isNil ifTrue:[ + self generateImage + ]. + super generateMagnifiedImage. +! ! + +!GnuplotGraphView class methodsFor:'documentation'! + +version + ^ '$Header$' +! + +version_CVS + ^ '$Header$' +! ! +