Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedding an R htmlwidget into existing webpage

Tags:

r

htmlwidgets

I am trying to embed an R htmlwidget into an existing webpage -- a webpage that already has bootstrap and styling applied. For example, consider the following webpage (note where the widget should be placed):

<!DOCTYPE html> <html lang="en"> <head>   <meta charset="UTF-8">   <title>Document</title> </head> <body>   <p>This is a test.</p>   <!-- htmlwidget should go here. -->   <p>A closing paragraph.</p> </body> </html> 

I can create and save a datatable widget like so:

library(htmlwidgets) library(datatable)  d1 <- datatable(mtcars, filter = "top") saveWidget(d1, file = "widget_file.html") 

The generated widget_file.html (even for this modest widget) contains a lot of code. Is there an easy way to embed this into an existing webpage/template?

I have been successful using <iframe src="widget_file.html"> but I'm wondering if there is a better way? Moreover, is there a way to separate pieces/dependencies (e.g. json data) from the widget_file.html so they can be placed in other folders?


Note: I created the htmlwidget tag, but I believe there should be a synonymous htmlwidgets tag.

like image 515
JasonAizkalns Avatar asked Dec 23 '15 16:12

JasonAizkalns


1 Answers

The htmlwidget-Package offers a way to save the pieces for the widget separately as follows:

library(dygraphs) d1 <- dygraph(nhtemp, main = "New Haven Temperatures") %>%    dyRangeSelector(dateWindow = c("1920-01-01", "1960-01-01"))  saveWidget(d1, file = "widget_file.html", selfcontained = FALSE) 

Which results in the following files/dirs:

widget_file.html widget_file_files   /dygraphs-1.1.1     ..   /dygraphs-binding-0.6     ..   /htmlwidgets-0.5     ..   /jquery-1.11.1     ..   /moment-2.8.4       ..   /moment-timezone-0.2.5     .. 

And widget_file.html reads as follows:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <script src="widget_file_files/htmlwidgets-0.5/htmlwidgets.js"></script> ... <script src="widget_file_files/dygraphs-binding-0.6/dygraphs.js"></script>  </head> <body style="background-color:white;"> <div id="htmlwidget_container">   <div id="htmlwidget-2956" style="width:960px;height:500px;" class="dygraphs"></div> </div>  <!-- THE JSON DATA --> <script type="application/json" data-for="htmlwidget-2956"> {THE JSON DATA YOU WERE LOOKING FOR} </script> <!-- THE JSON DATA -->  <script type="application/htmlwidget-sizing" data-for="htmlwidget-2956">{Widget-Styling-Json} </script> </body> </html> 

So you can edit your html as follows:

<!DOCTYPE html> <html lang="en"> <head>   <meta charset="UTF-8">   <title>Document</title>   <!-- Begin of scripts to run the widget -->   <script src="widget_file_files/htmlwidgets-0.5/htmlwidgets.js"></script>   <script src="widget_file_files/jquery-1.11.1/jquery.min.js"></script>   <link href="widget_file_files/dygraphs-1.1.1/dygraph.css" rel="stylesheet" />   <script src="widget_file_files/dygraphs-1.1.1/dygraph-combined.js"></script>   <script src="widget_file_files/moment-2.8.4/moment.js"></script>   <script src="widget_file_files/moment-timezone-0.2.5/moment-timezone-with-data.js"></script>   <script src="widget_file_files/dygraphs-binding-0.6/dygraphs.js"></script>   <!-- End of scripts to run the widget -->    <!-- Begin Widget styling -->     <script type="application/htmlwidget-sizing" data-for="htmlwidget-2956">{"viewer":{"width":450,"height":350,"padding":10,"fill":true},"browser":{"width":960,"height":500,"padding":40,"fill":true}}</script>   <!-- End widget Styling -->    <!-- Begin Data for the widget-->   <script type="application/json" data-for="htmlwidget-2956">{"x":{"attrs":{"title":"New Haven Temperatures","labels":["year","V1"],"legend":"auto","retainDateWindow":false,"axes":{"x":{"pixelsPerLabel":60}},"showRangeSelector":true,"dateWindow":["1920-01-01T00:00:00Z","1960-01-01T00:00:00Z"],"rangeSelectorHeight":40,"rangeSelectorPlotFillColor":" #A7B1C4","rangeSelectorPlotStrokeColor":"#808FAB","interactionModel":"Dygraph.Interaction.defaultModel"},"scale":"yearly","annotations":[],"shadings":[],"events":[],"format":"date","data":[["1912-01-01T00:00:00Z","1913-01-01T00:00:00Z","1914-01-01T00:00:00Z","1915-01-01T00:00:00Z","1916-01-01T00:00:00Z","1917-01-01T00:00:00Z","1918-01-01T00:00:00Z","1919-01-01T00:00:00Z","1920-01-01T00:00:00Z","1921-01-01T00:00:00Z","1922-01-01T00:00:00Z","1923-01-01T00:00:00Z","1924-01-01T00:00:00Z","1925-01-01T00:00:00Z","1926-01-01T00:00:00Z","1927-01-01T00:00:00Z","1928-01-01T00:00:00Z","1929-01-01T00:00:00Z","1930-01-01T00:00:00Z","1931-01-01T00:00:00Z","1932-01-01T00:00:00Z","1933-01-01T00:00:00Z","1934-01-01T00:00:00Z","1935-01-01T00:00:00Z","1936-01-01T00:00:00Z","1937-01-01T00:00:00Z","1938-01-01T00:00:00Z","1939-01-01T00:00:00Z","1940-01-01T00:00:00Z","1941-01-01T00:00:00Z","1942-01-01T00:00:00Z","1943-01-01T00:00:00Z","1944-01-01T00:00:00Z","1945-01-01T00:00:00Z","1946-01-01T00:00:00Z","1947-01-01T00:00:00Z","1948-01-01T00:00:00Z","1949-01-01T00:00:00Z","1950-01-01T00:00:00Z","1951-01-01T00:00:00Z","1952-01-01T00:00:00Z","1953-01-01T00:00:00Z","1954-01-01T00:00:00Z","1955-01-01T00:00:00Z","1956-01-01T00:00:00Z","1957-01-01T00:00:00Z","1958-01-01T00:00:00Z","1959-01-01T00:00:00Z","1960-01-01T00:00:00Z","1961-01-01T00:00:00Z","1962-01-01T00:00:00Z","1963-01-01T00:00:00Z","1964-01-01T00:00:00Z","1965-01-01T00:00:00Z","1966-01-01T00:00:00Z","1967-01-01T00:00:00Z","1968-01-01T00:00:00Z","1969-01-01T00:00:00Z","1970-01-01T00:00:00Z","1971-01-01T00:00:00Z"],[49.9,52.3,49.4,51.1,49.4,47.9,49.8,50.9,49.3,51.9,50.8,49.6,49.3,50.6,48.4,50.7,50.9,50.6,51.5,52.8,51.8,51.1,49.8,50.2,50.4,51.6,51.8,50.9,48.8,51.7,51,50.6,51.7,51.5,52.1,51.3,51,54,51.4,52.7,53.1,54.6,52,52,50.9,52.6,50.2,52.6,51.6,51.9,50.5,50.9,51.7,51.4,51.7,50.8,51.9,51.8,51.9,53]]},"evals":["attrs.interactionModel"]}</script>   <!-- End Data for the widget--> </head> <body>   <p>This is a test.</p>   <div id="htmlwidget_container">     <div id="htmlwidget-2956" style="width:960px;height:500px;" class="dygraphs"></div>   </div>   <p>A closing paragraph.</p> </body> </html> 

This will leave you with the json-data hardcoded within the html-document (see my ). If you want to load the data dynamically you can use e.g.

json_dat <- readLines("widget_file.html")[18] cat(sub("</script>","",sub('<script type=\"application/json\" data-for=.*\">', "", json_dat)), file = "./widget_file_files/my_data.json") 

To save the json-data as ./widget_file_files/my_data.json and then load it within the html. If you are using PHP you can do:

<script type="application/json" data-for="htmlwidget-2956">     <?php include('widget_file_files/my_data.json'); ?> </script> 

If you want to use a pure JS solution maybe have a look at http://api.jquery.com/jquery.getjson/ and the widget_file_files/htmlwidgets-0.5/htmlwidgets.js-File how the json-data is bound at the moment...

P.S.: As this question got a lot of attention already you could also contact the package developer and ask him to further "un-selfcontain" the "selfcontained" option in htmlwidgets:::saveWidget: Meaning to save the json-data separately and include it e.g. via jquery.getjson

like image 85
Rentrop Avatar answered Nov 09 '22 10:11

Rentrop