001    package org.jgnuplot;
002    
003    import java.io.BufferedWriter;
004    import java.io.File;
005    import java.io.FileWriter;
006    import java.io.IOException;
007    import java.util.Enumeration;
008    import java.util.List;
009    import java.util.Stack;
010    import java.util.StringTokenizer;
011    import java.util.Vector;
012    
013    /**
014     * This class models the plot command.
015     * 
016     * @author Pander
017     */
018    public class Plot {
019       private boolean itsPlotable;
020    
021       private String itsTerminal;
022    
023       private String itsOutputFileName;
024    
025       private String itsTitle;
026    
027       private String itsGrid;
028    
029       private String itsDataFileSeparator;
030    
031       private String itsKey;
032    
033       private int itsParametric;
034    
035       private int itsPolar;
036    
037       private String itsSamples;
038    
039       private String itsDummy;
040    
041       private String itsClip;
042    
043       private String itsAutoscale;
044    
045       private String itsXLabel;
046    
047       private String itsX2Label;
048    
049       private String itsYLabel;
050    
051       private String itsY2Label;
052    
053       private String itsXTics;
054    
055       private String itsX2Tics;
056    
057       private String itsYTics;
058    
059       private String itsY2Tics;
060    
061       private String itsRanges;
062    
063       private String itsXRange;
064    
065       private String itsX2Range;
066    
067       private String itsYRange;
068    
069       private String itsY2Range;
070    
071       private String itsTRange;
072    
073       private String itsMXTics;
074    
075       private String itsMYTics;
076    
077       private String itsXData;
078    
079       private String itsYData;
080    
081       private String itsTimeFormat;
082    
083       private String itsDataFileName;
084    
085       private String itsSize;
086    
087       private Stack<Graph> itsGraphs;
088    
089       private List<String> itsExtra;
090    
091       private String itsData;
092    
093       private String itsLogscale;
094    
095       private boolean itsCommandsOnOneLine;
096    
097       private BufferedWriter itsOutputPlotFile;
098    
099       private static String itsGnuplotExecutable;
100    
101       private static String itsPlotDirectory;
102    
103       private boolean itsAutoscaleAfterRanges;
104    
105       /*
106        * private static int getInt(Vector theVector, int theElement) { return
107        * ((Integer)theVector.elementAt(theElement)).intValue(); }
108        */
109    
110       public final void setAutoscaleAfterRanges() {
111          itsAutoscaleAfterRanges = true;
112       }
113    
114       public final void setTitle(String theTitle) {
115          itsTitle = theTitle;
116       }
117    
118       public final void setDataFileSeparator(String theDataFileSeparator) {
119          itsDataFileSeparator = theDataFileSeparator;
120       }
121    
122       public final void setGrid(String theGrid) {
123          itsGrid = theGrid;
124       }
125    
126       public final void setGrid() {
127          itsGrid = "";
128       }
129    
130       public final void unsetGrid() {
131          itsGrid = null;
132       }
133    
134       public final void setLogscale(String theLogscale) {
135          itsLogscale = theLogscale;
136       }
137    
138       public final void setLogscale() {
139          itsLogscale = "";
140       }
141    
142       public final void unsetLogscale() {
143          itsLogscale = null;
144       }
145    
146       public final void setKey(String theKey) {
147          itsKey = theKey;
148       }
149    
150       public final void unsetKey() {
151          itsKey = null;
152       }
153    
154       public final void setParametric() {
155          itsParametric = State.ON;
156       }
157    
158       public final void unsetParametric() {
159          itsParametric = State.OFF;
160       }
161    
162       public final void setPolar() {
163          itsPolar = State.ON;
164       }
165    
166       public final void unsetPolar() {
167          itsPolar = State.OFF;
168       }
169    
170       public final void setSamples(String theSamples) {
171          itsSamples = theSamples;
172       }
173    
174       public final void setDummy(String theDummy) {
175          itsDummy = theDummy;
176       }
177    
178       public final void setClip(String theClip) {
179          itsClip = theClip;
180       }
181    
182       public final void setClip() {
183          itsClip = "";
184       }
185    
186       // comma separated
187       public final void setAutoscale(String theAutoscale) {
188          itsAutoscale = theAutoscale;
189       }
190    
191       public final void setAutoscale() {
192          itsAutoscale = "";
193       }
194    
195       public final void setOutput(String theTerminal, String theOutputFileName) {
196          itsTerminal = theTerminal;
197          // make path absolute for .plt file which is in temp directory
198          if (!theOutputFileName.startsWith(File.separator)
199                && theOutputFileName.charAt(1) != ':') {
200             itsOutputFileName = (new File("")).getAbsolutePath() + File.separator
201                   + theOutputFileName;
202          }
203          itsOutputFileName = duplicateDoubleBackSlashes(theOutputFileName);
204       }
205    
206       public final void setOutput(String theTerminal, String theOutputFileName,
207             String theSize) {
208          setOutput(theTerminal, theOutputFileName);
209          itsSize = theSize;
210       }
211    
212       public Plot() {
213          clear();
214          itsExtra = new Vector<String>();
215          itsParametric = State.OFF;
216          itsPolar = State.OFF;
217       }
218    
219       public final void clear() {
220          // TODO don't if all needs to be cleared or not, e.g.
221          // itsTerminal
222          itsPlotable = false;
223          itsGraphs = new Stack<Graph>();
224          itsTerminal = Terminal.NOT_SPECIFIED;
225          itsOutputFileName = null;
226          itsCommandsOnOneLine = false;
227          itsTitle = null;
228       }
229    
230       public final void clearExtra() {
231          itsExtra = new Vector<String>();
232       }
233    
234       public final void setCommandsOnOneLine(boolean theValue) {
235          itsCommandsOnOneLine = theValue;
236       }
237    
238       public final void pushGraph(Graph theGraph) {
239          itsGraphs.push(new Graph(theGraph)); // TODO precaution for too
240          // enthousiastic Graph recycling
241          itsDataFileName = null;
242          evaluate();
243       }
244    
245       public final Graph popGraph() {
246          Graph aGraph = null;
247          if (itsGraphs.size() != 0) {
248             aGraph = (Graph) itsGraphs.pop();
249             evaluate();
250          }
251          return aGraph;
252       }
253    
254       private static String duplicateDoubleBackSlashes(String theString) {
255          return theString.replaceAll("\\\\", "\\\\\\\\");
256       }
257    
258       public final void setDataFileName(String theDataFileName) { // TODO check when
259          // to
260          // use this
261          itsDataFileName = duplicateDoubleBackSlashes(theDataFileName);
262          itsGraphs.clear();
263          evaluate();
264       }
265    
266       private void evaluate() {
267          if (itsGraphs.size() != 0 || itsDataFileName != null) {
268             itsPlotable = true;
269          }
270          else {
271             itsPlotable = false;
272          }
273       }
274    
275       public final void setXLabel(String theXLabel) {
276          itsXLabel = theXLabel;
277       }
278    
279       public final void setData(String theData) {
280          itsData = theData;
281       }
282    
283       public final void setYLabel(String theYLabel) {
284          itsYLabel = theYLabel;
285       }
286    
287       public final void setX2Label(String theX2Label) {
288          itsX2Label = theX2Label;
289       }
290    
291       public final void setY2Label(String theY2Label) {
292          itsY2Label = theY2Label;
293       }
294    
295       public final void setXTics(String theXTics) {
296          itsXTics = theXTics;
297       }
298    
299       public final void setXTics() {
300          itsXTics = "";
301       }
302    
303       public final void unsetXTics() {
304          itsXTics = null;
305       }
306    
307       public final void setYTics(String theYTics) {
308          itsYTics = theYTics;
309       }
310    
311       public final void setYTics() {
312          itsYTics = "";
313       }
314    
315       public final void unsetYTics() {
316          itsYTics = null;
317       }
318    
319       public final void setX2Tics(String theX2Tics) {
320          itsX2Tics = theX2Tics;
321       }
322    
323       public final void setX2Tics() {
324          itsX2Tics = "";
325       }
326    
327       public final void unsetX2Tics() {
328          itsX2Tics = null;
329       }
330    
331       public final void setY2Tics(String theY2Tics) {
332          itsY2Tics = theY2Tics;
333       }
334    
335       public final void setY2Tics() {
336          itsY2Tics = "";
337       }
338    
339       public final void unsetY2Tics() {
340          itsY2Tics = null;
341       }
342    
343       public final void setMXTics(String theMXTics) {
344          itsMXTics = theMXTics;
345       }
346    
347       public final void setMYTics(String theMYTics) {
348          itsMYTics = theMYTics;
349       }
350    
351       public final void setXData(String theXData) {
352          itsXData = theXData;
353       }
354    
355       public final void setYData(String theYData) {
356          itsYData = theYData;
357       }
358    
359       public final void setTimeFormat(String theTimeFormat) {
360          itsTimeFormat = theTimeFormat;
361       }
362    
363       public static void setGnuplotExecutable(String theGnuplotExecutable) {
364          itsGnuplotExecutable = theGnuplotExecutable;
365       }
366    
367       public static void setPlotDirectory(String thePlotDirectory) {
368          itsPlotDirectory = thePlotDirectory;
369       }
370    
371       public final void setRanges(String theRanges) {
372          itsRanges = theRanges;
373       }
374    
375       public final void setXRange(double theBegin, double theEnd) {
376          itsXRange = toRange(Double.toString(theBegin), Double.toString(theEnd));
377       }
378    
379       public final void setXRange(int theBegin, int theEnd) {
380          itsXRange = toRange(Integer.toString(theBegin), Integer.toString(theEnd));
381       }
382    
383       public final void setXRange(String theBegin, String theEnd) {
384          itsXRange = toRange(theBegin, theEnd);
385       }
386    
387       public final void setX2Range(double theBegin, double theEnd) {
388          itsX2Range = toRange(Double.toString(theBegin), Double.toString(theEnd));
389       }
390    
391       public final void setX2Range(int theBegin, int theEnd) {
392          itsX2Range = toRange(Integer.toString(theBegin), Integer.toString(theEnd));
393       }
394    
395       public final void setX2Range(String theBegin, String theEnd) {
396          itsX2Range = toRange(theBegin, theEnd);
397       }
398    
399       public final void setYRange(double theBegin, double theEnd) {
400          itsYRange = toRange(Double.toString(theBegin), Double.toString(theEnd));
401       }
402    
403       public final void setYRange(int theBegin, int theEnd) {
404          itsYRange = toRange(Integer.toString(theBegin), Integer.toString(theEnd));
405       }
406    
407       public final void setYRange(String theBegin, String theEnd) {
408          itsYRange = toRange(theBegin, theEnd);
409       }
410    
411       public final void setY2Range(double theBegin, double theEnd) {
412          itsY2Range = toRange(Double.toString(theBegin), Double.toString(theEnd));
413       }
414    
415       public final void setY2Range(int theBegin, int theEnd) {
416          itsY2Range = toRange(Integer.toString(theBegin), Integer.toString(theEnd));
417       }
418    
419       public final void setY2Range(String theBegin, String theEnd) {
420          itsY2Range = toRange(theBegin, theEnd);
421       }
422    
423       public final void setTRange(String theBegin, String theEnd) {
424          itsTRange = toRange(theBegin, theEnd);
425       }
426    
427       private final String toRange(String theBegin, String theEnd) {
428          return "[" + String.valueOf(theBegin) + ":" + String.valueOf(theEnd)
429                + "]";
430       }
431    
432       public final void addExtra(String theExtra) {
433          if (!theExtra.trim().startsWith("#") && theExtra.indexOf("=") != -1) {
434             String theKey = theExtra.substring(0, theExtra.indexOf("=")).trim();
435             Enumeration<String> aEnum = ((Vector) itsExtra).elements();
436             while (aEnum.hasMoreElements()) {
437                Object aExtra = aEnum.nextElement();
438                String aKey = (String) aExtra;
439                if (!aKey.trim().startsWith("#") && aKey.indexOf("=") != -1) {
440                   aKey = aKey.substring(0, aKey.indexOf("=")).trim();
441                   if (theKey.equals(aKey)) {
442                      itsExtra.remove(aExtra);
443                      break;
444                   }
445                }
446             }
447          }
448          itsExtra.add(theExtra);
449       }
450    
451       public final void plot() throws IOException, InterruptedException {
452          if (!itsPlotable) {
453             throw new IllegalArgumentException(
454                   "Set data before calling plot method");
455          }
456          String aFileName = itsPlotDirectory + File.separator
457                + String.valueOf(System.currentTimeMillis()) + "-plt.txt";
458          /*
459           * BufferedWriter aOutputDataFile = new BufferedWriter(new
460           * FileWriter(aFileBaseName + ".dat")); Enumeration aDataEnum =
461           * itsData.elements(); while (aDataEnum.hasMoreElements()) {
462           * aOutputDataFile.write((String)aDataEnum.nextElement() + "\n"); }
463           * aOutputDataFile.close();
464           */
465          itsOutputPlotFile = new BufferedWriter(new FileWriter(aFileName));
466          if (itsTitle != null) {
467             itsOutputPlotFile.write("set title \"" + itsTitle + "\"");
468             if (itsCommandsOnOneLine) {
469                itsOutputPlotFile.write("; ");
470             }
471             else {
472                itsOutputPlotFile.write("\n");
473             }
474          }
475          if (itsDataFileSeparator != null) {
476             itsOutputPlotFile.write("set datafile separator \""
477                   + itsDataFileSeparator + "\"");
478             if (itsCommandsOnOneLine) {
479                itsOutputPlotFile.write("; ");
480             }
481             else {
482                itsOutputPlotFile.write("\n");
483             }
484          }
485          if (itsGrid == null) {
486             itsOutputPlotFile.write("unset grid");
487          }
488          else {
489             itsOutputPlotFile.write("set grid");
490             if (!itsGrid.equals("")) {
491                itsOutputPlotFile.write(" " + itsGrid);
492             }
493          }
494          if (itsCommandsOnOneLine) {
495             itsOutputPlotFile.write("; ");
496          }
497          else {
498             itsOutputPlotFile.write("\n");
499          }
500          if (itsKey == null) {
501             itsOutputPlotFile.write("unset key");
502          }
503          else {
504             itsOutputPlotFile.write("set key " + itsKey);
505          }
506          if (itsCommandsOnOneLine) {
507             itsOutputPlotFile.write("; ");
508          }
509          else {
510             itsOutputPlotFile.write("\n");
511          }
512          switch (itsParametric) {
513          case State.ON:
514             itsOutputPlotFile.write("set parametric");
515             if (itsCommandsOnOneLine) {
516                itsOutputPlotFile.write("; ");
517             }
518             else {
519                itsOutputPlotFile.write("\n");
520             }
521             break;
522          case State.OFF:
523             itsOutputPlotFile.write("unset parametric");
524             if (itsCommandsOnOneLine) {
525                itsOutputPlotFile.write("; ");
526             }
527             else {
528                itsOutputPlotFile.write("\n");
529             }
530             break;
531          default:
532             throw new IllegalArgumentException("Invalid parametric state");
533          }
534          switch (itsPolar) {
535          case State.ON:
536             itsOutputPlotFile.write("set polar");
537             if (itsCommandsOnOneLine) {
538                itsOutputPlotFile.write("; ");
539             }
540             else {
541                itsOutputPlotFile.write("\n");
542             }
543             break;
544          case State.OFF:
545             itsOutputPlotFile.write("unset polar");
546             if (itsCommandsOnOneLine) {
547                itsOutputPlotFile.write("; ");
548             }
549             else {
550                itsOutputPlotFile.write("\n");
551             }
552             break;
553          default:
554             throw new IllegalArgumentException("Invalid polar state");
555          }
556          if (itsSamples != null) {
557             itsOutputPlotFile.write("set samples " + itsSamples);
558             if (itsCommandsOnOneLine) {
559                itsOutputPlotFile.write("; ");
560             }
561             else {
562                itsOutputPlotFile.write("\n");
563             }
564          }
565          if (itsDummy != null) {
566             itsOutputPlotFile.write("set dummy " + itsDummy);
567             if (itsCommandsOnOneLine) {
568                itsOutputPlotFile.write("; ");
569             }
570             else {
571                itsOutputPlotFile.write("\n");
572             }
573          }
574          if (itsClip != null) {
575             itsOutputPlotFile.write("set clip");
576             if (!itsClip.equals("")) {
577                itsOutputPlotFile.write(" " + itsClip);
578             }
579             if (itsCommandsOnOneLine) {
580                itsOutputPlotFile.write("; ");
581             }
582             else {
583                itsOutputPlotFile.write("\n");
584             }
585          }
586          if (itsXLabel != null) {
587             itsOutputPlotFile.write("set xlabel \"" + itsXLabel + "\"");
588             if (itsCommandsOnOneLine) {
589                itsOutputPlotFile.write("; ");
590             }
591             else {
592                itsOutputPlotFile.write("\n");
593             }
594          }
595          if (itsYLabel != null) {
596             itsOutputPlotFile.write("set ylabel \"" + itsYLabel + "\"");
597             if (itsCommandsOnOneLine) {
598                itsOutputPlotFile.write("; ");
599             }
600             else {
601                itsOutputPlotFile.write("\n");
602             }
603          }
604          if (itsX2Label != null) {
605             itsOutputPlotFile.write("set x2label \"" + itsX2Label + "\"");
606             if (itsCommandsOnOneLine) {
607                itsOutputPlotFile.write("; ");
608             }
609             else {
610                itsOutputPlotFile.write("\n");
611             }
612          }
613          if (itsY2Label != null) {
614             itsOutputPlotFile.write("set y2label \"" + itsY2Label + "\"");
615             if (itsCommandsOnOneLine) {
616                itsOutputPlotFile.write("; ");
617             }
618             else {
619                itsOutputPlotFile.write("\n");
620             }
621          }
622          if (itsXTics != null) {
623             itsOutputPlotFile.write("set xtics");
624             if (!itsXTics.equals("")) {
625                itsOutputPlotFile.write(" " + itsXTics);
626             }
627             if (itsCommandsOnOneLine) {
628                itsOutputPlotFile.write("; ");
629             }
630             else {
631                itsOutputPlotFile.write("\n");
632             }
633          }
634          if (itsYTics != null) {
635             itsOutputPlotFile.write("set ytics");
636             if (!itsYTics.equals("")) {
637                itsOutputPlotFile.write(" " + itsYTics);
638             }
639             if (itsCommandsOnOneLine) {
640                itsOutputPlotFile.write("; ");
641             }
642             else {
643                itsOutputPlotFile.write("\n");
644             }
645          }
646          if (itsX2Tics != null) {
647             itsOutputPlotFile.write("set x2tics");
648             if (!itsX2Tics.equals("")) {
649                itsOutputPlotFile.write(" " + itsX2Tics);
650             }
651             if (itsCommandsOnOneLine) {
652                itsOutputPlotFile.write("; ");
653             }
654             else {
655                itsOutputPlotFile.write("\n");
656             }
657          }
658          if (itsY2Tics != null) {
659             itsOutputPlotFile.write("set y2tics");
660             if (!itsY2Tics.equals("")) {
661                itsOutputPlotFile.write(" " + itsY2Tics);
662             }
663             if (itsCommandsOnOneLine) {
664                itsOutputPlotFile.write("; ");
665             }
666             else {
667                itsOutputPlotFile.write("\n");
668             }
669          }
670          else {
671             if (itsYTics == null && itsY2Label != null) {
672                // TODO should be according to all used axes
673                itsOutputPlotFile.write("set ytics nomirror");
674                if (itsCommandsOnOneLine) {
675                   itsOutputPlotFile.write("; ");
676                }
677                else {
678                   itsOutputPlotFile.write("\n");
679                }
680                itsOutputPlotFile.write("set y2tics nomirror");
681                if (itsCommandsOnOneLine) {
682                   itsOutputPlotFile.write("; ");
683                }
684                else {
685                   itsOutputPlotFile.write("\n");
686                }
687             }
688          }
689          if (itsMXTics != null) {
690             itsOutputPlotFile.write("set mxtics " + itsMXTics);
691             if (itsCommandsOnOneLine) {
692                itsOutputPlotFile.write("; ");
693             }
694             else {
695                itsOutputPlotFile.write("\n");
696             }
697          }
698          if (itsMYTics != null) {
699             itsOutputPlotFile.write("set mytics " + itsMYTics);
700             if (itsCommandsOnOneLine) {
701                itsOutputPlotFile.write("; ");
702             }
703             else {
704                itsOutputPlotFile.write("\n");
705             }
706          }
707          if (itsTimeFormat != null) {
708             itsOutputPlotFile.write("set timefmt '" + itsTimeFormat + "'");
709             if (itsCommandsOnOneLine) {
710                itsOutputPlotFile.write("; ");
711             }
712             else {
713                itsOutputPlotFile.write("\n");
714             }
715          }
716          if (itsXData != null) {
717             itsOutputPlotFile.write("set xdata " + itsXData);
718             if (itsCommandsOnOneLine) {
719                itsOutputPlotFile.write("; ");
720             }
721             else {
722                itsOutputPlotFile.write("\n");
723             }
724          }
725          if (itsYData != null) {
726             itsOutputPlotFile.write("set ydata " + itsYData);
727             if (itsCommandsOnOneLine) {
728                itsOutputPlotFile.write("; ");
729             }
730             else {
731                itsOutputPlotFile.write("\n");
732             }
733          }
734          if (itsTerminal != Terminal.NOT_SPECIFIED && itsOutputFileName != null) {
735             itsOutputPlotFile.write("set terminal " + itsTerminal);
736             if (itsSize != null) {
737                itsOutputPlotFile.write(" size " + itsSize);
738             }
739             if (itsCommandsOnOneLine) {
740                itsOutputPlotFile.write("; ");
741             }
742             else {
743                itsOutputPlotFile.write("\n");
744             }
745             itsOutputPlotFile.write("set output \"" + itsOutputFileName + "\"");
746             if (itsCommandsOnOneLine) {
747                itsOutputPlotFile.write("; ");
748    
749             }
750             else {
751                itsOutputPlotFile.write("\n");
752             }
753          }
754          Enumeration<String> aEnum = ((Vector) itsExtra).elements();
755          while (aEnum.hasMoreElements()) {
756             itsOutputPlotFile.write((String) aEnum.nextElement());
757             if (itsCommandsOnOneLine) {
758                itsOutputPlotFile.write("; ");
759             }
760             else {
761                itsOutputPlotFile.write("\n");
762             }
763          }
764          if (itsLogscale == null) {
765             itsOutputPlotFile.write("unset logscale");
766          }
767          else {
768             itsOutputPlotFile.write("set logscale");
769             if (!itsLogscale.equals("")) {
770                itsOutputPlotFile.write(" " + itsLogscale);
771             }
772          }
773          if (itsCommandsOnOneLine) {
774             itsOutputPlotFile.write("; ");
775          }
776          else {
777             itsOutputPlotFile.write("\n");
778          }
779          if (!itsAutoscaleAfterRanges) {
780             if (itsAutoscale != null) {
781                itsOutputPlotFile.write("set autoscale");
782                if (!itsAutoscale.equals("")) {
783                   StringTokenizer aST = new StringTokenizer(itsAutoscale, ",");
784                   boolean aFirst = true;
785                   while (aST.hasMoreElements()) {
786                      if (aFirst) {
787                         aFirst = false;
788                      }
789                      else {
790                         itsOutputPlotFile.write(";set autoscale");
791                      }
792                      itsOutputPlotFile.write(" " + (String) aST.nextElement());
793                   }
794                }
795                if (itsCommandsOnOneLine) {
796                   itsOutputPlotFile.write("; ");
797                }
798                else {
799                   itsOutputPlotFile.write("\n");
800                }
801             }
802          }
803          if (itsXRange != null) {
804             itsOutputPlotFile.write("set xrange " + itsXRange);
805             if (itsCommandsOnOneLine) {
806                itsOutputPlotFile.write("; ");
807             }
808             else {
809                itsOutputPlotFile.write("\n");
810             }
811          }
812          if (itsX2Range != null) {
813             itsOutputPlotFile.write("set x2range " + itsX2Range);
814             if (itsCommandsOnOneLine) {
815                itsOutputPlotFile.write("; ");
816             }
817             else {
818                itsOutputPlotFile.write("\n");
819             }
820          }
821          if (itsYRange != null) {
822             itsOutputPlotFile.write("set yrange " + itsYRange);
823             if (itsCommandsOnOneLine) {
824                itsOutputPlotFile.write("; ");
825    
826             }
827             else {
828                itsOutputPlotFile.write("\n");
829             }
830          }
831          if (itsY2Range != null) {
832             itsOutputPlotFile.write("set y2range " + itsY2Range);
833             if (itsCommandsOnOneLine) {
834                itsOutputPlotFile.write("; ");
835             }
836             else {
837                itsOutputPlotFile.write("\n");
838             }
839          }
840          if (itsTRange != null) {
841             itsOutputPlotFile.write("set trange " + itsTRange);
842             if (itsCommandsOnOneLine) {
843                itsOutputPlotFile.write("; ");
844             }
845             else {
846                itsOutputPlotFile.write("\n");
847             }
848          }
849          if (itsAutoscaleAfterRanges) {
850             if (itsAutoscale != null) {
851                itsOutputPlotFile.write("set autoscale");
852                if (!itsAutoscale.equals("")) {
853                   StringTokenizer aST = new StringTokenizer(itsAutoscale, ",");
854                   boolean aFirst = true;
855                   while (aST.hasMoreElements()) {
856                      if (aFirst) {
857                         aFirst = false;
858                      }
859                      else {
860                         itsOutputPlotFile.write(";set autoscale");
861                      }
862                      itsOutputPlotFile.write(" " + (String) aST.nextElement());
863                   }
864                }
865                if (itsCommandsOnOneLine) {
866                   itsOutputPlotFile.write("; ");
867                }
868                else {
869                   itsOutputPlotFile.write("\n");
870                }
871             }
872          }
873          itsOutputPlotFile.write("plot");
874          if (itsRanges != null) {
875             itsOutputPlotFile.write(" " + itsRanges);
876          }
877          if (itsGraphs.size() == 0) {
878             itsOutputPlotFile.write("\t\"" + itsDataFileName + "\"");
879             if (itsCommandsOnOneLine) {
880                itsOutputPlotFile.write("; ");
881             }
882             else {
883                itsOutputPlotFile.write("\n");
884             }
885          }
886          else {
887             for (int i = 0; i < itsGraphs.size(); i++) {
888                Graph aGraph = (Graph) itsGraphs.elementAt(i);
889                if (itsCommandsOnOneLine) {
890                   itsOutputPlotFile.write(" ");
891                }
892                else {
893                   itsOutputPlotFile.write("\t");
894                }
895                if (aGraph.isFunction()) {
896                   // function
897                   itsOutputPlotFile.write(aGraph.getFunction());
898                }
899                else {
900                   // data file
901                   itsOutputPlotFile.write("\""
902                         + duplicateDoubleBackSlashes(aGraph.getDataFileName())
903                         + "\"");
904                   // columns to use
905                   if (aGraph.getUsing() != null) {
906                      itsOutputPlotFile.write(" using " + aGraph.getUsing());
907                   }
908                   // data modifiers
909                   if (aGraph.getDataModifiers() != null) {
910                      itsOutputPlotFile.write(" " + aGraph.getDataModifiers());
911                   }
912                }
913                // axes to use
914                if (aGraph.getAxes() != null) {
915                   itsOutputPlotFile.write(" axes " + aGraph.getAxes());
916                }
917                // title / name
918                if (aGraph.getName() != null) {
919                   if (aGraph.getName().equals("")) {
920                      itsOutputPlotFile.write(" notitle");
921                   }
922                   else {
923                      itsOutputPlotFile.write(" title \"" + aGraph.getName() + "\"");
924                   }
925                }
926                // style
927                if (aGraph.getStyle() != Style.NOT_SPECIFIED) {
928                   itsOutputPlotFile.write(" with "
929                         + Style.toString(aGraph.getStyle()));
930                   if (aGraph.getLineType() != LineType.NOT_SPECIFIED) {
931                      itsOutputPlotFile.write(" lt " + aGraph.getLineType());
932                   }
933                   if (aGraph.getPointType() != PointType.NOT_SPECIFIED
934                         && (aGraph.getStyle() == Style.POINTS || aGraph.getStyle() == Style.LINESPOINTS)) {
935                      itsOutputPlotFile.write(" pt " + aGraph.getPointType());
936                   }
937                }
938                if (i != itsGraphs.size() - 1) {
939                   itsOutputPlotFile.write(",");
940                }
941                if (!itsCommandsOnOneLine) {
942                   if (i != itsGraphs.size() - 1) {
943                      itsOutputPlotFile.write("\\");
944                   }
945                   itsOutputPlotFile.write("\n");
946                }
947             }
948          }
949          if (itsCommandsOnOneLine) {
950             itsOutputPlotFile.write("; ");
951          }
952          if (itsTerminal == Terminal.NOT_SPECIFIED && itsOutputFileName == null) {
953             itsOutputPlotFile.write("pause -1 \"Hit return to continue\"\n");
954          }
955          else {
956             itsOutputPlotFile.write("\n");
957          }
958          if (itsData != null) {
959             if (!itsCommandsOnOneLine) {
960                throw new IllegalArgumentException(
961                      "Commands should be on one line when data has been set");
962             }
963             itsOutputPlotFile.write(itsData);
964          }
965          itsOutputPlotFile.close();
966          if (itsOutputFileName != null) {
967             File aFile = new File(itsOutputFileName);
968             aFile = new File(aFile.getParent());
969             if (!aFile.canWrite()) {
970                if (!aFile.mkdirs()) {
971                   throw new IOException("Could not create directory "
972                         + aFile.getParent());
973                }
974             }
975          }
976          Process aProcess = Runtime.getRuntime().exec(
977                itsGnuplotExecutable + " " + aFileName);
978          Thread.currentThread().sleep(1000);
979          aProcess.waitFor();
980          // TODO Remove temporary -plt.txt file and make it configurable for
981          // debug purposes via system properties. Better and preferred is to
982          // directly stream it into gnuplot.
983       }
984    }