diff --git a/docs/404.html b/docs/404.html new file mode 100644 index 0000000..49a3e67 --- /dev/null +++ b/docs/404.html @@ -0,0 +1,103 @@ + + + + + + + +Page not found (404) • listviewer + + + + + + + + + + + +
+
+ + + + +
+
+ + +Content not found. Please use links in the navbar. + +
+ + + +
+ + + + +
+ + + + + + + + diff --git a/docs/CONDUCT.html b/docs/CONDUCT.html index 7160ecd..afd1fd6 100644 --- a/docs/CONDUCT.html +++ b/docs/CONDUCT.html @@ -1,55 +1,12 @@ - - - - - - - -Contributor Code of Conduct • listviewer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Contributor Code of Conduct • listviewer + + - - - -
-
- -
-
+
+ +
-
- + +
+ + + - - + diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index 26c376d..9c03795 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -1,55 +1,12 @@ - - - - - - - -License • listviewer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -License • listviewer + + - - - -
-
- -
-
+
+ +
-
- + +
+ + + - - + diff --git a/docs/authors.html b/docs/authors.html index a1f7490..ffea285 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -1,55 +1,12 @@ - - - - - - - -Authors • listviewer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Authors and Citation • listviewer + + - - - - -
-
-
-
+
-
-
- + +
+ + + - - + diff --git a/docs/bootstrap-toc.css b/docs/bootstrap-toc.css new file mode 100644 index 0000000..5a85941 --- /dev/null +++ b/docs/bootstrap-toc.css @@ -0,0 +1,60 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ + +/* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ + +/* All levels of nav */ +nav[data-toggle='toc'] .nav > li > a { + display: block; + padding: 4px 20px; + font-size: 13px; + font-weight: 500; + color: #767676; +} +nav[data-toggle='toc'] .nav > li > a:hover, +nav[data-toggle='toc'] .nav > li > a:focus { + padding-left: 19px; + color: #563d7c; + text-decoration: none; + background-color: transparent; + border-left: 1px solid #563d7c; +} +nav[data-toggle='toc'] .nav > .active > a, +nav[data-toggle='toc'] .nav > .active:hover > a, +nav[data-toggle='toc'] .nav > .active:focus > a { + padding-left: 18px; + font-weight: bold; + color: #563d7c; + background-color: transparent; + border-left: 2px solid #563d7c; +} + +/* Nav: second level (shown on .active) */ +nav[data-toggle='toc'] .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; +} +nav[data-toggle='toc'] .nav .nav > li > a { + padding-top: 1px; + padding-bottom: 1px; + padding-left: 30px; + font-size: 12px; + font-weight: normal; +} +nav[data-toggle='toc'] .nav .nav > li > a:hover, +nav[data-toggle='toc'] .nav .nav > li > a:focus { + padding-left: 29px; +} +nav[data-toggle='toc'] .nav .nav > .active > a, +nav[data-toggle='toc'] .nav .nav > .active:hover > a, +nav[data-toggle='toc'] .nav .nav > .active:focus > a { + padding-left: 28px; + font-weight: 500; +} + +/* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ +nav[data-toggle='toc'] .nav > .active > ul { + display: block; +} diff --git a/docs/bootstrap-toc.js b/docs/bootstrap-toc.js new file mode 100644 index 0000000..1cdd573 --- /dev/null +++ b/docs/bootstrap-toc.js @@ -0,0 +1,159 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ +(function() { + 'use strict'; + + window.Toc = { + helpers: { + // return all matching elements in the set, or their descendants + findOrFilter: function($el, selector) { + // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ + // http://stackoverflow.com/a/12731439/358804 + var $descendants = $el.find(selector); + return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); + }, + + generateUniqueIdBase: function(el) { + var text = $(el).text(); + var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); + return anchor || el.tagName.toLowerCase(); + }, + + generateUniqueId: function(el) { + var anchorBase = this.generateUniqueIdBase(el); + for (var i = 0; ; i++) { + var anchor = anchorBase; + if (i > 0) { + // add suffix + anchor += '-' + i; + } + // check if ID already exists + if (!document.getElementById(anchor)) { + return anchor; + } + } + }, + + generateAnchor: function(el) { + if (el.id) { + return el.id; + } else { + var anchor = this.generateUniqueId(el); + el.id = anchor; + return anchor; + } + }, + + createNavList: function() { + return $(''); + }, + + createChildNavList: function($parent) { + var $childList = this.createNavList(); + $parent.append($childList); + return $childList; + }, + + generateNavEl: function(anchor, text) { + var $a = $(''); + $a.attr('href', '#' + anchor); + $a.text(text); + var $li = $('
  • '); + $li.append($a); + return $li; + }, + + generateNavItem: function(headingEl) { + var anchor = this.generateAnchor(headingEl); + var $heading = $(headingEl); + var text = $heading.data('toc-text') || $heading.text(); + return this.generateNavEl(anchor, text); + }, + + // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). + getTopLevel: function($scope) { + for (var i = 1; i <= 6; i++) { + var $headings = this.findOrFilter($scope, 'h' + i); + if ($headings.length > 1) { + return i; + } + } + + return 1; + }, + + // returns the elements for the top level, and the next below it + getHeadings: function($scope, topLevel) { + var topSelector = 'h' + topLevel; + + var secondaryLevel = topLevel + 1; + var secondarySelector = 'h' + secondaryLevel; + + return this.findOrFilter($scope, topSelector + ',' + secondarySelector); + }, + + getNavLevel: function(el) { + return parseInt(el.tagName.charAt(1), 10); + }, + + populateNav: function($topContext, topLevel, $headings) { + var $context = $topContext; + var $prevNav; + + var helpers = this; + $headings.each(function(i, el) { + var $newNav = helpers.generateNavItem(el); + var navLevel = helpers.getNavLevel(el); + + // determine the proper $context + if (navLevel === topLevel) { + // use top level + $context = $topContext; + } else if ($prevNav && $context === $topContext) { + // create a new level of the tree and switch to it + $context = helpers.createChildNavList($prevNav); + } // else use the current $context + + $context.append($newNav); + + $prevNav = $newNav; + }); + }, + + parseOps: function(arg) { + var opts; + if (arg.jquery) { + opts = { + $nav: arg + }; + } else { + opts = arg; + } + opts.$scope = opts.$scope || $(document.body); + return opts; + } + }, + + // accepts a jQuery object, or an options object + init: function(opts) { + opts = this.helpers.parseOps(opts); + + // ensure that the data attribute is in place for styling + opts.$nav.attr('data-toggle', 'toc'); + + var $topContext = this.helpers.createChildNavList(opts.$nav); + var topLevel = this.helpers.getTopLevel(opts.$scope); + var $headings = this.helpers.getHeadings(opts.$scope, topLevel); + this.helpers.populateNav($topContext, topLevel, $headings); + } + }; + + $(function() { + $('nav[data-toggle="toc"]').each(function(i, el) { + var $nav = $(el); + Toc.init($nav); + }); + }); +})(); diff --git a/docs/index.html b/docs/index.html index 47a66ef..eec1531 100644 --- a/docs/index.html +++ b/docs/index.html @@ -5,23 +5,26 @@ -'htmlwidget' for Interactive Views of R Lists • listviewer - - - - +htmlwidget for Interactive Views of R Lists • listviewer + + + + + + - + lists. The function reactjson() requires a package + reactR that can be installed from CRAN or <https://github.com/timelyportfolio/reactR>."> - + + +
    -
    - -

    A package of R htmlwidgets to interactively view and maybe modify lists. As of now, listviewer provides an interface to jsoneditor and react-json-view. listviewer is designed to support multiple interfaces.

    -
    -

    -install

    +

    R-CMD-check

    +
    + +

    A package of R htmlwidgets to interactively view and maybe modify lists. As of now, listviewer provides an interface to jsoneditor and react-json-view. listviewer is designed to support multiple interfaces.

    +
    +

    install +

    CRAN

    -
    install.packages("listviewer")
    +
    +install.packages("listviewer")

    Development Version

    -
    devtools::install_github("timelyportfolio/listviewer")
    +
    +devtools::install_github("timelyportfolio/listviewer")
    -
    -

    -jsoneditor

    -

    jsoneditor is a really well designed JSON interactive editor by Jos de Jong. Since most R data can be represented in JSON, we can use this great JavaScript library in R.

    - - - - -

    See the above interactive view of par for yourself.

    +
    +

    jsoneditor +

    +

    jsoneditor is a really well designed JSON interactive editor by Jos de Jong. Since most R data can be represented in JSON, we can use this great JavaScript library in R.

    +
    +# using the data from the jsoneditor simple example
    +#  in R list form
    +
    +library(listviewer)
    +
    +jsonedit(
    +  list(
    +    array = c(1,2,3)
    +    ,boolean = TRUE
    +    ,null = NULL
    +    ,number = 123
    +    ,object = list( a="b", c="d" )
    +    ,string = "Hello World"
    +  )
    +)
    +
    +# also works with data.frames
    +jsonedit( mtcars )
    +
    +# helpful interactive view of par
    +jsonedit( par() )
    +
    +# meta view of the above
    +jsonedit(jsonedit(par()))
    +

    See the above interactive view of par for yourself.

    I got this idea courtesy of @jasonpbecker on Twitter. htmlwidgets dependencies are defined by YAML. Let’s see the dependencies for jsonedit.

    -
    jsonedit(
    -  yaml.load_file(system.file("htmlwidgets/jsonedit.yaml",package="listviewer"))
    -)
    +
    +jsonedit(
    +  yaml.load_file(system.file("htmlwidgets/jsonedit.yaml",package="listviewer"))
    +)

    How about topojson?

    - +
    +### experiment with topojson
    +library(httr)
    +library(pipeR)
    +library(listviewer)
    +
    +# topojson for Afghanistan
    +url_path = "https://gist.githubusercontent.com/markmarkoh/8856417/raw/6178d18115d9f273656d294a867c3f83b739a951/customAfghanMap.topo.json"
    +
    +url_path %>>% 
    +  GET %>>%
    +  content( as = "text") %>>%
    +  jsonedit
    -
    -

    -reactjson

    -

    react-json-view is another very nice JSON interactive editor. We even get copy/paste! All of the above examples should also work with reactjson.

    - +
    +

    reactjson +

    +

    react-json-view is another very nice JSON interactive editor. We even get copy/paste! All of the above examples should also work with reactjson.

    +
    +# using the data from the jsoneditor simple example
    +#  in R list form
    +
    +library(listviewer)
    +
    +reactjson(
    +  list(
    +    array = c(1,2,3)
    +    ,boolean = TRUE
    +    ,null = NULL
    +    ,number = 123
    +    ,object = list( a="b", c="d" )
    +    ,string = "Hello World"
    +  )
    +)
    -
    -

    -Shiny example

    +
    +

    Shiny example +

    listviewer works with Shiny but the implementation is crude and likely to change for jsonedit while reactjson integration is much better. If you really want to use jsonedit with Shiny, I would recommend debouncing the change callback. Here are examples with each.

    - - +
    +library(shiny)
    +library(listviewer)
    +
    +# put some data in environment so it will show up
    +data(mtcars)
    +
    +ui <- shinyUI(
    +  fluidPage(
    +    jsoneditOutput( "jsed" )
    +  )
    +)
    +
    +server <- function(input,output){
    +  output$jsed <- renderJsonedit({
    +    jsonedit(
    +      jsonlite::toJSON(mtcars, auto_unbox = TRUE, data.frame = "rows")
    +      ,"onChange" = htmlwidgets::JS('function(after, before, patch){
    +        console.log( after.json )
    +      }')
    +    )
    +    
    +  })
    +}
    +
    +runApp( list( ui = ui, server = server ) )
    +
    +library(shiny)
    +library(listviewer)
    +
    +# put some data in environment so it will show up
    +data(mtcars)
    +
    +ui <- shinyUI(
    +  fluidPage(
    +    reactjsonOutput( "rjed" )
    +  )
    +)
    +
    +server <- function(input,output){
    +  output$rjed <- renderReactjson({
    +    reactjson( jsonlite::toJSON(mtcars, auto_unbox = TRUE, data.frame = "rows") )
    +  })
    +  
    +  observeEvent(input$rjed_edit, {
    +    str(input$rjed_edit, max.level=2)
    +  })
    +}
    +
    +runApp( list( ui = ui, server = server ) )
    -
    -

    -code of conduct

    -

    Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

    +
    +

    code of conduct +

    +

    Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

    -