# -*- org-export-babel-evaluate: nil; org-export-allow-bind-keywords: t; -*-
#+AUTHOR: Malcolm Cook;
#+EMAIL: malcolm_cook@stowers.org

#+OPTIONS:   ':nil H:3 toc:3 num:t \n:nil @:t ::t |:t ^:nil -:nil f:t *:t <:t _:nil
#+OPTIONS:   email:T author:T creator:T timestamp:T   
#+STARTUP: showall

#+STARTUP: showall
#+PROPERTY: header-args:R :session *R:htmlwidgets** 
#+PROPERTY: header-args:R+ :results replace drawer
#+PROPERTY: header-args+ :exports both  
#+SETUPFILE: https://raw.githubusercontent.com/fniessen/org-html-themes/master/org/theme-readtheorg.setup

* Overview
This emacs org-mode document demonstrates an approach to embedding
htmlwidgets in the exported html resulting from org-html-export-html.
The approach:

 - uses (coopts?) org's
   [[https://orgmode.org/manual/Environment-of-a-Code-Block.html][:prologue/:epilogue]]
   header args.
 - allows for an htmlwidget to be developed interactively "normally"
   within a code blocks, isolating the machinery for their inclusion
   in an exported html document to the time of html-export.
 - suffers from the possibility that the javascript in two widget may
   conflict. For example uncommenting the results of the
   plotly::ggplotly demonstration below and re-exporting to html will
   cause the DT::datatable to break (unless the DT:datatable is
   included after the ggploty). They may both define a handler for the
   document's onLoad event, only one of which will run, thereby
   disaling the other.  TODO: understand fully and address.

* Method
#+caption: Define a single function providing orgmode integration
#+begin_src R :results none...

* Demonstrations

Following are examples that use various kinds of htmlwidget.

#+caption: Include librarys required for demonstrations
#+begin_src R :results none
library(DT)
library(RColorBrewer)
library(fission)
library(ggplot2)
library(gplots)
library(metricsgraphics)
library(networkD3)
library(plotly)
#+end_src

** Network layout using forceNetwork
#+begin_src R :results html output :prologue "orgWidget(iframe(src=.,width=1000,height=300),'forceNetwork.html',{" :epilogue "})"
data(MisLinks, MisNodes)
forceNetwork(Links = MisLinks, Nodes = MisNodes, 
  Source =  "source", Target = "target", Value = "value", 
  NodeID = "name", Group = "group", opacity = 0.4)
#+END_SRC

#+RESULTS:
#+begin_export html
<iframe src="forceNetwork.html" width="1000" height="300"></iframe>
#+end_export

** Word Clouds using rWordCloud
#+begin_src R :results html output :prologue "orgWidget(iframe(src=.,width='1000px',height='700px'),'rWordCloud.html',{" :epilogue "})"
library(rWordCloud)
text <- c('d3','wordcloud','impressive','experiment','htmlwidgets','myfirstwidget')
size <- c(25,20,13,9,6,5)
df <- data.frame(text,size)
d3Cloud(text = text, size = size)
#+END_SRC

#+RESULTS:
#+begin_export html
<iframe src="rWordCloud.html" width="1000px" height="700px"></iframe>
#+end_export

** ScatterPlots using metricsgraphics
*** An MA plot with 7039 genes
#+begin_src R :results value raw :prologue "orgWidget(include,'metricsgraphics_MAplot_widget.html',{" :epilogue "})"
## load a example expression data as a SummarizedExperiment, and
## format two experiments as data.frame
data("fission")
cnt<-assay(fission)
names(dimnames(cnt))<-c('gene','sample')
dat<-as.data.frame(cnt[,1:2]) ##"GSM1368273" "GSM1368274"
dat$gene<-rownames(dat) ## needed as column to pass to javascript widget

# compute M, A, and encode DE as down, up, no change.
dat$M<-log2(sqrt(dat[,1] * dat[,2]))
dat$A<-log2(sqrt(dat[,1] / dat[,2]))
dat$DE <- c('DN','NC','UP')[(sign(dat$A) * as.integer(abs(dat$A)>1)) +  2]

# create the widget
dat %>%
mjs_plot(x=M
        ,y=A
        ,width=600, height=500
         ) %>%
mjs_point(color_accessor=DE
         ,color_type='category'
         ,color_range=c('green','blue','red')
          ,least_squares=TRUE
          ) %>%
mjs_labs(x="MM", y="AA") %>%
mjs_add_mouseover("function(d, i) {
                $('{{ID}} svg .mg-active-datapoint')
                     .text([d.point.gene, d.point.DE, 'M:', d.point.M.toFixed(2), 'A:', d.point.A.toFixed(2)].join(' '));
               }")
#+END_SRC

#+RESULTS:
#+include: "metricsgraphics_MAplot_widget.html" export html

*** The cars example from http://rpubs.com/hrbrmstr/53741
#+begin_src R :results value raw :prologue "orgWidget(include,'metricsgraphics_cars.html',{" :epilogue "})"
mtcars %>%
  mjs_plot(x=wt, y=mpg, width=600, height=500) %>%
  mjs_point(color_accessor=carb, size_accessor=carb) %>%
  mjs_labs(x="Weight of Car", y="Miles per Gallon")
#+END_SRC

#+RESULTS:
#+include: "metricsgraphics_cars.html" export html

** DataTables using DT
#+caption: orgWidget with :results value raw
#+begin_src R :results value raw replace :prologue "orgWidget(file,'iris.html',datatable(" :epilogue "))"
iris
#+end_src

#+RESULTS:
iris.html

#+caption: orgWidget with :results value file - makes the filename be a link
#+begin_src R :results value file :prologue "orgWidget(file,'iris.html',datatable(" :epilogue "))"
iris
#+end_src

#+RESULTS:
file:iris.html

In either case, you can cause `org-html-export-to-html` to *inline*
the exported html file with `#+include iris.html export html`,
resulting in:
#+include: iris.html export html

#+caption: `orgWidget(include,...)` is a shorthand for just this (requires `:results value raw`.)
#+begin_src R :results value raw :prologue "orgWidget(include,'iris.html',datatable(" :epilogue "))"
iris
#+end_src

#+RESULTS:
#+include: "iris.html" export html

#+caption: `orgWidget(iframe,...)` inlines <file> wrapped in an iframe (with default sizing)
#+begin_src R :results output html :prologue "orgWidget(iframe,'iris.html',datatable(" :epilogue "))"
iris
#+end_src

#+RESULTS:
#+begin_export html
<iframe src="iris.html"></iframe>
#+end_export

#+caption: `orgWidget(iframe(src=.,...),...)` inlines <file> wrapped in an iframe with <attributes> (such as width & height)
#+begin_src R :results output html :prologue "orgWidget(iframe(src=.,title='iframe example',width='1300',height='400'),'iris.html',datatable(" :epilogue "))"
iris
#+end_src

#+RESULTS:
#+begin_export html
<iframe src="iris.html" title="iframe example" width="1300" height="400"></iframe>
#+end_export

** ggplot using plotly
#+begin_src R :results value raw :prologue "orgWidget(include,'ggplotly_widget.html',ggplotly({" :epilogue "}))"
ggplot(data = diamonds, aes(x = cut, fill = clarity)) +
            geom_bar(position = "dodge")
#+end_src

#+RESULTS:
# #+include: "ggplotly_widget.html" export html

These results are intentionally commented out since thier export
conflict with those of previous DT::datatable.

* Source Code
#+HTML: <iframe height=800px width=1100px src=./htmlwidgets.org.html scrolling=yes></iframe>