RInside Version 0.2.10
inst/examples/wt/wtdensity.cpp
Go to the documentation of this file.
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4;  tab-width: 8; -*-
00002 //
00003 // Wt usage example for RInside, inspired by the standard 'density sliders' example
00004 //
00005 // Copyright (C) 2011  Dirk Eddelbuettel and Romain Francois
00006 //
00007 // This file is licensed under GPL 2 or later, as are the rest of RInside and Rcpp
00008 //
00009 // Derived from hello.C in the Wt sources
00010 // Copyright (C) 2008 Emweb bvba, Heverlee, Belgium.
00011 
00012 #include <cstdio>
00013 
00014 #include <Wt/WApplication>
00015 #include <Wt/WBreak>
00016 #include <Wt/WContainerWidget>
00017 #include <Wt/WLineEdit>
00018 #include <Wt/WPushButton>
00019 #include <Wt/WText>
00020 #include <Wt/WImage>
00021 #include <Wt/WSpinBox>
00022 #include <Wt/WGroupBox>
00023 #include <Wt/WButtonGroup>
00024 #include <Wt/WRadioButton>
00025 #include <Wt/WHBoxLayout>
00026 #include <Wt/WEnvironment>
00027 #include <Wt/WFileResource>
00028 
00029 #include <RInside.h>
00030 
00031 using namespace Wt;
00032 
00033 class DensityApp : public WApplication {
00034 public:
00035     DensityApp(const WEnvironment& env, RInside & R);
00036 
00037 private:
00038     WLineEdit *codeEdit_;       // to edit the RNG draw expression
00039     WButtonGroup *group_;       // holds the radiobuttons
00040     WSpinBox *spin_;            // selects the density bandwidth
00041     WImage *img_;               // displays the image
00042     WFileResource *imgfile_;    // controls the file resources
00043     WText *greeting_;           // text label for status message
00044 
00045     void reportButton();        // called when new button selected
00046     void reportEdit();          // called when RNG expression edited
00047     void reportSpinner();       // called when bandwidth changed
00048     void plot();                // to call R for new plot
00049     
00050     enum Kernel { Gaussian     = 0, Epanechnikov = 1, Rectangular  = 2,
00051                   Triangular   = 3, Cosine       = 4 };
00052   
00053     RInside & R_;               // reference to embedded R instance
00054     std::string tempfile_;      // name of file used by R for plots
00055     int bw_, kernel_;           // parameters used to estimate the density
00056     std::string cmd_;           // random draw command string
00057     Rcpp::NumericVector Yvec_;  // the random draw
00058 };
00059 
00060 // The env argument contains information about the new session, and the initial request. 
00061 // It must be passed to the WApplication // constructor so it is typically also an argument
00062 // for your custom application constructor.
00063 DensityApp::DensityApp(const WEnvironment& env, RInside & R) : WApplication(env), R_(R) {
00064 
00065     setTitle("Witty WebApp With RInside");                      // application title
00066 
00067     setCssTheme("polished");
00068     messageResourceBundle().use(appRoot() + "wtdensity");
00069 
00070     new WText(WString::tr("overview"), root());
00071 
00072     std::string tfcmd = "tfile <- tempfile(pattern=\"img\", tmpdir=\"/tmp\", fileext=\".png\")";        
00073     tempfile_ = Rcpp::as<std::string>(R_.parseEval(tfcmd));     // assign to 'tfile' in R, and report back
00074     bw_ = 100; 
00075     kernel_ = 0;                                                // parameters used to estimate the density
00076     cmd_ = "c(rnorm(100,0,1), rnorm(50,5,1))";                  // random draw command string
00077    
00078     new WText(WString::tr("user input"), root());
00079     Wt::WContainerWidget *wc = new Wt::WContainerWidget(root());
00080     wc->setStyleClass("box");
00081 
00082     Wt::WHBoxLayout *layout = new Wt::WHBoxLayout();
00083     Wt::WContainerWidget *midbox = new Wt::WContainerWidget(root());
00084     layout->addWidget(midbox);
00085     Wt::WContainerWidget *container = new Wt::WContainerWidget(root());
00086     layout->addWidget(container);
00087 
00088     wc->setLayout(layout, AlignTop | AlignJustify);
00089 
00090     midbox->addWidget(new WText("Density estimation scale factor (div. by 100)"));
00091     midbox->addWidget(new WBreak());                            // insert a line break
00092     spin_ = new WSpinBox(midbox);
00093     spin_->setRange(5, 200);
00094     spin_->setValue(bw_);
00095     spin_->valueChanged().connect(this, &DensityApp::reportSpinner);
00096 
00097     midbox->addWidget(new WBreak());                            // insert a line break
00098     midbox->addWidget(new WText("R Command for data generation"));  // show some text
00099     midbox->addWidget(new WBreak());                            // insert a line break
00100     codeEdit_ = new WLineEdit(midbox);                          // allow text input
00101     codeEdit_->setTextSize(30);
00102     codeEdit_->setText(cmd_); 
00103     codeEdit_->setFocus();                                      // give focus
00104     codeEdit_->enterPressed().connect(this, &DensityApp::reportEdit);
00105 
00106     group_ = new Wt::WButtonGroup(container);                   // use button group to arrange radio buttons
00107 
00108     Wt::WRadioButton *button;
00109     button = new Wt::WRadioButton("Gaussian", container);
00110     new Wt::WBreak(container);
00111     group_->addButton(button, Gaussian);
00112 
00113     button = new Wt::WRadioButton("Epanechnikov", container);
00114     new Wt::WBreak(container);
00115     group_->addButton(button, Epanechnikov);
00116 
00117     button = new Wt::WRadioButton("Rectangular", container);
00118     new Wt::WBreak(container);
00119     group_->addButton(button, Rectangular);
00120 
00121     button = new Wt::WRadioButton("Triangular", container);
00122     new Wt::WBreak(container);
00123     group_->addButton(button, Triangular);
00124 
00125     button = new Wt::WRadioButton("Cosine", container);
00126     new Wt::WBreak(container);
00127     group_->addButton(button, Cosine);
00128 
00129     group_->setCheckedButton(group_->button(kernel_));
00130     group_->checkedChanged().connect(this, &DensityApp::reportButton);
00131 
00132     new WText(WString::tr("r result"), root());
00133     Wt::WContainerWidget *botbox = new Wt::WContainerWidget(root());
00134     botbox->setStyleClass("box");
00135     imgfile_ = new Wt::WFileResource("image/png", tempfile_);
00136     imgfile_->suggestFileName("density.png");  // name the clients sees of datafile
00137     img_ = new Wt::WImage(imgfile_, "PNG version", botbox);
00138 
00139     new WText(WString::tr("browser info"), root());
00140     Wt::WContainerWidget *stbox = new Wt::WContainerWidget(root());
00141     stbox->setStyleClass("box");
00142     greeting_ = new WText(stbox);                               // empty text
00143     greeting_->setText("Setting up...");
00144 
00145     useStyleSheet("wtdensity.css");                             // set our style sheet last
00146   
00147     reportEdit();                                               // create a new RNG draw in Yvec_
00148     plot();                                                     // and draw a new density plot
00149 }
00150 
00151 void DensityApp::reportButton() {
00152     kernel_ = group_->checkedId();                              // get id of selected kernel 
00153     plot();
00154 }
00155 
00156 void DensityApp::reportEdit() {
00157     cmd_ = codeEdit_->text().toUTF8();  // get text written in box, as UTF-8, assigned to string
00158     std::string rng = "y2 <- " + cmd_ + "; y <- y2";
00159     R_.parseEvalQNT(rng);                       // evaluates expression, assigns to 'y'
00160     Yvec_ = R_["y"];                    // cache the y vector
00161     plot();
00162 }
00163 
00164 void DensityApp::reportSpinner() {
00165     bw_ = spin_->value();               // get the value of the spin selector
00166     plot();
00167 }
00168 
00169 void DensityApp::plot() {
00170     const char *kernelstr[] = { "gaussian", "epanechnikov", "rectangular", "triangular", "cosine" };
00171     greeting_->setText("Starting R call");
00172     R_["tfile"]  = tempfile_;
00173     R_["bw"]     = bw_;
00174     R_["kernel"] = kernelstr[kernel_];                  // passes the string to R
00175     R_["y"]      = Yvec_;
00176     std::string cmd0 = "png(filename=tfile,width=600,height=400); plot(density(y, bw=bw/100, kernel=kernel), xlim=range(y)+c(-2,2), main=\"Kernel: ";
00177     std::string cmd1 = "\"); points(y, rep(0, length(y)), pch=16, col=rgb(0,0,0,1/4));  dev.off()";
00178     std::string cmd = cmd0 + kernelstr[kernel_] + cmd1; // stick the selected kernel in the middle
00179     R_.parseEvalQ(cmd);                                 // evaluate command -- generates new density plot
00180     imgfile_->setChanged();                             // important: tells consumer that image has changed, forces refresh
00181     greeting_->setText("Finished request from " + this->environment().clientAddress() + " using " + this->environment().userAgent()) ;
00182 }
00183 
00184 WApplication *createApplication(const WEnvironment& env) {
00185     // You could read information from the environment to decide whether
00186     // the user has permission to start a new application
00187     //
00188     // We grab an instance of the embedded R. Note we can start only one,
00189     // so resource conflicts have to be managed (eg add mutexes etc)
00190     //
00191     return new DensityApp(env, RInside::instance());
00192 }
00193 
00194 int main(int argc, char **argv) {
00195 
00196     RInside R(argc, argv);              // create the one embedded R instance 
00197 
00198     // Your main method may set up some shared resources, but should then
00199     // start the server application (FastCGI or httpd) that starts listening
00200     // for requests, and handles all of the application life cycles.
00201     //
00202     // The last argument to WRun specifies the function that will instantiate
00203     // new application objects. That function is executed when a new user surfs
00204     // to the Wt application, and after the library has negotiated browser
00205     // support. The function should return a newly instantiated application
00206     // object.
00207     return WRun(argc, argv, createApplication);
00208 }
 All Classes Files Functions Variables Enumerations Enumerator Defines