Beispiel #1
0
// CONSTRUCTOR
GPViewCurveNode::GPViewCurveNode( Widget          Toplevel,
                                  DPV_TextBuffer *Textbuf,
                                  DPC_curve      *Curve,
                                  int             Curve_number
                                ) {

    const char * presentation;
    double    x, y;
    std::string       curve_x_label;
    std::string       curve_x_min_rng;
    std::string       curve_x_max_rng;
    std::string       curve_x_scale_factor;
    std::string       curve_x_bias;
    std::string       curve_y_label;
    std::string       curve_y_min_rng;
    std::string       curve_y_max_rng;
    std::string       curve_y_scale_factor;
    std::string       curve_y_bias;
    std::string       curve_line_color;
    std::string       curve_line_style;
    std::string       curve_gp_line_style;
    std::string       curve_symbol_style;
    std::string       curve_symbol_size;
    std::string       tmp_string;
    std::stringstream tmp_stream;

    toplevel = Toplevel;
    dpc_curve = Curve;

    data_src_label = (Curve->getDataSrcLbl()) ? Curve->getDataSrcLbl() : "" ;

    /*
     If present, the curves label is THE label of the curve. It represents what the
     user wants to see and should not be altered. If it is not present, then a label
     is generated from the variable name and the units.
     */
    if (Curve->getXAttribute("label")) {
        curve_x_label = Curve->getXAttribute("label");
    } else {
        std::string curve_x_var_name = (dpc_curve->getXVarName()) ? dpc_curve->getXVarName() : "" ;
        std::string curve_x_units    = (dpc_curve->getXAttribute("units")) ?  dpc_curve->getXAttribute("units") : "--";
        curve_x_label    = curve_x_var_name + "(" + curve_x_units + ")";
    }

    std::string curve_y_var_name = (dpc_curve->getYVarName()) ? dpc_curve->getYVarName() : "" ;
    if (Curve->getYAttribute("label")) {
        curve_y_label = Curve->getYAttribute("label");
    } else {
        std::string curve_y_units    = (dpc_curve->getYAttribute("units")) ?  dpc_curve->getYAttribute("units") : "--";
        curve_y_label    = curve_y_var_name + "(" + curve_y_units + ")"; 
    }

    std::string curve_title = curve_y_label + " VS. " + curve_x_label + " ["+data_src_label+"]";

    /**!
     * WARNING: getAttribute() returns a const char *, which may be null.
     *          Assigning a null pointer to a string will crash the plot.
     *          So, check the return value before making the assignment.
     */
    curve_x_min_rng      = (dpc_curve->getXAttribute("min")) ?  dpc_curve->getXAttribute("min") : "";
    curve_x_max_rng      = (dpc_curve->getXAttribute("max")) ?  dpc_curve->getXAttribute("max") : "";
    curve_x_scale_factor = (dpc_curve->getXAttribute("scale")) ?  dpc_curve->getXAttribute("scale") : "1.0";
    curve_x_bias         = (dpc_curve->getXAttribute("bias")) ?  dpc_curve->getXAttribute("bias") : "0.0";
    curve_y_min_rng      = (dpc_curve->getYAttribute("min")) ?  dpc_curve->getYAttribute("min") : "";
    curve_y_max_rng      = (dpc_curve->getYAttribute("max")) ?  dpc_curve->getYAttribute("max") : "";
    curve_y_scale_factor = (dpc_curve->getYAttribute("scale")) ?  dpc_curve->getYAttribute("scale") : "1.0";
    curve_y_bias         = (dpc_curve->getYAttribute("bias")) ?  dpc_curve->getYAttribute("bias") : "0.0";
    curve_line_color     = (dpc_curve->getYAttribute("line_color")) ?  dpc_curve->getYAttribute("line_color") : "";
    curve_line_style     = (dpc_curve->getYAttribute("line_style")) ?  dpc_curve->getYAttribute("line_style") : "";
    curve_gp_line_style  = (dpc_curve->getYAttribute("gnuplot_line_style")) ?  dpc_curve->getYAttribute("gnuplot_line_style") : "lines";
    curve_symbol_style   = (dpc_curve->getYAttribute("symbol_style")) ?  dpc_curve->getYAttribute("symbol_style") : "";
    curve_symbol_size    = (dpc_curve->getYAttribute("symbol_size")) ?  dpc_curve->getYAttribute("symbol_size") : "Small";

    std::string save_template = "<SAVE_TMP_FILE_SPEC>";
    std::string prev_TmpFileSpec = "";

    //------------------------------------------------------------------
    // Set the XYCurve's data points (points) and number of points (nPoints)
    //------------------------------------------------------------------

    presentation = Curve->getYAttribute("presentation") ;

    if ( (presentation != NULL)  &&  strcasecmp(presentation, "stream") != 0 ) {

        char curve_data_file_name[512];
        FILE *curve_data_fp;

        //! Figure out where we can create a temporary file.
        if (!access("/tmp", W_OK)) {

            strncpy(curve_data_file_name,
                    "/tmp/dpx_gp_curve_XXXXXX", sizeof(curve_data_file_name));

        } else if (!access("/var/tmp", W_OK)) {
            strncpy(curve_data_file_name,
                    "/var/tmp/dpx_gp_curve_XXXXXX", sizeof(curve_data_file_name));

        } else {
            std::cerr << "Unable to access /tmp or /var/tmp, where a temporary\n"
                << "file (that represents gnuplot curve data) needs\n"
                << "to be created. Please check your permissions." << std::endl ;
            return;
        }

        //! Create a name for our temporary data file.
        if (mkstemp( curve_data_file_name) < 0) {
            std::cerr << "Unable to generate a temporary file"
                << "name for some mind boggling reason." << std::endl ;
            return;
        }

        //! Open the temporary data file.
        if ((curve_data_fp = fopen( curve_data_file_name, "w")) == NULL) {
            std::cerr << "Unable to open a temporary file." << std::endl ;
            return;
        }

        //! Get the data for the curve.
        while ( Curve->getXY(&x, &y)) {
            fprintf( curve_data_fp,"%e\t%e\n",
              ( x*atof(curve_x_scale_factor.c_str()) + atof(curve_x_bias.c_str()) ),
              ( y*atof(curve_y_scale_factor.c_str()) + atof(curve_y_bias.c_str()) ) );
        }
        fclose(curve_data_fp);

        if ( Curve_number == 0 ) {
            /*!
             * Set ranges as part of the plot command. A range given on the plot
             * command will be used for all curves on that single graph only, &
             * not for all subsequent graphs(e.g. plot [xmin:xmax] [ymin:ymax] )
             */
            //! Set each curve's X Var MIN RANGE.
            if ( ! curve_x_min_rng.empty() ) {
                Textbuf->print("[%d:", curve_x_min_rng.c_str());
            } else {
                Textbuf->print("[<PLOT_X_MIN_RNG>:");
            }
            //! Set each curve's X Var MAX RANGE.
            if ( ! curve_x_max_rng.empty() ) {
                Textbuf->print("%d]", curve_x_max_rng.c_str());
            } else {
                Textbuf->print("<PLOT_X_MAX_RNG>]");
            }
            //! Set each curve's Y Var MIN RANGE.
            if ( ! curve_y_min_rng.empty() ) {
                Textbuf->print("[%d:", curve_y_min_rng.c_str());
            } else {
                Textbuf->print("[<PLOT_Y_MIN_RNG>:");
            }
            //! Set each curve's Y Var MAX RANGE.
            if ( ! curve_y_max_rng.empty() ) {
                Textbuf->print("%d]", curve_y_max_rng.c_str());
            } else {
                Textbuf->print("<PLOT_Y_MAX_RNG>]");
            }

            Textbuf->print(" \\\n");

        } else if ( Curve_number > 0 ) {
            /* At this point, the `plot` command is drawing multiple
             * lines (curves) onto the same graph.
             * The `plot` command will not work if other non-plot text
             * (i.e. system commands) exist within the curve info list.
             * We need to save off all system commands from the buffer
             * that delete the previous curves' temporary datafile(s).
             * We will re-insert later once this curve's info is written.
             */
            tmp_string = Textbuf->getText();
            int save_startPos = (int)tmp_string.find("\n"+save_template, 0);

            prev_TmpFileSpec = tmp_string.substr( save_startPos, tmp_string.size() );

            /* Remove previous system commands */
            Textbuf->subst_g(prev_TmpFileSpec.c_str(), "");

            //! insert a comma, space, backslash(\) & newline prior to next curve info
            Textbuf->print(", \\\n", " ");
        }

        //! Indent 4 spaces then Populate the datafile name.
        Textbuf->print("%4s\"%s\" using 1:2",  " ", curve_data_file_name);

        //! Set each curve's TITLE.
        Textbuf->print("  t \"%s\"", curve_title.c_str());

        //! Set each curve's GP LINE STYLE.
        Textbuf->print(" w %s", curve_gp_line_style.c_str());

        if ( GnuplotVersion() >= 4.2 ) {
            //! Default line definitions.
            Textbuf->print(" lt line_type_%i", (Curve_number+1));
            Textbuf->print(" lw 1.0");

            //! Set each curve's LINE COLOR.
            if ( ! curve_line_color.empty() ) {
                if ( color_is_valid(&curve_line_color) ) {
                    Textbuf->print(" lc rgb \"%s\"", curve_line_color.c_str());
                }
            }

            //! POINT settings are applicable to points & linepoints only.
            if ( curve_gp_line_style.find("point") != std::string::npos ) {
                //! Set each curve's POINT TYPE.
                if ( ! curve_symbol_style.empty() ) {
                    Textbuf->print(" pt %s", curve_symbol_style.c_str());
                } else {
                    Textbuf->print(" pt point_shape_%i", (Curve_number+1));
                }
                //! Set each curve's POINT SIZE.
                Textbuf->print(" ps %s", curve_symbol_size.c_str());
            }
        } else {
            /*!
             * Setting line color in gnuplot version 4.0 or older cannot be done
             * on the fly. It must be set using a limited number of line styles
             * or at startup (e.g. -xrm 'gnuplot*line1Color:black'...).
             */
            Textbuf->print(" linestyle %i", (Curve_number+1) );
            if (!curve_line_color.empty()) {
                std::cout << "note: Ignoring line color; " ;
                std::cout << "feature only available in Gnuplot version 4.2 (or later)." << std::endl;
            }
        }

        /* Re-insert previous system commands */
        Textbuf->print("%s\n", prev_TmpFileSpec.c_str());
        /*!
         * After the command to plot the curve is processed, add
         * a system command to delete the associated data file.
         * Run the delete command in the background.
         */
        Textbuf->print("%ssystem \"rm -f %s &\"", save_template.c_str(), curve_data_file_name);
    }

    instance_count ++;
}
Beispiel #2
0
void GPViewPlotNode::finalize() {

    std::string       plot_data_src_label;
    std::string       plot_title;
    std::string       plot_x_label;
    std::string       plot_x_units;
    std::string       plot_x_scale;
    std::string       plot_x_min_rng;
    std::string       plot_x_max_rng;
    std::string       plot_y_label;
    std::string       plot_y_units;
    std::string       plot_y_format;
    std::string       plot_y_scale;
    std::string       plot_y_min_rng;
    std::string       plot_y_max_rng;
    std::string       plot_fg_color;
    std::string       plot_bg_color;
    std::string       show_grid;
    std::string       grid_color;
    std::string       plot_font;
    int          n_curves;
    std::stringstream tmp_stream;

    //! Plot info is taken from file: '/tmp/DP_*.xml'
    tmp_stream.str("");
    tmp_stream << "Plot " << instance_count+1 ;

    n_curves = plot->getNumCurves();

    /**!
     * WARNING: getAttribute() returns a const char *, which may be null.
     *          Assigning a null pointer to a string will crash the plot.
     *          So, check the return value before making the assignment.
     */
    plot_title      = (plot->getTitle()) ?  plot->getTitle() : tmp_stream.str();
    plot_x_label    = (plot->getXLabel()) ?  plot->getXLabel() : "";
    plot_x_scale    = (plot->getAttribute("x_scale")) ?  plot->getAttribute("x_scale") : "";
    plot_x_min_rng  = (plot->getAttribute("xmin")) ?  plot->getAttribute("xmin") : "";
    plot_x_max_rng  = (plot->getAttribute("xmax")) ?  plot->getAttribute("xmax") : "";
    plot_y_label    = (plot->getYLabel()) ?  plot->getYLabel() : "";
    plot_y_format   = (plot->getAttribute("format")) ?  plot->getAttribute("format") : "";
    plot_y_scale    = (plot->getAttribute("y_scale")) ?  plot->getAttribute("y_scale") : "";
    plot_y_min_rng  = (plot->getAttribute("ymin")) ?  plot->getAttribute("ymin") : "";
    plot_y_max_rng  = (plot->getAttribute("ymax")) ?  plot->getAttribute("ymax") : "";
    plot_fg_color   = (plot->getAttribute("foreground_color")) ?  plot->getAttribute("foreground_color") : "";
    plot_bg_color   = (plot->getAttribute("background_color")) ?  plot->getAttribute("background_color") : "";
    show_grid       = (plot->getAttribute("grid")) ?  plot->getAttribute("grid") : "";
    grid_color      = (plot->getAttribute("grid_color")) ?  plot->getAttribute("grid_color") : "";
    plot_font       = (plot->getAttribute("font")) ?  plot->getAttribute("font") : "";

    if (n_curves == 1) {
        plot_data_src_label = curve_node_list[0]->data_src_label;
        if (!plot_data_src_label.empty()) {
            /* Append SIM/RUN_ name to plot title */
            plot_title.append("\\n" );  /* add a newline after Plot title */
            plot_title.append("(" + plot_data_src_label + ")");
        }
    }

    //! plot_width and plot_height values are assigned in the Page constructor.
    textbuf->subst_g( "<PLOT_SIZE_SPEC>", "plot_width, plot_height") ;

    if (n_curves > 10) {
        // too many curves to have a legend
        textbuf->subst_g( "<PLOT_KEY_SPEC>", "set key off \n" );
    } else {
        // use default page setting
        textbuf->subst_g( "<PLOT_KEY_SPEC>", "<PAGE_KEY_SPEC>" );
    }

    //! Set the plot's TITLE.
    plot_title.insert( 0, "\\n" );  /* add a newline between Page title */
    textbuf->subst_g( "<PLOT_TITLE>", plot_title.c_str() );

    //! Set the plot's X AXIS LABEL.
    if ( ! plot_x_label.empty() ) {
        textbuf->subst_g( "<PLOT_X_AXIS_LABEL>", plot_x_label.c_str() );
    } else {
        textbuf->subst_g( "<PLOT_X_AXIS_LABEL>", "" );
    }

    //! Set the plot's X AXIS SCALING.
    if ( plot_x_scale.compare("Log") == 0 ) {
        textbuf->subst_g( "<PLOT_X_AXIS_SCALING_SPEC>", "set logscale x\n" );
    } else {
        textbuf->subst_g( "<PLOT_X_AXIS_SCALING_SPEC>", "<PAGE_X_AXIS_SCALING_SPEC>" );
    }

    //! Set the plot's X MIN RANGE.
    if ( ! plot_x_min_rng.empty() ) {
        textbuf->subst_g( "<PLOT_X_MIN_RNG>", plot_x_min_rng.c_str() );
    } else {
        textbuf->subst_g( "<PLOT_X_MIN_RNG>", "" );  /* keep current range */
    }

    //! Set the plot's X MAX RANGE.
    if ( ! plot_x_max_rng.empty() ) {
        textbuf->subst_g( "<PLOT_X_MAX_RNG>", plot_x_max_rng.c_str() );
    } else {
        textbuf->subst_g( "<PLOT_X_MAX_RNG>", "" );  /* keep current range */
    }

    //! Set the plot's Y AXIS LABEL.
    if ( ! plot_y_label.empty() ) {
        textbuf->subst_g( "<PLOT_Y_AXIS_LABEL>", plot_y_label.c_str() );
    } else {
        textbuf->subst_g( "<PLOT_Y_AXIS_LABEL>", "" );
    }

    //! Set the plot's Y AXIS UNITS.
    if ( ! plot_y_units.empty() ) {
        textbuf->subst_g( "<PLOT_Y_AXIS_UNITS>", plot_y_units.c_str() );
    } else {
        textbuf->subst_g( "<PLOT_Y_AXIS_UNITS>", "" );
    }

    //! Set the plot's Y AXIS FORMAT.
    if ( ! plot_y_format.empty() ) {
        tmp_stream.str("");
        tmp_stream << "set format y \'" << plot_y_format << "\'\n" ;
        textbuf->subst_g( "<PLOT_Y_AXIS_FORMAT_SPEC>", tmp_stream.str().c_str() );
    } else {
        textbuf->subst_g( "<PLOT_Y_AXIS_FORMAT_SPEC>", "<PAGE_Y_AXIS_FORMAT_SPEC>" );
    }

    //! Set the plot's Y AXIS SCALING.
    if ( plot_y_scale.compare("Log") == 0 ) {
        textbuf->subst_g( "<PLOT_Y_AXIS_SCALING_SPEC>", "set logscale y\n" );
    } else {
        textbuf->subst_g( "<PLOT_Y_AXIS_SCALING_SPEC>", "<PAGE_Y_AXIS_SCALING_SPEC>" );
    }

    //! Set the plot's Y MIN RANGE.
    if ( ! plot_y_min_rng.empty() ) {
        textbuf->subst_g( "<PLOT_Y_MIN_RNG>", plot_y_min_rng.c_str() );
    } else {
        textbuf->subst_g( "<PLOT_Y_MIN_RNG>", "" );  /* keep current range */
    }

    //! Set the plot's Y MAX RANGE.
    if ( ! plot_y_max_rng.empty() ) {
        textbuf->subst_g( "<PLOT_Y_MAX_RNG>", plot_y_max_rng.c_str() );
    } else {
        textbuf->subst_g( "<PLOT_Y_MAX_RNG>", "" );  /* keep current range */
    }

    /*!
     * Set the plot's FOREGROUND COLOR.
     * (Feature only available in Gnuplot version 4.2, or later.)
     */
    tmp_stream.str("");
    if ( GnuplotVersion() < 4.2  ||  plot_fg_color.empty()  ||
         !color_is_valid(&plot_fg_color) ) {
        tmp_stream << "#" ; /* comment out the textcolor command */
    }
    tmp_stream << "textcolor rgb \"" << plot_fg_color << "\"" ;
    textbuf->subst_g( "<PLOT_TEXT_COLOR_SPEC>", tmp_stream.str().c_str() );
    textbuf->subst_g( "<PLOT_FOREGROUND_SPEC>", "<PAGE_FOREGROUND_SPEC>" );

    /*!
     * Set the plot's BACKGROUND COLOR.
     * (Feature only available in Gnuplot version 4.2, or later.)
     */
    if ( GnuplotVersion() >= 4.2 ) {
        tmp_stream.str("");
        tmp_stream << "set object 1 rect default; ";
        tmp_stream << "unset object 1 #Clear previous plot background color" << std::endl;
        if ( ! plot_bg_color.empty()  &&  color_is_valid(&plot_bg_color) ) {
            tmp_stream << "set object 1 rectangle";
            tmp_stream << " from graph 0, graph 0 to graph 1, graph 1 behind" << std::endl;
            tmp_stream << "set object 1 rectangle";
            tmp_stream << " fc rgb \"" << plot_bg_color << "\"" << std::endl;
            textbuf->subst_g( "<PLOT_BACKGROUND_SPEC>", tmp_stream.str().c_str() );
        } else {
            textbuf->subst_g( "<PLOT_BACKGROUND_SPEC>", tmp_stream.str().c_str() );
        }
    } else {
            textbuf->subst_g( "<PLOT_BACKGROUND_SPEC>", "<PAGE_BACKGROUND_SPEC>" );
    }

    //! Enable/Disable Grid.
    if ( show_grid.compare("No") == 0 ) {
        textbuf->subst_g( "<PLOT_GRID_SPEC>", "unset grid" );
        textbuf->subst_g( "<PLOT_GRID_COLOR_SPEC>", "" );
    } else {
        textbuf->subst_g( "<PLOT_GRID_SPEC>", "<PAGE_GRID_SPEC>" );

        /*!
         * Set the plot's GRID COLOR.
         * (Feature only available in Gnuplot version 4.2, or later.)
         */
        if ( GnuplotVersion() >= 4.2  &&
             ! grid_color.empty()  &&  color_is_valid(&grid_color) ) {
            tmp_stream.str("");
            tmp_stream << "linecolor rgb \"" << grid_color << "\"" ;
            //! Also change border color to match grid color
            tmp_stream << "\nset border linecolor rgb \"" << grid_color << "\"" ;
            textbuf->subst_g( "<PLOT_GRID_COLOR_SPEC>", tmp_stream.str().c_str() );
        } else {
            textbuf->subst_g( "<PLOT_GRID_COLOR_SPEC>", "<PAGE_GRID_COLOR_SPEC>" );
        }
    }

    //! Set the plot's FONT.
    if ( ! plot_font.empty() ) {
        tmp_stream.str("");
        //! insert a backslash(\), newline & indent 4 spaces
        tmp_stream << "\\\n    font \"" << plot_font << "\"" ;
        textbuf->subst_g( "<PLOT_FONT_SPEC>", tmp_stream.str().c_str() );
    } else {
        textbuf->subst_g( "<PLOT_FONT_SPEC>", "<PAGE_FONT_SPEC>" );
    }

}
Beispiel #3
0
void GPViewPageNode::finalize() {

    int ii;
    const char *separator = "#------------------------------------------------\n";
    const char *new_section = "\n\n";
    string       page_title;
    string       page_legend;
    string       page_fg_color;
    string       page_bg_color;
    string       page_font; /* X11 font naming convention */
    char gp_template_file_name[512];
    char outFileName[512];
    string tmp_string;
    stringstream tmp_stream;
    stringstream cmd;
    string extension;
    string::size_type idx;
    int xx_geom = 850;  //default gnuplot window width
    int yy_geom = 657;  //default gnuplot window height
    int max_num_curves = 0;

    /*!
     * Gnuplot knows a limited number of color names.
     * To see the list of known color names, run...
     * % gnuplot -e 'show palette colornames'
     */
    string plotColors[]= { "black", "red", "blue", "green", "magenta",
                           "yellow", "cyan", "pink", "dark-green",
                           "light-blue",  "purple", "orange", "brown" };
    int n_CustomColors = sizeof(plotColors)/sizeof(plotColors[0]);

    /**!
     * WARNING: getAttribute() returns a const char *, which may be null.
     *          Assigning a null pointer to a string will crash the plot.
     *          So, check the return value before making the assignment.
     */
    page_title       = (page->getTitle()) ?  page->getTitle() : "Page";
    page_legend      = (page->getAttribute("legend")) ?  page->getAttribute("legend") : "";
    page_bg_color    = (page->getAttribute("background_color")) ?  page->getAttribute("background_color") : "";
    page_fg_color    = (page->getAttribute("foreground_color")) ?  page->getAttribute("foreground_color") : "";
    page_font        = (page->getAttribute("font")) ?  page->getAttribute("font") : "";


    //! Nomultiplot command
    textbuf.print("\n");
    textbuf.print("%s", new_section);
    textbuf.print("%s", separator);
    textbuf.print("# For some terminals, plots are not displayed\n");
    textbuf.print("# until the command `unset multiplot` is given.\n");
    textbuf.print("# Return to single plot mode to switch device\n");
    textbuf.print("%s", separator);
    textbuf.print("unset multiplot\n");


    //! Get Gnuplot Terminal setting
    terminalType_txt = (page->getAttribute("gnuplot_terminal")) ?  page->getAttribute("gnuplot_terminal") : "";
    if ( strcasecmp(terminalType_txt.c_str(), "X11") == 0 ) {

        terminalType = GPViewPageNode::X11;
        terminalType_txt = "x11";

    } else if ( strcasecmp(terminalType_txt.c_str(), "PS") == 0 ) {

        terminalType = GPViewPageNode::PS;
        terminalType_txt = "postscript";
        extension = ".ps";

    } else if ( strcasecmp(terminalType_txt.c_str(), "PS_COLOR") == 0 ) {

        terminalType = GPViewPageNode::PS_COLOR;
        terminalType_txt = "postscript";
        extension = ".ps";

    } else if ( strcasecmp(terminalType_txt.c_str(), "PNG") == 0 ) {

        terminalType = GPViewPageNode::PNG;
        terminalType_txt = "png";
        extension = ".png";

    } else if ( strcasecmp(terminalType_txt.c_str(), "EPS") == 0 ) {

        terminalType = GPViewPageNode::EPS;
        terminalType_txt = "eps";
        extension = ".eps";

    } else if ( strcasecmp(terminalType_txt.c_str(), "AQUA") == 0 ) {

        terminalType = GPViewPageNode::AQUA;
        terminalType_txt = "x11";

    }  else {
        cerr << "ERROR: Bad terminal-type spec: \"" << tmp_string << "\"" << endl;
        cerr << "Defaulting terminal-type to \"x11.\"" << endl;
        terminalType = GPViewPageNode::X11 ;
        terminalType_txt = "x11";
    }


    //! Get Destination setting
    device_txt = (page->getAttribute("device")) ?  page->getAttribute("device") : "";
    if ( strcasecmp(device_txt.c_str(), "TERMINAL") == 0 ) {

        device = GPViewPageNode::TERMINAL;

    } else if ( strncasecmp(device_txt.c_str(), "FILE", 4) == 0 ) {

        device = GPViewPageNode::DISK ;
        //! copy from first space character to end of string
        diskFileName = device_txt.substr( device_txt.find(" ") );

        //! output may not redirect to file format with some terminal types
        switch ( terminalType ) {
            case GPViewPageNode::X11:
            case GPViewPageNode::AQUA:
                //! Force to a different format before going to file.
                terminalType_txt = "postscript";
                extension = ".ps";
                break;
            default:
                break;
        }

    } else if ( strcasecmp(device_txt.c_str(), "PRINTER") == 0 ) {

        device = GPViewPageNode::PRINTER;
        terminalType_txt = "postscript";

    }  else {
        cerr << "ERROR: Bad device spec: \"" << device_txt << "\"" << endl;
        cerr << "Defaulting device to \"Terminal.\"" << endl;
        device = GPViewPageNode::TERMINAL;
    }


    // ==================================================
    //                POPULATE THE TEMPLATE
    // ==================================================
    tmp_stream.str("");
    tmp_stream << GnuplotVersion() ;
    textbuf.subst_g("<GNUPLOT_VERSION>", tmp_stream.str().c_str() );
    textbuf.subst_g("<PAGE_TITLE>", page_title.c_str());
    textbuf.subst_g("<TERM_TYPE>", terminalType_txt.c_str());
    if ( (plot_node_list.size()%5 == 2  ||  plot_node_list.size()%5 == 3)  &&
          plot_node_list.size() > 2 ) {
        xx_geom = 600;
        yy_geom = 720;
    }
    tmp_stream.str("");
    tmp_stream << "size " << xx_geom << "," << yy_geom ;
    textbuf.subst_g("<CANVAS_SIZE>", tmp_stream.str().c_str() );
    if ( strcasecmp(terminalType_txt.c_str(), "x11") == 0 ) {
        if ( GnuplotVersion() >= 4.0 ) {
            textbuf.subst_g("<TERM_OPTIONS>", "persist");
        }
    } else {
        textbuf.subst_g("<TERM_OPTIONS>", "");
    }

    //! Enable/Disable Grid
    textbuf.subst_g("<PAGE_GRID_SPEC>", "set grid");
    if ( GnuplotVersion() >= 4.2  &&
            ! page_fg_color.empty()  &&  color_is_valid(&page_fg_color) ) {
        tmp_stream.str("");
        tmp_stream << "linecolor rgb \"" << page_fg_color << "\"" ;
        //! Also change border color to match grid color
        tmp_stream << "\nset border linecolor rgb \"" << page_fg_color << "\"" ;
        textbuf.subst_g( "<PAGE_GRID_COLOR_SPEC>", tmp_stream.str().c_str() );
    } else {
        textbuf.subst_g( "<PAGE_GRID_COLOR_SPEC>", "" );
    }

    //! plotting style for Data plots
    textbuf.subst_g("<STYLE_DATA_SPEC>", "lines");
    //! plotting style for Function plots
    textbuf.subst_g("<STYLE_FUNC_SPEC>", "lines");

    textbuf.subst_g("<PAGE_X_AXIS_SCALING_SPEC>", "unset logscale x\n");
    textbuf.subst_g("<PAGE_Y_AXIS_FORMAT_SPEC>", "set format y\n");
    textbuf.subst_g("<PAGE_Y_AXIS_SCALING_SPEC>", "unset logscale y\n");
    textbuf.subst_g("<PAGE_FOREGROUND_SPEC>", "");
    textbuf.subst_g("<PAGE_BACKGROUND_SPEC>", "");

    //! Enable/Disable key (legend).
    if ( page_legend.compare("No") == 0 ) {
        if ( GnuplotVersion() >= 4.0 ) {
                textbuf.subst_g("<PAGE_KEY_SPEC>", "set key off\n");
        } else {
                textbuf.subst_g("<PAGE_KEY_SPEC>", "set nokey\n");
        }
    } else {
        string vert_spacing_ = "";
        if ( GnuplotVersion() < 4.2 ) {
            vert_spacing_ = " spacing 0.5";
        }
        tmp_stream.str("");
        tmp_stream << "set key below Left reverse" << vert_spacing_ << "\n" ;
        textbuf.subst_g( "<PAGE_KEY_SPEC>", tmp_stream.str().c_str() );

        /* Increase window size so key doesn't cause graph to shrink */
        for (ii = 0;  ii < (int)plot_node_list.size();  ii++) {
            if ((int)plot_node_list[ii]->curve_node_list.size() > max_num_curves) {
                max_num_curves = plot_node_list[ii]->curve_node_list.size();
            }
        }
        yy_geom += max_num_curves*10;  // stretch 10 pixels per Y-var label
    }

    //! Set Font
    if (  ! page_font.empty() ) {
        tmp_stream.str("");
        //! insert a backslash(\), newline & indent 4 spaces
        tmp_stream << "\\\n    font \"" << page_font << "\"" ;
        textbuf.subst_g( "<PAGE_FONT_SPEC>", tmp_stream.str().c_str() );
    } else {
        textbuf.subst_g("<PAGE_FONT_SPEC>", "\\\n    font <DEFAULT_FONT>");
    }

    textbuf.subst_g("<LINE_TYPE_1>",  "-1 #black");
    textbuf.subst_g("<LINE_TYPE_2>",  " 1 #red");
    textbuf.subst_g("<LINE_TYPE_3>",  " 3 #blue");
    textbuf.subst_g("<LINE_TYPE_4>",  " 2 #green");
    textbuf.subst_g("<LINE_TYPE_5>",  " 0 #magenta");
    textbuf.subst_g("<LINE_TYPE_6>",  " 7 #yellow");
    textbuf.subst_g("<LINE_TYPE_7>",  " 5 #cyan");
    textbuf.subst_g("<LINE_TYPE_8>",  " 0 #pink");
    textbuf.subst_g("<LINE_TYPE_9>",  " 0 #dark-green");
    textbuf.subst_g("<LINE_TYPE_10>", " 0 #light-blue");
    textbuf.subst_g("<LINE_TYPE_11>", " 4 #purple");
    textbuf.subst_g("<LINE_TYPE_12>", " 8 #orange");
    textbuf.subst_g("<LINE_TYPE_13>", " 6 #brown");

    textbuf.subst_g("<POINT_SHAPE_1>",  " 1 #plus");
    textbuf.subst_g("<POINT_SHAPE_2>",  " 2 #cross");
    textbuf.subst_g("<POINT_SHAPE_3>",  " 3 #astrisk");
    textbuf.subst_g("<POINT_SHAPE_4>",  " 4 #open_square");
    textbuf.subst_g("<POINT_SHAPE_5>",  " 5 #filled_square");
    textbuf.subst_g("<POINT_SHAPE_6>",  " 6 #open_circle");
    textbuf.subst_g("<POINT_SHAPE_7>",  " 7 #filled_circle");
    textbuf.subst_g("<POINT_SHAPE_8>",  " 8 #open_triangle");
    textbuf.subst_g("<POINT_SHAPE_9>",  " 9 #filled_triangle");
    textbuf.subst_g("<POINT_SHAPE_10>", "10 #open_inverse-triangle");
    textbuf.subst_g("<POINT_SHAPE_11>", "11 #filled_inverse-triangle");
    textbuf.subst_g("<POINT_SHAPE_12>", "12 #open_diamond");
    textbuf.subst_g("<POINT_SHAPE_13>", "13 #filled_diamond");

    textbuf.subst_g("<LINE_SPEC_1>", "lw 1.0  pt point_shape_1   ps Small");
    textbuf.subst_g("<LINE_SPEC_2>", "lw 1.0  pt point_shape_2   ps Small");
    textbuf.subst_g("<LINE_SPEC_3>", "lw 1.0  pt point_shape_3   ps Small");
    textbuf.subst_g("<LINE_SPEC_4>", "lw 1.0  pt point_shape_4   ps Small");
    textbuf.subst_g("<LINE_SPEC_5>", "lw 1.0  pt point_shape_5   ps Small");
    textbuf.subst_g("<LINE_SPEC_6>", "lw 1.0  pt point_shape_6   ps Small");
    textbuf.subst_g("<LINE_SPEC_7>", "lw 1.0  pt point_shape_7   ps Small");
    textbuf.subst_g("<LINE_SPEC_8>", "lw 1.0  pt point_shape_8   ps Small");
    textbuf.subst_g("<LINE_SPEC_9>", "lw 1.0  pt point_shape_9   ps Small");
    textbuf.subst_g("<LINE_SPEC_10>","lw 1.0  pt point_shape_10  ps Small");
    textbuf.subst_g("<LINE_SPEC_11>","lw 1.0  pt point_shape_11  ps Small");
    textbuf.subst_g("<LINE_SPEC_12>","lw 1.0  pt point_shape_12  ps Small");
    textbuf.subst_g("<LINE_SPEC_13>","lw 1.0  pt point_shape_13  ps Small");

    if ( GnuplotVersion() >= 4.2 ) {
        for (ii = 0;  ii < n_CustomColors;   ii++) {
            //! build template (e.g. "<LINE_COLOR_1>")
            tmp_stream.str("");
            tmp_stream << "<LINE_COLOR_" << ii+1 << ">" ;
            tmp_string = tmp_stream.str();
            //! build string (e.g. "linecolor rgb \"black\"")
            tmp_stream.str("");
            tmp_stream << "linecolor rgb \"" << plotColors[ii] << "\"" ;
            //! Replace template with string
            textbuf.subst_g( tmp_string.c_str(), tmp_stream.str().c_str() );
        }
    } else {
        /*!
         * Change gnuplot's default line colors (1=red 2=green 3=blue
         * 4=magenta 5=cyan 6=sienna 7=orange 8=coral) for plot.
         * Note: This is only used when co-plotting multiple RUN_ dirs.
         */
        for (ii = 0;  ii < n_CustomColors;   ii++) {
            tmp_stream.str("");
            tmp_stream << "<LINE_COLOR_" << ii+1 << ">" ;
            //! Clear template; use new line#Color definitions from "-xrm" options
            textbuf.subst_g( tmp_stream.str().c_str(), "" );
        }
    }

    tmp_stream.str("");
    if ( GnuplotVersion() < 4.2  ||  page_fg_color.empty()  ||
         !page_fg_color.empty() ) {
        tmp_stream << "#" ;  /* comment out the textcolor command */
    }
    tmp_stream << "textcolor rgb \"" << page_fg_color << "\"" ;
    textbuf.subst_g("<PAGE_TEXT_COLOR_SPEC>", tmp_stream.str().c_str());

    textbuf.subst_g("<LABEL_1_TAG>", "1");
    textbuf.subst_g("<LABEL_1_NAME>", page_title.c_str());
    textbuf.subst_g("<LABEL_1_XPOS>", "0.51");
    textbuf.subst_g("<LABEL_1_YPOS>", "0.97");
    textbuf.subst_g("<LABEL_1_JUST>", "center");
    textbuf.subst_g("<LABEL_1_FONT>", "\"Helvetica,14\"");

    textbuf.subst_g("<LABEL_2_TAG>", "2");
    textbuf.subst_g("<LABEL_2_NAME>", "");
    textbuf.subst_g("<LABEL_2_XPOS>", "0.51");
    textbuf.subst_g("<LABEL_2_YPOS>", "0.95");
    textbuf.subst_g("<LABEL_2_JUST>", "center");
    textbuf.subst_g("<LABEL_2_FONT>", "\"Helvetica,10\"");

    textbuf.subst_g("<LABEL_3_TAG>", "3");
    textbuf.subst_g("<LABEL_3_NAME>", "`whoami`");
    textbuf.subst_g("<LABEL_3_XPOS>", "0.99");
    textbuf.subst_g("<LABEL_3_YPOS>", "0.99");
    textbuf.subst_g("<LABEL_3_JUST>", "right");
    textbuf.subst_g("<LABEL_3_FONT>", "\"Helvetica,8\"");

    textbuf.subst_g("<LABEL_4_TAG>", "4");
    textbuf.subst_g("<LABEL_4_NAME>", "`date +%m/%d/%Y`");
    textbuf.subst_g("<LABEL_4_XPOS>", "0.99");
    textbuf.subst_g("<LABEL_4_YPOS>", "0.957");
    textbuf.subst_g("<LABEL_4_JUST>", "right");
    textbuf.subst_g("<LABEL_4_FONT>", "\"Helvetica,8\"");

    textbuf.subst_g("<PLOT_TITLE_XPOS>", "0.0");
    textbuf.subst_g("<PLOT_TITLE_YPOS>", "0.2");
    textbuf.subst_g("<X_AXIS_LABEL_XPOS_DECL>", "0.0");
    textbuf.subst_g("<X_AXIS_LABEL_YPOS_DECL>", "0.6");
    if ( GnuplotVersion() < 4.2 ) {
        textbuf.subst_g("<Y_AXIS_LABEL_XPOS_DECL>", "0.6");
    } else {
        textbuf.subst_g("<Y_AXIS_LABEL_XPOS_DECL>", "1.4");
    }
    textbuf.subst_g("<Y_AXIS_LABEL_YPOS_DECL>", "0.0");

    textbuf.subst_g("<DEFAULT_FONT>",  "\"Helvetica,12\"");

    layout_page ( this );

    //! Figure out where we can create a temporary file.
    if (!access("/tmp", W_OK)) {
        strncpy(gp_template_file_name,
                "/tmp/dpx_gp_page_XXXXXX", sizeof(gp_template_file_name));

    } else if (!access("/var/tmp", W_OK)) {
        strncpy(gp_template_file_name,
                "/var/tmp/dpx_gp_page_XXXXXX", sizeof(gp_template_file_name));

    } else {
        post_dialog( toplevel, XmDIALOG_ERROR,
            "Unable to access /tmp or /var/tmp, where a temporary\n"
            "file (that represents gnuplot commands) needs\n"
            "to be created. Please check your permissions.\n");
        return;
    }

    //! Create a name for our temporary gnuplot command file.
    if (mkstemp( gp_template_file_name) < 0) {
        post_dialog( toplevel, XmDIALOG_ERROR,
            "Unable to generate a temporary file"
            "name for some mind boggling reason." );
        return;
    }


    if ( save_tmp_files ) {

        cout << "Keeping data associated with this gnuplot file : " << gp_template_file_name << endl;

        //! Comment out all commands that delete temp data files
        textbuf.subst_g("<SAVE_TMP_FILE_SPEC>", "#");

    } else {

        //! Allow all temp data files to be deleted
        textbuf.subst_g("<SAVE_TMP_FILE_SPEC>", "");

    }


    //! If user would like to see this template, print it to stdout
    //if (args.generate_template) {
    //    cout << textbuf.getText() << endl;
    //}

    /*!
     * SAVE buffer TO FILE with given filename.
     * Note: must save to file prior to sending to PRINTER device.
     */
    textbuf.writeFile( (const char*)gp_template_file_name );


    cmd << "gnuplot";
    if ( ! page_fg_color.empty()  &&  color_is_valid(&page_fg_color) ) {
        cmd << " -xrm 'gnuplot*textColor:" << page_fg_color << "'" ;
        cmd << " -xrm 'gnuplot*borderColor:" << page_fg_color << "'" ;
        cmd << " -xrm 'gnuplot*axisColor:" << page_fg_color << "'" ;
    }
    if ( ! page_bg_color.empty()  &&  color_is_valid(&page_bg_color) ) {
        cmd << " -xrm 'gnuplot*background:" << page_bg_color << "'" ;
    }
    /*!
     * Set X11 line colors.
     * Line colors are global per page in gnuplot.
     * And there are at max 8 default colors. (%man gnuplot)
     */
    for (ii = 0;  ii < n_CustomColors;   ii++) {
        cmd << " -xrm 'gnuplot*line" << ii+1 << "Color:" << plotColors[ii] << "'" ;
    }

    if ( device > GPViewPageNode::NOT_SET ) {
            cerr    << "ERROR: GPViewPageNode::finalize() called with invalid device.\n"
                    << "Example devices are TERMINAL, DISK and PRINTER.\n"
                    << "It is an enumerated type in the GPViewPageNode class.\n" ;
            exit(-1);
    }

    switch ( device ) {

        case GPViewPageNode::DISK:

            if ( diskFileName.empty() ) {
                cerr << "ERROR: GPViewPageNode::finalize() called without "
                     << "setting output file.  When you are sending data "
                     << "to disk, you must set output file name."
                     << endl ;
                exit(-1);
            }

            //! Remove any quotes from string
            while ( 1 ) {
                idx = diskFileName.find('"');
                if ( idx != string::npos ) {
                    diskFileName.erase(idx,1);
                } else {
                    break ;
                }
            }

            /*!
             * The weird rfind(), substr() and erase() are used
             * to make sure that if the outfile name already
             * has an extension that we don't duplicate it
             */
            idx = diskFileName.rfind('.');
            if ( idx != string::npos ) {
                if (diskFileName.substr(idx) == extension) {
                    diskFileName.erase(idx);
                }
            }

            tmp_stream.str("");
            tmp_stream << instance_count ;
            diskFileName.append( tmp_stream.str() );
            diskFileName.append( extension );

            //! Complete command by generating an output file from the gnuplot file.
            cmd << " " << gp_template_file_name << " >& " << diskFileName;
            cout << "Generating " << diskFileName << "..." << endl;
            cout.flush();
            if ( system(cmd.str().c_str()) > -1 ) {
                cout << "Done." << endl;
            }

            //! Run postscript file through a filter
            if ( terminalType == PS ) {
                filterPostScriptBW( diskFileName.c_str() );
            } else if ( terminalType == PS_COLOR || terminalType == EPS) {
                filterPostScriptColor( diskFileName.c_str(), this );
            }

            break;

        case GPViewPageNode::PRINTER:

            //! Figure out where we can create a temporary file.
            if (!access("/tmp", W_OK)) {
                strncpy(outFileName,
                        "/tmp/dpx_gxplot_XXXXXX", sizeof(outFileName));

            } else if (!access("/var/tmp", W_OK)) {
                strncpy(outFileName,
                        "/var/tmp/dpx_gxplot_XXXXXX", sizeof(outFileName));

            } else {
                post_dialog( toplevel, XmDIALOG_ERROR,
                    "Unable to access /tmp or /var/tmp, where a temporary\n"
                    "file for printing needs to be created.\n"
                    "Please check your permissions.\n");
                return;
            }

            //! Create a name for our temporary gnuplot command file.
            if (mkstemp(outFileName) < 0) {
                post_dialog( toplevel, XmDIALOG_ERROR,
                    "Unable to generate a temporary file"
                    "name for some mind boggling reason." );
                return;
            }

            //! Complete command by generating an output file from the gnuplot file.
            cmd << " " << gp_template_file_name << " >& " << outFileName;
            cout << "Generating output file : " << outFileName << "..." << endl;
            if ( system(cmd.str().c_str()) > -1 ) {
                cout << "Done." << endl;
            }

            //! Run postscript file through a filter
            filterPostScriptBW(outFileName);

            //! Print the file
            if ( printPS((const char*)outFileName) > -1 ) {
                cout << "Complete." << endl;
                cout.flush();
            }

            if ( !save_tmp_files ) {
                //! Clean up output file.
                tmp_stream.str("");
                tmp_stream << "rm -f " << outFileName ;
                tmp_stream << "; rm -f " << gp_template_file_name;
                system( tmp_stream.str().c_str() );
            }

            break;

        case GPViewPageNode::NOT_SET:
            break;

        case GPViewPageNode::TERMINAL:
        default:

            cmd << " -persist";
            cmd << " -geometry " << xx_geom << "x" << yy_geom ; //e.g. 850x657

            //! Complete the command by providing the gnuplot file name.
            cmd << " " << gp_template_file_name ;

            if ( !save_tmp_files ) {
                /*!
                * After the plot is drawn, add another command to delete
                * the temporary gnuplot file: '/tmp/dpx_gp_page_******'.
                */
                cmd << "; rm -f " << gp_template_file_name;
            }

            /*!
             * Run the system command to create the plot.
             * Example:
             *    % "gnuplot -persist -geometry 850x657 \
             *       -xrm 'gnuplot*textColor:black' /tmp/dpx_gp_page_******"
             */
            system( cmd.str().c_str() );

            break;

    }

}