├── .gitignore ├── 1-01-intro-introduction.Rmd ├── 1-02-basics.Rmd ├── 3-20-htmlwidgets-intro.Rmd ├── 3-21-htmlwidgets-basics.Rmd ├── 3-22-htmlwidgets-first.Rmd ├── 3-23-htmlwidgets-peity.Rmd ├── 3-24-htmlwidgets-gio.Rmd ├── 3-25-htmlwidgets-advanced.Rmd ├── 3-26-htmlwidgets-crosstalk.Rmd ├── 3-27-htmlwidgets-polish.Rmd ├── 4-11-shiny-first-look.Rmd ├── 4-12-shiny-complete.Rmd ├── 4-13-shiny-tips.Rmd ├── 4-15-shiny-output.Rmd ├── 4-16-shiny-input.Rmd ├── 4-17-shiny-cookies.Rmd ├── 4-18-shiny-htmlwidgets.Rmd ├── 6-01-computations-v8.Rmd ├── 6-02-computations-ml.Rmd ├── 7-01-webpack-npm-intro.Rmd ├── 7-02-webpack-npm-discover.Rmd ├── 7-03-webpack-packer.Rmd ├── 7-04-webpack-advanced.Rmd ├── 8-40-conclusion.Rmd ├── 99-references.Rmd ├── LICENSE ├── README.md ├── _book ├── 1-01-intro-introduction.md ├── 1-02-basics.md ├── 3-20-htmlwidgets-intro.md ├── 3-21-htmlwidgets-basics.md ├── 3-22-htmlwidgets-first.md ├── 3-23-htmlwidgets-peity.md ├── 3-24-htmlwidgets-gio.md ├── 3-25-htmlwidgets-advanced.md ├── 3-26-htmlwidgets-crosstalk.md ├── 3-27-htmlwidgets-polish.md ├── 3-28-htmlwidgets-plotly.md ├── 4-11-shiny-first-look.md ├── 4-12-shiny-complete.md ├── 4-13-shiny-tips.md ├── 4-15-shiny-output.md ├── 4-16-shiny-input.md ├── 4-17-shiny-cookies.md ├── 4-18-shiny-htmlwidgets.md ├── 6-01-computations-v8.md ├── 6-02-computations-ml.md ├── 7-01-webpack-npm-intro.md ├── 7-02-webpack-npm-discover.md ├── 7-03-webpack-packer.md ├── 7-04-webpack-advanced.md ├── 7-31-examples-ml5.md ├── 7-31-examples-plotly.md ├── 7-32-examples-rsup.md ├── 8-40-conclusion.md ├── 99-references.md ├── a-complete-integration-jbox-js.html ├── a-complete-integration.html ├── a-first-look-alerts.html ├── a-first-look.html ├── a-realistic-approach.html ├── a-realistic-widget-typed-js.html ├── a-realistic-widget.html ├── a-two-way-street.html ├── advanced-topics.html ├── advanced-usage.html ├── advanced.html ├── basic-widget.html ├── basics-of-building-widgets.html ├── basics.html ├── bookdown.tex ├── conclusion.html ├── cookies.html ├── crosstalk.html ├── css │ ├── style.css │ └── toc.css ├── custom-input.html ├── custom-inputs.html ├── custom-outputs.html ├── discover.html ├── events-1.html ├── excercise-ploty.html ├── exercise-machine-learning.html ├── exercise-ploty.html ├── external-library-1.html ├── favicon.ico ├── final-revisions.html ├── for-the-curious.html ├── from-javascript-to-r.html ├── from-r-to-javascript.html ├── get-started.html ├── html-widgets.html ├── htmlwidgets-with-shiny.html ├── image-classifier.html ├── images │ ├── DT-example.png │ ├── alert-shiny.png │ ├── alert.png │ ├── bootstrap-input-group-addon.png │ ├── boxxy-example.png │ ├── candidate-chartjs.png │ ├── candidate-highcharts.png │ ├── candidate-plotly.png │ ├── checkbox-switch.png │ ├── console-table.png │ ├── cover.jpg │ ├── crosstalk-gio-1.png │ ├── crosstalk-gio-2.png │ ├── crosstalk-shiny.png │ ├── crosstalk-three-dots.png │ ├── crosstalk.png │ ├── custom-output-boxxy.png │ ├── devtools.png │ ├── dt-button.png │ ├── dt-crosstalk-intro.png │ ├── gio-100.png │ ├── gio-data.png │ ├── gio-example.png │ ├── gio-fit.png │ ├── gio-init.png │ ├── gio-input-handler.png │ ├── gio-shiny-clear.png │ ├── gio-shiny-error.png │ ├── gio-shiny-input-no-handler.png │ ├── gio-shiny-input.png │ ├── gio-shiny-style.png │ ├── gio-size-issue.png │ ├── gio-small.png │ ├── gio-style.png │ ├── gio-title.png │ ├── htmlwidgets-performances.png │ ├── javascript-intro.png │ ├── jbox-custom.png │ ├── jbox-end.png │ ├── jbox-init.png │ ├── jbox-r2js.png │ ├── lena-demo.png │ ├── lena-test.png │ ├── ml5-init.png │ ├── ml5-output.png │ ├── ml5-pkg.png │ ├── ml5-table.png │ ├── mousetrap.png │ ├── notice-1.png │ ├── notice-2.png │ ├── open-in-browser.png │ ├── peity-div.png │ ├── peity-span.png │ ├── playground-1.png │ ├── playground-color.png │ ├── playground-console-el.png │ ├── playground-console-x.png │ ├── playground-deps.png │ ├── playground-h1.png │ ├── playground-source.png │ ├── plotlier-add.png │ ├── plotlier-responsive.png │ ├── plotlier-scatter.png │ ├── rstudio-create-package.png │ ├── rsup.png │ ├── shiny-complete-classify-console.png │ ├── shiny-complete-skeleton.png │ ├── shiny-complete-table.png │ ├── shiny-cookies-2.png │ ├── shiny-cookies.png │ ├── shiny-events.png │ ├── social.png │ ├── stats.png │ ├── switch-example.png │ ├── tryingjs.png │ ├── vue-bs4.png │ └── waiter.png ├── index.html ├── index.md ├── intro-overview.html ├── intro.html ├── introduction-1.html ├── introduction-2.html ├── introduction-to-htmlwidgets.html ├── introduction-to-rmarkdown.html ├── introduction-to-shiny.html ├── introduction-to-widgets.html ├── introduction.html ├── lena.html ├── libs │ ├── DiagrammeR-styles-0.2 │ │ └── styles.css │ ├── DiagrammeR-styles │ │ └── styles.css │ ├── accessible-code-block-0.0.1 │ │ └── empty-anchor.js │ ├── accessible-code-block │ │ └── empty-anchor.js │ ├── anchor-sections-1.0 │ │ ├── anchor-sections.css │ │ └── anchor-sections.js │ ├── core-js-2.5.3 │ │ └── shim.min.js │ ├── core-js │ │ └── shim.min.js │ ├── crosstalk-1.1.0.1 │ │ ├── css │ │ │ └── crosstalk.css │ │ └── js │ │ │ └── crosstalk.min.js │ ├── crosstalk-1.1.1 │ │ ├── css │ │ │ └── crosstalk.css │ │ └── js │ │ │ └── crosstalk.min.js │ ├── crosstalk │ │ ├── css │ │ │ └── crosstalk.css │ │ └── js │ │ │ └── crosstalk.min.js │ ├── d3v5-5.0.0 │ │ └── d3.min.js │ ├── d3v5 │ │ └── d3.min.js │ ├── d3v6-6.2.0 │ │ └── d3.min.js │ ├── datatables-binding-0.16 │ │ └── datatables.js │ ├── datatables-binding-0.17 │ │ └── datatables.js │ ├── datatables-binding │ │ └── datatables.js │ ├── datatables-css-0.0.0 │ │ └── datatables-crosstalk.css │ ├── datatables-css │ │ └── datatables-crosstalk.css │ ├── dt-core-1.10.20 │ │ ├── css │ │ │ ├── jquery.dataTables.extra.css │ │ │ └── jquery.dataTables.min.css │ │ └── js │ │ │ └── jquery.dataTables.min.js │ ├── dt-core │ │ ├── css │ │ │ ├── jquery.dataTables.extra.css │ │ │ └── jquery.dataTables.min.css │ │ └── js │ │ │ └── jquery.dataTables.min.js │ ├── gitbook-2.6.7 │ │ ├── css │ │ │ ├── fontawesome │ │ │ │ └── fontawesome-webfont.ttf │ │ │ ├── plugin-bookdown.css │ │ │ ├── plugin-clipboard.css │ │ │ ├── plugin-fontsettings.css │ │ │ ├── plugin-highlight.css │ │ │ ├── plugin-search.css │ │ │ ├── plugin-table.css │ │ │ └── style.css │ │ └── js │ │ │ ├── app.min.js │ │ │ ├── clipboard.min.js │ │ │ ├── jquery.highlight.js │ │ │ ├── lunr.js │ │ │ ├── plugin-bookdown.js │ │ │ ├── plugin-clipboard.js │ │ │ ├── plugin-fontsettings.js │ │ │ ├── plugin-search.js │ │ │ └── plugin-sharing.js │ ├── gitbook │ │ ├── css │ │ │ ├── fontawesome │ │ │ │ └── fontawesome-webfont.ttf │ │ │ ├── plugin-bookdown.css │ │ │ ├── plugin-clipboard.css │ │ │ ├── plugin-fontsettings.css │ │ │ ├── plugin-highlight.css │ │ │ ├── plugin-search.css │ │ │ ├── plugin-table.css │ │ │ └── style.css │ │ └── js │ │ │ ├── app.min.js │ │ │ ├── clipboard.min.js │ │ │ ├── jquery.highlight.js │ │ │ ├── lunr.js │ │ │ ├── plugin-bookdown.js │ │ │ ├── plugin-clipboard.js │ │ │ ├── plugin-fontsettings.js │ │ │ ├── plugin-search.js │ │ │ └── plugin-sharing.js │ ├── grViz-binding-1.0.6.1 │ │ └── grViz.js │ ├── grViz-binding │ │ └── grViz.js │ ├── header-attrs-2.4 │ │ └── header-attrs.js │ ├── header-attrs-2.5 │ │ └── header-attrs.js │ ├── header-attrs-2.6 │ │ └── header-attrs.js │ ├── header-attrs │ │ └── header-attrs.js │ ├── htmlwidgets-1.5.2.9000 │ │ └── htmlwidgets.js │ ├── htmlwidgets-1.5.2 │ │ └── htmlwidgets.js │ ├── htmlwidgets-1.5.3 │ │ └── htmlwidgets.js │ ├── htmlwidgets │ │ └── htmlwidgets.js │ ├── jquery-2.2.3 │ │ └── jquery.min.js │ ├── jquery-3.5.1 │ │ └── jquery.min.js │ ├── jquery │ │ └── jquery.min.js │ ├── peity-binding │ │ └── peity.js │ ├── peity │ │ └── jquery.peity.min.js │ ├── plotly-binding-4.9.2.1 │ │ └── plotly.js │ ├── plotly-binding-4.9.2.9000 │ │ └── plotly.js │ ├── plotly-binding-4.9.3 │ │ └── plotly.js │ ├── plotly-binding │ │ └── plotly.js │ ├── plotly-htmlwidgets-css-1.52.2 │ │ └── plotly-htmlwidgets.css │ ├── plotly-htmlwidgets-css-1.54.1 │ │ └── plotly-htmlwidgets.css │ ├── plotly-htmlwidgets-css-1.57.1 │ │ └── plotly-htmlwidgets.css │ ├── plotly-htmlwidgets-css │ │ └── plotly-htmlwidgets.css │ ├── plotly-main-1.52.2 │ │ └── plotly-latest.min.js │ ├── plotly-main-1.54.1 │ │ └── plotly-latest.min.js │ ├── plotly-main-1.57.1 │ │ └── plotly-latest.min.js │ ├── plotly-main │ │ └── plotly-latest.min.js │ ├── plotly │ │ └── plotly.min.js │ ├── r2d3-binding-0.2.3 │ │ └── r2d3.js │ ├── r2d3-binding-0.2.5 │ │ └── r2d3.js │ ├── r2d3-binding │ │ └── r2d3.js │ ├── r2d3-render-0.1.0 │ │ └── r2d3-render.js │ ├── r2d3-render │ │ └── r2d3-render.js │ ├── react-16.12.0 │ │ ├── react-dom.min.js │ │ └── react.min.js │ ├── react │ │ ├── react-dom.min.js │ │ └── react.min.js │ ├── reactable-binding-0.2.3 │ │ └── reactable.js │ ├── reactable-binding │ │ └── reactable.js │ ├── reactwidget-1.0.0 │ │ └── react-tools.js │ ├── reactwidget │ │ └── react-tools.js │ ├── typedarray-0.1 │ │ └── typedarray.min.js │ ├── typedarray │ │ └── typedarray.min.js │ ├── viz-1.8.2 │ │ └── viz.js │ ├── viz │ │ └── viz.js │ ├── webcomponents-2.0.0 │ │ └── webcomponents.js │ └── webcomponents │ │ └── webcomponents.js ├── linking-widgets.html ├── machine-learning.html ├── math-evaluator.html ├── node.html ├── overview.html ├── packer-adv.html ├── packer-overview.html ├── part-basics-roadmap.html ├── part-closing-remarks.html ├── part-data-visualisation.html ├── part-examples.html ├── part-javascript-for-computations.html ├── part-web-development-with-shiny.html ├── ploty.html ├── polish-and-good-practice.html ├── prerequisites.html ├── progress-bar.html ├── progress.html ├── references.html ├── rmd-intro.html ├── search_index.json ├── shiny-1.html ├── shiny-complete.html ├── shiny-cookies.html ├── shiny-input.html ├── shiny-intro.html ├── shiny-output.html ├── shiny-tips.html ├── shiny-widgets.html ├── the-full-monty-gio-js.html ├── the-full-monty.html ├── the-v8-engine.html ├── tips-tricks.html ├── v8-img.html ├── v8-ml.html ├── v8.html ├── webpack-intro-discover.html ├── webpack-intro.html ├── widgets-adv.html ├── widgets-basics.html ├── widgets-ex-plotly.html ├── widgets-final.html ├── widgets-first.html ├── widgets-full.html ├── widgets-intro-intro.html ├── widgets-realistic.html ├── widgets-with-shiny.html ├── working-with-shiny.html ├── wrap-up.html └── your-first-widget.html ├── _bookdown.yml ├── _bookdown_files ├── 1-01-intro-introduction_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 1-02-basics_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 3-20-htmlwidgets-intro_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 3-21-htmlwidgets-basics_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 3-22-htmlwidgets-first_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 3-23-htmlwidgets-peity_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 3-24-htmlwidgets-gio_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 3-25-htmlwidgets-advanced_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 3-26-htmlwidgets-crosstalk_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 3-27-htmlwidgets-polish_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 4-11-shiny-first-look_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 4-12-shiny-complete_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 4-13-shiny-tips_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 4-15-shiny-output_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 4-16-shiny-input_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 4-17-shiny-cookies_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 4-18-shiny-htmlwidgets_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 6-01-computations-v8_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 6-02-computations-ml_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 7-02-webpack-npm-discover_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 7-03-webpack-packer_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages ├── 7-04-webpack-advanced_cache │ ├── html │ │ └── __packages │ └── latex │ │ └── __packages └── index_cache │ ├── html │ └── __packages │ └── latex │ └── __packages ├── _install.sh ├── _output.yml ├── before.R ├── book.bib ├── chord.js ├── code ├── README.md ├── boxxy │ ├── app.R │ └── assets │ │ ├── binding.js │ │ ├── countup.js │ │ └── styles.css ├── candidate-libraries │ ├── README.md │ ├── chartjs.html │ ├── highcharts.html │ └── plotly.html ├── cookies │ ├── README.md │ ├── app.R │ └── www │ │ └── script.js ├── counter │ ├── .Rbuildignore │ ├── .gitignore │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ └── countup.R │ ├── inst │ │ └── htmlwidgets │ │ │ ├── countup.js │ │ │ └── countup.yaml │ ├── man │ │ ├── countup-shiny.Rd │ │ └── countup.Rd │ ├── package-lock.json │ ├── package.json │ ├── srcjs │ │ ├── config │ │ │ ├── entry_points.json │ │ │ ├── externals.json │ │ │ ├── loaders.json │ │ │ ├── misc.json │ │ │ └── output_path.json │ │ ├── index.js │ │ ├── modules │ │ │ └── count.js │ │ └── widgets │ │ │ └── countup.js │ ├── webpack.common.js │ ├── webpack.dev.js │ └── webpack.prod.js ├── events │ ├── README.md │ ├── app.R │ └── www │ │ ├── script.js │ │ ├── style.css │ │ └── typing.gif ├── gio │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ ├── gio.R │ │ ├── handler.R │ │ ├── proxy.R │ │ ├── stats.R │ │ ├── style.R │ │ ├── title.R │ │ ├── utils-pipe.R │ │ └── zzz.R │ ├── README.md │ ├── inst │ │ └── htmlwidgets │ │ │ ├── gio.js │ │ │ ├── gio.yaml │ │ │ ├── gio │ │ │ └── gio.min.js │ │ │ ├── stats │ │ │ └── stats.min.js │ │ │ └── three │ │ │ └── three.min.js │ └── man │ │ ├── gio-shiny.Rd │ │ ├── gio.Rd │ │ └── pipe.Rd ├── increment │ ├── .Rbuildignore │ ├── .gitignore │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ └── increment.R │ ├── inst │ │ └── packer │ │ │ └── increment.js │ ├── package-lock.json │ ├── package.json │ ├── srcjs │ │ ├── config │ │ │ ├── entry_points.json │ │ │ ├── externals.json │ │ │ ├── loaders.json │ │ │ ├── misc.json │ │ │ └── output_path.json │ │ ├── index.js │ │ └── inputs │ │ │ └── increment.js │ ├── webpack.common.js │ ├── webpack.dev.js │ └── webpack.prod.js ├── javascript-intro │ └── index.html ├── jbox │ └── app.R ├── ml │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ ├── lm.R │ │ └── zzz.R │ ├── README.md │ └── inst │ │ └── ml.min.js ├── ml5-app │ ├── README.md │ ├── app.R │ └── assets │ │ ├── classify.js │ │ ├── flamingo.jpg │ │ ├── fratercula.jpg │ │ ├── gentoo.jpg │ │ ├── hummingbird.jpg │ │ └── lorikeet.jpg ├── ml5-pkg-test │ ├── app.R │ └── assets │ │ ├── flamingo.jpg │ │ ├── fratercula.jpg │ │ ├── gentoo.jpg │ │ ├── hummingbird.jpg │ │ └── lorikeet.jpg ├── ml5-pkg │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ ├── classify.R │ │ ├── deps.R │ │ └── handler.R │ └── inst │ │ ├── classify.js │ │ └── ml5.min.js ├── ms │ ├── .Rbuildignore │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ ├── ms.R │ │ └── zzz.R │ ├── README.md │ ├── in.js │ ├── inst │ │ └── ms.js │ └── man │ │ └── to_ms.Rd ├── peity │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ └── peity.R │ ├── inst │ │ └── htmlwidgets │ │ │ ├── jquery │ │ │ └── jquery.min.js │ │ │ ├── peity.js │ │ │ ├── peity.yaml │ │ │ └── peity │ │ │ └── jquery.peity.min.js │ └── man │ │ ├── peity-shiny.Rd │ │ └── peity.Rd ├── playground │ ├── .Rbuildignore │ ├── .gitignore │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ └── play.R │ ├── inst │ │ └── htmlwidgets │ │ │ ├── play.js │ │ │ └── play.yaml │ ├── man │ │ ├── play-shiny.Rd │ │ └── play.Rd │ └── playground.Rproj ├── plotlier │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ ├── add.R │ │ ├── layers.R │ │ ├── plotly.R │ │ └── utils-pipe.R │ ├── README.md │ ├── inst │ │ └── htmlwidgets │ │ │ ├── plotly.js │ │ │ ├── plotly.yaml │ │ │ └── plotly │ │ │ └── plotly.min.js │ └── man │ │ ├── pipe.Rd │ │ ├── plotly-shiny.Rd │ │ └── plotly.Rd ├── rsup │ ├── README.md │ ├── app-auto.R │ ├── app.R │ └── www │ │ ├── auto.js │ │ └── script.js ├── switch-input │ ├── app.R │ └── assets │ │ ├── binding.js │ │ └── styles.css ├── table-button │ ├── README.md │ └── app.R ├── typed │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ └── typed.R │ ├── README.md │ └── inst │ │ └── htmlwidgets │ │ ├── typed.js │ │ ├── typed.yaml │ │ └── typed │ │ └── typed.min.js ├── vuer │ ├── .Rbuildignore │ ├── .babelrc │ ├── .gitignore │ ├── DESCRIPTION │ ├── NAMESPACE │ ├── R │ │ ├── app_config.R │ │ ├── app_server.R │ │ ├── app_ui.R │ │ ├── run_app.R │ │ └── vue_cdn.R │ ├── dev │ │ ├── 01_start.R │ │ ├── 02_dev.R │ │ ├── 03_deploy.R │ │ └── run_dev.R │ ├── inst │ │ ├── app │ │ │ └── www │ │ │ │ ├── favicon.ico │ │ │ │ ├── index.js │ │ │ │ └── index.js.LICENSE.txt │ │ └── golem-config.yml │ ├── man │ │ └── run_app.Rd │ ├── package-lock.json │ ├── package.json │ ├── srcjs │ │ ├── Home.vue │ │ ├── config │ │ │ ├── entry_points.json │ │ │ ├── externals.json │ │ │ ├── loaders.json │ │ │ ├── misc.json │ │ │ └── output_path.json │ │ └── index.js │ ├── webpack.common.js │ ├── webpack.dev.js │ └── webpack.prod.js └── webpack-intro │ ├── app.R │ ├── dist │ └── main.js │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── index.js │ ├── input.js │ └── secret.js │ └── webpack.config.js ├── css ├── style.css └── toc.css ├── data └── countries.json ├── favicon.ico ├── ga.html ├── images ├── 01-d3.png ├── 01-plotly.png ├── 01-reactable.png ├── 02-dom-viz.png ├── 03-DT.png ├── 03-crosstalk-gio.png ├── 03-crosstalk-grps.png ├── 03-crosstalk-viz.png ├── 03-ggplotly.png ├── 03-htmlwidget-viz.png ├── 03-htmlwidgets-internals.png ├── 03-plotly-multiple.png ├── 03-plotly-scatter.png ├── 04-custom-msg.png ├── 04-shiny-complex.png ├── 04-shiny-input.png ├── 04-shiny-websocket.png ├── 04-websocket.png ├── 07-webpack-shiny.png ├── DT-example.png ├── alert-shiny.png ├── alert.png ├── boxxy-example.png ├── candidate-chartjs.png ├── candidate-highcharts.png ├── candidate-plotly.png ├── checkbox-switch.png ├── console-table.png ├── coronavirus.png ├── cover.jpg ├── crosstalk-gio-1.png ├── crosstalk-gio-2.png ├── crosstalk-shiny.png ├── crosstalk-three-dots.png ├── crosstalk.png ├── custom-output-boxxy.png ├── devtools.png ├── dt-button.png ├── dt-crosstalk-intro.png ├── gio-100.png ├── gio-data.png ├── gio-example.png ├── gio-fit.png ├── gio-init.png ├── gio-input-handler.png ├── gio-shiny-clear.png ├── gio-shiny-error.png ├── gio-shiny-input-no-handler.png ├── gio-shiny-style.png ├── gio-size-issue.png ├── gio-small.png ├── gio-style.png ├── gio-title.png ├── hotkeys-console.png ├── htmlwidgets-performances.png ├── javascript-intro.png ├── jbox-custom.png ├── jbox-end.png ├── jbox-init.png ├── jbox-r2js.png ├── jbox-recreate.png ├── lena-demo.png ├── lena-test.png ├── ml5-init.png ├── ml5-output.png ├── ml5-pkg.png ├── ml5-table.png ├── mousetrap.png ├── note.png ├── open-in-browser.png ├── peity-div.png ├── peity-span.png ├── playground-1.png ├── playground-color.png ├── playground-console-el.png ├── playground-console-x.png ├── playground-deps.png ├── playground-h1.png ├── playground-source.png ├── plotlier-add.png ├── plotlier-responsive.png ├── plotlier-scatter.png ├── rstudio-create-package.png ├── rsup.png ├── shiny-complete-classify-console.png ├── shiny-complete-skeleton.png ├── shiny-complete-table.png ├── shiny-cookies-1.png ├── shiny-cookies-2.png ├── shiny-cookies.png ├── shiny-events.png ├── social.png ├── stats.png ├── switch-example.png ├── tryingjs.png ├── typed-deps.png ├── vue-bs4.png └── waiter.png ├── index.Rmd ├── krantz.cls ├── latex ├── after_body.tex ├── before_body.tex └── preamble.tex ├── makefile ├── ms.js ├── package-lock.json ├── package.json ├── packages.bib ├── preface.html ├── social.html ├── try.html └── utils.R /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | node_modules 6 | .DS_Store 7 | _book/bookdown.epub 8 | _book/bookdown.pdf 9 | .vscode 10 | _bookdown_files 11 | bookdown.rds 12 | corrector-note.md 13 | -------------------------------------------------------------------------------- /99-references.Rmd: -------------------------------------------------------------------------------- 1 | `r if (knitr:::is_html_output()) '# References {-}'` 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # R and JavaScript 2 | 3 | Code for the [JavaScript for R](https://javascript-for-r.com/) book. 4 | 5 | -------------------------------------------------------------------------------- /_book/99-references.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /_book/css/toc.css: -------------------------------------------------------------------------------- 1 | .book .book-summary { 2 | position: absolute; 3 | top: 0; 4 | left: -300px; 5 | width: 300px; 6 | bottom: 0; 7 | z-index: 1; 8 | color: #FFFFFF; 9 | background: #0462a1; 10 | } 11 | 12 | .book .book-summary ul.summary li a, .book .book-summary ul.summary li span { 13 | margin: 5px 5px 5px 5px; 14 | display: block; 15 | padding: 10px 20px 10px 20px; 16 | color: #FFFFFF; 17 | background: 0 0; 18 | text-overflow: ellipsis; 19 | overflow: hidden; 20 | white-space: nowrap; 21 | position: relative; 22 | } 23 | 24 | .book .book-summary ul.summary li.active>a { 25 | padding-left: 5px; 26 | color: #FFFFFF; 27 | font-weight: bold; 28 | border-left:4px solid #ffcb00; 29 | text-decoration: none; 30 | } 31 | 32 | .book .book-summary ul.summary li a:hover { 33 | padding-left: 5px; 34 | color: #FFFFFF; 35 | font-weight: bold; 36 | border-left:4px solid #ffcb00; 37 | text-decoration: none; 38 | } 39 | 40 | td, tr, th { 41 | color:white !important; 42 | background-color: transparent !important; 43 | } 44 | 45 | table { 46 | color:white !important; 47 | background-color: #0462a1 !important; 48 | } 49 | 50 | 51 | .part{ 52 | padding-top: 2em; 53 | text-transform: uppercase; 54 | font-size: .95em; 55 | } 56 | -------------------------------------------------------------------------------- /_book/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/favicon.ico -------------------------------------------------------------------------------- /_book/images/DT-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/DT-example.png -------------------------------------------------------------------------------- /_book/images/alert-shiny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/alert-shiny.png -------------------------------------------------------------------------------- /_book/images/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/alert.png -------------------------------------------------------------------------------- /_book/images/bootstrap-input-group-addon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/bootstrap-input-group-addon.png -------------------------------------------------------------------------------- /_book/images/boxxy-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/boxxy-example.png -------------------------------------------------------------------------------- /_book/images/candidate-chartjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/candidate-chartjs.png -------------------------------------------------------------------------------- /_book/images/candidate-highcharts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/candidate-highcharts.png -------------------------------------------------------------------------------- /_book/images/candidate-plotly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/candidate-plotly.png -------------------------------------------------------------------------------- /_book/images/checkbox-switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/checkbox-switch.png -------------------------------------------------------------------------------- /_book/images/console-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/console-table.png -------------------------------------------------------------------------------- /_book/images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/cover.jpg -------------------------------------------------------------------------------- /_book/images/crosstalk-gio-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/crosstalk-gio-1.png -------------------------------------------------------------------------------- /_book/images/crosstalk-gio-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/crosstalk-gio-2.png -------------------------------------------------------------------------------- /_book/images/crosstalk-shiny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/crosstalk-shiny.png -------------------------------------------------------------------------------- /_book/images/crosstalk-three-dots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/crosstalk-three-dots.png -------------------------------------------------------------------------------- /_book/images/crosstalk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/crosstalk.png -------------------------------------------------------------------------------- /_book/images/custom-output-boxxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/custom-output-boxxy.png -------------------------------------------------------------------------------- /_book/images/devtools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/devtools.png -------------------------------------------------------------------------------- /_book/images/dt-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/dt-button.png -------------------------------------------------------------------------------- /_book/images/dt-crosstalk-intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/dt-crosstalk-intro.png -------------------------------------------------------------------------------- /_book/images/gio-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-100.png -------------------------------------------------------------------------------- /_book/images/gio-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-data.png -------------------------------------------------------------------------------- /_book/images/gio-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-example.png -------------------------------------------------------------------------------- /_book/images/gio-fit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-fit.png -------------------------------------------------------------------------------- /_book/images/gio-init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-init.png -------------------------------------------------------------------------------- /_book/images/gio-input-handler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-input-handler.png -------------------------------------------------------------------------------- /_book/images/gio-shiny-clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-shiny-clear.png -------------------------------------------------------------------------------- /_book/images/gio-shiny-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-shiny-error.png -------------------------------------------------------------------------------- /_book/images/gio-shiny-input-no-handler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-shiny-input-no-handler.png -------------------------------------------------------------------------------- /_book/images/gio-shiny-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-shiny-input.png -------------------------------------------------------------------------------- /_book/images/gio-shiny-style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-shiny-style.png -------------------------------------------------------------------------------- /_book/images/gio-size-issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-size-issue.png -------------------------------------------------------------------------------- /_book/images/gio-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-small.png -------------------------------------------------------------------------------- /_book/images/gio-style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-style.png -------------------------------------------------------------------------------- /_book/images/gio-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/gio-title.png -------------------------------------------------------------------------------- /_book/images/htmlwidgets-performances.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/htmlwidgets-performances.png -------------------------------------------------------------------------------- /_book/images/javascript-intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/javascript-intro.png -------------------------------------------------------------------------------- /_book/images/jbox-custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/jbox-custom.png -------------------------------------------------------------------------------- /_book/images/jbox-end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/jbox-end.png -------------------------------------------------------------------------------- /_book/images/jbox-init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/jbox-init.png -------------------------------------------------------------------------------- /_book/images/jbox-r2js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/jbox-r2js.png -------------------------------------------------------------------------------- /_book/images/lena-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/lena-demo.png -------------------------------------------------------------------------------- /_book/images/lena-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/lena-test.png -------------------------------------------------------------------------------- /_book/images/ml5-init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/ml5-init.png -------------------------------------------------------------------------------- /_book/images/ml5-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/ml5-output.png -------------------------------------------------------------------------------- /_book/images/ml5-pkg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/ml5-pkg.png -------------------------------------------------------------------------------- /_book/images/ml5-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/ml5-table.png -------------------------------------------------------------------------------- /_book/images/mousetrap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/mousetrap.png -------------------------------------------------------------------------------- /_book/images/notice-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/notice-1.png -------------------------------------------------------------------------------- /_book/images/notice-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/notice-2.png -------------------------------------------------------------------------------- /_book/images/open-in-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/open-in-browser.png -------------------------------------------------------------------------------- /_book/images/peity-div.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/peity-div.png -------------------------------------------------------------------------------- /_book/images/peity-span.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/peity-span.png -------------------------------------------------------------------------------- /_book/images/playground-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/playground-1.png -------------------------------------------------------------------------------- /_book/images/playground-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/playground-color.png -------------------------------------------------------------------------------- /_book/images/playground-console-el.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/playground-console-el.png -------------------------------------------------------------------------------- /_book/images/playground-console-x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/playground-console-x.png -------------------------------------------------------------------------------- /_book/images/playground-deps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/playground-deps.png -------------------------------------------------------------------------------- /_book/images/playground-h1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/playground-h1.png -------------------------------------------------------------------------------- /_book/images/playground-source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/playground-source.png -------------------------------------------------------------------------------- /_book/images/plotlier-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/plotlier-add.png -------------------------------------------------------------------------------- /_book/images/plotlier-responsive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/plotlier-responsive.png -------------------------------------------------------------------------------- /_book/images/plotlier-scatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/plotlier-scatter.png -------------------------------------------------------------------------------- /_book/images/rstudio-create-package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/rstudio-create-package.png -------------------------------------------------------------------------------- /_book/images/rsup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/rsup.png -------------------------------------------------------------------------------- /_book/images/shiny-complete-classify-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/shiny-complete-classify-console.png -------------------------------------------------------------------------------- /_book/images/shiny-complete-skeleton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/shiny-complete-skeleton.png -------------------------------------------------------------------------------- /_book/images/shiny-complete-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/shiny-complete-table.png -------------------------------------------------------------------------------- /_book/images/shiny-cookies-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/shiny-cookies-2.png -------------------------------------------------------------------------------- /_book/images/shiny-cookies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/shiny-cookies.png -------------------------------------------------------------------------------- /_book/images/shiny-events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/shiny-events.png -------------------------------------------------------------------------------- /_book/images/social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/social.png -------------------------------------------------------------------------------- /_book/images/stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/stats.png -------------------------------------------------------------------------------- /_book/images/switch-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/switch-example.png -------------------------------------------------------------------------------- /_book/images/tryingjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/tryingjs.png -------------------------------------------------------------------------------- /_book/images/vue-bs4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/vue-bs4.png -------------------------------------------------------------------------------- /_book/images/waiter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/images/waiter.png -------------------------------------------------------------------------------- /_book/libs/DiagrammeR-styles-0.2/styles.css: -------------------------------------------------------------------------------- 1 | .DiagrammeR,.grViz pre { 2 | white-space: pre-wrap; /* CSS 3 */ 3 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 4 | white-space: -pre-wrap; /* Opera 4-6 */ 5 | white-space: -o-pre-wrap; /* Opera 7 */ 6 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 7 | } 8 | 9 | .DiagrammeR g .label { 10 | font-family: Helvetica; 11 | font-size: 14px; 12 | color: #333333; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /_book/libs/DiagrammeR-styles/styles.css: -------------------------------------------------------------------------------- 1 | .DiagrammeR,.grViz pre { 2 | white-space: pre-wrap; /* CSS 3 */ 3 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 4 | white-space: -pre-wrap; /* Opera 4-6 */ 5 | white-space: -o-pre-wrap; /* Opera 7 */ 6 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 7 | } 8 | 9 | .DiagrammeR g .label { 10 | font-family: Helvetica; 11 | font-size: 14px; 12 | color: #333333; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /_book/libs/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /_book/libs/accessible-code-block/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /_book/libs/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /_book/libs/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /_book/libs/crosstalk-1.1.0.1/css/crosstalk.css: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /_book/libs/crosstalk-1.1.1/css/crosstalk.css: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /_book/libs/crosstalk/css/crosstalk.css: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /_book/libs/datatables-css-0.0.0/datatables-crosstalk.css: -------------------------------------------------------------------------------- 1 | .dt-crosstalk-fade { 2 | opacity: 0.2; 3 | } 4 | 5 | html body div.DTS div.dataTables_scrollBody { 6 | background: none; 7 | } 8 | 9 | 10 | /* 11 | Fix https://github.com/rstudio/DT/issues/563 12 | If the `table.display` is set to "block" (e.g., pkgdown), the browser will display 13 | datatable objects strangely. The search panel and the page buttons will still be 14 | in full-width but the table body will be "compact" and shorter. 15 | In therory, having this attributes will affect `dom="t"` 16 | with `display: block` users. But in reality, there should be no one. 17 | We may remove the below lines in the future if the upstream agree to have this there. 18 | See https://github.com/DataTables/DataTablesSrc/issues/160 19 | */ 20 | 21 | table.dataTable { 22 | display: table; 23 | } 24 | -------------------------------------------------------------------------------- /_book/libs/datatables-css/datatables-crosstalk.css: -------------------------------------------------------------------------------- 1 | .dt-crosstalk-fade { 2 | opacity: 0.2; 3 | } 4 | 5 | html body div.DTS div.dataTables_scrollBody { 6 | background: none; 7 | } 8 | 9 | 10 | /* 11 | Fix https://github.com/rstudio/DT/issues/563 12 | If the `table.display` is set to "block" (e.g., pkgdown), the browser will display 13 | datatable objects strangely. The search panel and the page buttons will still be 14 | in full-width but the table body will be "compact" and shorter. 15 | In therory, having this attributes will affect `dom="t"` 16 | with `display: block` users. But in reality, there should be no one. 17 | We may remove the below lines in the future if the upstream agree to have this there. 18 | See https://github.com/DataTables/DataTablesSrc/issues/160 19 | */ 20 | 21 | table.dataTable { 22 | display: table; 23 | } 24 | -------------------------------------------------------------------------------- /_book/libs/dt-core-1.10.20/css/jquery.dataTables.extra.css: -------------------------------------------------------------------------------- 1 | /* Selected rows/cells */ 2 | table.dataTable tr.selected td, table.dataTable td.selected { 3 | background-color: #b0bed9 !important; 4 | } 5 | /* In case of scrollX/Y or FixedHeader */ 6 | .dataTables_scrollBody .dataTables_sizing { 7 | visibility: hidden; 8 | } 9 | 10 | /* The datatables' theme CSS file doesn't define 11 | the color but with white background. It leads to an issue that 12 | when the HTML's body color is set to 'white', the user can't 13 | see the text since the background is white. One case happens in the 14 | RStudio's IDE when inline viewing the DT table inside an Rmd file, 15 | if the IDE theme is set to "Cobalt". 16 | 17 | See https://github.com/rstudio/DT/issues/447 for more info 18 | 19 | This fixes should have little side-effects because all the other elements 20 | of the default theme use the #333 font color. 21 | 22 | TODO: The upstream may use relative colors for both the table background 23 | and the color. It means the table can display well without this patch 24 | then. At that time, we need to remove the below CSS attributes. 25 | */ 26 | div.datatables { 27 | color: #333; 28 | } 29 | -------------------------------------------------------------------------------- /_book/libs/dt-core/css/jquery.dataTables.extra.css: -------------------------------------------------------------------------------- 1 | /* Selected rows/cells */ 2 | table.dataTable tr.selected td, table.dataTable td.selected { 3 | background-color: #b0bed9 !important; 4 | } 5 | /* In case of scrollX/Y or FixedHeader */ 6 | .dataTables_scrollBody .dataTables_sizing { 7 | visibility: hidden; 8 | } 9 | 10 | /* The datatables' theme CSS file doesn't define 11 | the color but with white background. It leads to an issue that 12 | when the HTML's body color is set to 'white', the user can't 13 | see the text since the background is white. One case happens in the 14 | RStudio's IDE when inline viewing the DT table inside an Rmd file, 15 | if the IDE theme is set to "Cobalt". 16 | 17 | See https://github.com/rstudio/DT/issues/447 for more info 18 | 19 | This fixes should have little side-effects because all the other elements 20 | of the default theme use the #333 font color. 21 | 22 | TODO: The upstream may use relative colors for both the table background 23 | and the color. It means the table can display well without this patch 24 | then. At that time, we need to remove the below CSS attributes. 25 | */ 26 | div.datatables { 27 | color: #333; 28 | } 29 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/css/fontawesome/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/libs/gitbook-2.6.7/css/fontawesome/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/css/plugin-clipboard.css: -------------------------------------------------------------------------------- 1 | div.sourceCode { 2 | position: relative; 3 | } 4 | 5 | .copy-to-clipboard-button { 6 | position: absolute; 7 | right: 0; 8 | top: 0; 9 | visibility: hidden; 10 | } 11 | 12 | .copy-to-clipboard-button:focus { 13 | outline: 0; 14 | } 15 | 16 | div.sourceCode:hover > .copy-to-clipboard-button { 17 | visibility: visible; 18 | } 19 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/css/plugin-search.css: -------------------------------------------------------------------------------- 1 | .book .book-summary .book-search { 2 | padding: 6px; 3 | background: transparent; 4 | position: absolute; 5 | top: -50px; 6 | left: 0px; 7 | right: 0px; 8 | transition: top 0.5s ease; 9 | } 10 | .book .book-summary .book-search input, 11 | .book .book-summary .book-search input:focus, 12 | .book .book-summary .book-search input:hover { 13 | width: 100%; 14 | background: transparent; 15 | border: 1px solid #ccc; 16 | box-shadow: none; 17 | outline: none; 18 | line-height: 22px; 19 | padding: 7px 4px; 20 | color: inherit; 21 | box-sizing: border-box; 22 | } 23 | .book.with-search .book-summary .book-search { 24 | top: 0px; 25 | } 26 | .book.with-search .book-summary ul.summary { 27 | top: 50px; 28 | } 29 | .with-search .summary li[data-level] a[href*=".html#"] { 30 | display: none; 31 | } 32 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/css/plugin-table.css: -------------------------------------------------------------------------------- 1 | .book .book-body .page-wrapper .page-inner section.normal table{display:table;width:100%;border-collapse:collapse;border-spacing:0;overflow:auto}.book .book-body .page-wrapper .page-inner section.normal table td,.book .book-body .page-wrapper .page-inner section.normal table th{padding:6px 13px;border:1px solid #ddd}.book .book-body .page-wrapper .page-inner section.normal table tr{background-color:#fff;border-top:1px solid #ccc}.book .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n){background-color:#f8f8f8}.book .book-body .page-wrapper .page-inner section.normal table th{font-weight:700} 2 | -------------------------------------------------------------------------------- /_book/libs/gitbook-2.6.7/js/plugin-clipboard.js: -------------------------------------------------------------------------------- 1 | gitbook.require(["gitbook", "jQuery"], function(gitbook, $) { 2 | 3 | var copyButton = ''; 4 | var clipboard; 5 | 6 | gitbook.events.bind("page.change", function() { 7 | 8 | if (!ClipboardJS.isSupported()) return; 9 | 10 | // the page.change event is thrown twice: before and after the page changes 11 | if (clipboard) { 12 | // clipboard is already defined 13 | // we can deduct that we are before page changes 14 | clipboard.destroy(); // destroy the previous events listeners 15 | clipboard = undefined; // reset the clipboard object 16 | return; 17 | } 18 | 19 | $(copyButton).prependTo("div.sourceCode"); 20 | 21 | clipboard = new ClipboardJS(".copy-to-clipboard-button", { 22 | text: function(trigger) { 23 | return trigger.parentNode.textContent; 24 | } 25 | }); 26 | 27 | }); 28 | 29 | }); 30 | -------------------------------------------------------------------------------- /_book/libs/gitbook/css/fontawesome/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/_book/libs/gitbook/css/fontawesome/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /_book/libs/gitbook/css/plugin-clipboard.css: -------------------------------------------------------------------------------- 1 | div.sourceCode { 2 | position: relative; 3 | } 4 | 5 | .copy-to-clipboard-button { 6 | position: absolute; 7 | right: 0; 8 | top: 0; 9 | visibility: hidden; 10 | } 11 | 12 | .copy-to-clipboard-button:focus { 13 | outline: 0; 14 | } 15 | 16 | div.sourceCode:hover > .copy-to-clipboard-button { 17 | visibility: visible; 18 | } 19 | -------------------------------------------------------------------------------- /_book/libs/gitbook/css/plugin-search.css: -------------------------------------------------------------------------------- 1 | .book .book-summary .book-search { 2 | padding: 6px; 3 | background: transparent; 4 | position: absolute; 5 | top: -50px; 6 | left: 0px; 7 | right: 0px; 8 | transition: top 0.5s ease; 9 | } 10 | .book .book-summary .book-search input, 11 | .book .book-summary .book-search input:focus, 12 | .book .book-summary .book-search input:hover { 13 | width: 100%; 14 | background: transparent; 15 | border: 1px solid #ccc; 16 | box-shadow: none; 17 | outline: none; 18 | line-height: 22px; 19 | padding: 7px 4px; 20 | color: inherit; 21 | box-sizing: border-box; 22 | } 23 | .book.with-search .book-summary .book-search { 24 | top: 0px; 25 | } 26 | .book.with-search .book-summary ul.summary { 27 | top: 50px; 28 | } 29 | .with-search .summary li[data-level] a[href*=".html#"] { 30 | display: none; 31 | } 32 | -------------------------------------------------------------------------------- /_book/libs/gitbook/css/plugin-table.css: -------------------------------------------------------------------------------- 1 | .book .book-body .page-wrapper .page-inner section.normal table{display:table;width:100%;border-collapse:collapse;border-spacing:0;overflow:auto}.book .book-body .page-wrapper .page-inner section.normal table td,.book .book-body .page-wrapper .page-inner section.normal table th{padding:6px 13px;border:1px solid #ddd}.book .book-body .page-wrapper .page-inner section.normal table tr{background-color:#fff;border-top:1px solid #ccc}.book .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n){background-color:#f8f8f8}.book .book-body .page-wrapper .page-inner section.normal table th{font-weight:700} 2 | -------------------------------------------------------------------------------- /_book/libs/gitbook/js/plugin-clipboard.js: -------------------------------------------------------------------------------- 1 | gitbook.require(["gitbook", "jQuery"], function(gitbook, $) { 2 | 3 | var copyButton = ''; 4 | var clipboard; 5 | 6 | gitbook.events.bind("page.change", function() { 7 | 8 | if (!ClipboardJS.isSupported()) return; 9 | 10 | // the page.change event is thrown twice: before and after the page changes 11 | if (clipboard) { 12 | // clipboard is already defined 13 | // we can deduct that we are before page changes 14 | clipboard.destroy(); // destroy the previous events listeners 15 | clipboard = undefined; // reset the clipboard object 16 | return; 17 | } 18 | 19 | $(copyButton).prependTo("div.sourceCode"); 20 | 21 | clipboard = new ClipboardJS(".copy-to-clipboard-button", { 22 | text: function(trigger) { 23 | return trigger.parentNode.textContent; 24 | } 25 | }); 26 | 27 | }); 28 | 29 | }); 30 | -------------------------------------------------------------------------------- /_book/libs/header-attrs-2.4/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /_book/libs/header-attrs-2.5/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /_book/libs/header-attrs-2.6/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /_book/libs/header-attrs/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /_book/libs/peity-binding/peity.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'peity', 4 | 5 | type: 'output', 6 | 7 | factory: function(el, width, height) { 8 | 9 | // TODO: define shared variables for this instance 10 | 11 | return { 12 | 13 | renderValue: function(x) { 14 | 15 | // TODO: code to render the widget, e.g. 16 | el.innerText = x.data; 17 | $(el).peity(x.type, x.options); 18 | 19 | }, 20 | 21 | resize: function(width, height) { 22 | 23 | // TODO: code to re-render the widget with a new size 24 | 25 | } 26 | 27 | }; 28 | } 29 | }); -------------------------------------------------------------------------------- /_book/libs/plotly-htmlwidgets-css-1.52.2/plotly-htmlwidgets.css: -------------------------------------------------------------------------------- 1 | /* 2 | just here so that plotly works 3 | correctly with ioslides. 4 | see https://github.com/ropensci/plotly/issues/463 5 | */ 6 | 7 | slide:not(.current) .plotly.html-widget{ 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /_book/libs/plotly-htmlwidgets-css-1.54.1/plotly-htmlwidgets.css: -------------------------------------------------------------------------------- 1 | /* 2 | just here so that plotly works 3 | correctly with ioslides. 4 | see https://github.com/ropensci/plotly/issues/463 5 | */ 6 | 7 | slide:not(.current) .plotly.html-widget{ 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /_book/libs/plotly-htmlwidgets-css-1.57.1/plotly-htmlwidgets.css: -------------------------------------------------------------------------------- 1 | /* 2 | just here so that plotly works 3 | correctly with ioslides. 4 | see https://github.com/ropensci/plotly/issues/463 5 | */ 6 | 7 | slide:not(.current) .plotly.html-widget{ 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /_book/libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css: -------------------------------------------------------------------------------- 1 | /* 2 | just here so that plotly works 3 | correctly with ioslides. 4 | see https://github.com/ropensci/plotly/issues/463 5 | */ 6 | 7 | slide:not(.current) .plotly.html-widget{ 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /_book/libs/r2d3-binding-0.2.3/r2d3.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | name: 'r2d3', 3 | type: 'output', 4 | factory: function(el, width, height) { 5 | 6 | var r2d3 = new R2D3(el, width, height); 7 | 8 | return { 9 | renderValue: function(x) { 10 | r2d3.widgetRender(x); 11 | }, 12 | 13 | resize: function(width, height) { 14 | r2d3.widgetResize(width, height); 15 | } 16 | }; 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /_book/libs/r2d3-binding-0.2.5/r2d3.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | name: 'r2d3', 3 | type: 'output', 4 | factory: function(el, width, height) { 5 | 6 | var r2d3 = new R2D3(el, width, height); 7 | 8 | return { 9 | renderValue: function(x) { 10 | r2d3.widgetRender(x); 11 | }, 12 | 13 | resize: function(width, height) { 14 | r2d3.widgetResize(width, height); 15 | } 16 | }; 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /_book/libs/r2d3-binding/r2d3.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | name: 'r2d3', 3 | type: 'output', 4 | factory: function(el, width, height) { 5 | 6 | var r2d3 = new R2D3(el, width, height); 7 | 8 | return { 9 | renderValue: function(x) { 10 | r2d3.widgetRender(x); 11 | }, 12 | 13 | resize: function(width, height) { 14 | r2d3.widgetResize(width, height); 15 | } 16 | }; 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /_bookdown.yml: -------------------------------------------------------------------------------- 1 | book_filename: bookdown 2 | clean: [packages.bib, bookdown.bbl] 3 | new_session: yes 4 | before_chapter_script: ["before.R"] 5 | delete_merged_file: true 6 | language: 7 | label: 8 | fig: "FIGURE " 9 | tab: "TABLE " 10 | ui: 11 | edit: "Edit" 12 | chapter_name: "Chapter " 13 | -------------------------------------------------------------------------------- /_bookdown_files/1-01-intro-introduction_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | rmapshaper 3 | ggplot2 4 | plotly 5 | V8 6 | -------------------------------------------------------------------------------- /_bookdown_files/1-01-intro-introduction_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | rmapshaper 3 | ggplot2 4 | plotly 5 | V8 6 | -------------------------------------------------------------------------------- /_bookdown_files/1-02-basics_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | jsonlite 3 | -------------------------------------------------------------------------------- /_bookdown_files/1-02-basics_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | jsonlite 3 | -------------------------------------------------------------------------------- /_bookdown_files/3-20-htmlwidgets-intro_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | ggplot2 3 | plotly 4 | -------------------------------------------------------------------------------- /_bookdown_files/3-20-htmlwidgets-intro_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | ggplot2 3 | plotly 4 | -------------------------------------------------------------------------------- /_bookdown_files/3-21-htmlwidgets-basics_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/3-21-htmlwidgets-basics_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/3-22-htmlwidgets-first_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/3-22-htmlwidgets-first_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/3-23-htmlwidgets-peity_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | peity 3 | -------------------------------------------------------------------------------- /_bookdown_files/3-23-htmlwidgets-peity_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | peity 3 | -------------------------------------------------------------------------------- /_bookdown_files/3-24-htmlwidgets-gio_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/3-24-htmlwidgets-gio_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/3-25-htmlwidgets-advanced_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/3-25-htmlwidgets-advanced_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/3-26-htmlwidgets-crosstalk_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | crosstalk 3 | -------------------------------------------------------------------------------- /_bookdown_files/3-26-htmlwidgets-crosstalk_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | crosstalk 3 | -------------------------------------------------------------------------------- /_bookdown_files/3-27-htmlwidgets-polish_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/3-27-htmlwidgets-polish_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-11-shiny-first-look_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-11-shiny-first-look_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-12-shiny-complete_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-12-shiny-complete_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-13-shiny-tips_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-13-shiny-tips_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-15-shiny-output_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-15-shiny-output_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-16-shiny-input_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-16-shiny-input_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-17-shiny-cookies_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-17-shiny-cookies_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-18-shiny-htmlwidgets_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/4-18-shiny-htmlwidgets_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/6-01-computations-v8_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | V8 3 | -------------------------------------------------------------------------------- /_bookdown_files/6-01-computations-v8_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | V8 3 | -------------------------------------------------------------------------------- /_bookdown_files/6-02-computations-ml_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | ml 3 | -------------------------------------------------------------------------------- /_bookdown_files/6-02-computations-ml_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | ml 3 | -------------------------------------------------------------------------------- /_bookdown_files/7-02-webpack-npm-discover_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/7-02-webpack-npm-discover_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/7-03-webpack-packer_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/7-03-webpack-packer_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/7-04-webpack-advanced_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/7-04-webpack-advanced_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | -------------------------------------------------------------------------------- /_bookdown_files/index_cache/html/__packages: -------------------------------------------------------------------------------- 1 | base 2 | DiagrammeRsvg 3 | knitr 4 | -------------------------------------------------------------------------------- /_bookdown_files/index_cache/latex/__packages: -------------------------------------------------------------------------------- 1 | base 2 | DiagrammeRsvg 3 | knitr 4 | -------------------------------------------------------------------------------- /_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | Rscript -e "setwd('./code/gio');devtools::install();" 4 | Rscript -e "setwd('./code/jbox');devtools::install();" 5 | Rscript -e "setwd('./code/ms');devtools::install();" 6 | Rscript -e "setwd('./code/playground');devtools::install();" 7 | Rscript -e "setwd('./code/typed');devtools::install();" 8 | Rscript -e "setwd('./code/peity');devtools::install();" 9 | Rscript -e "setwd('./code/playground');devtools::install();" 10 | Rscript -e "setwd('./code/ml5-pkg');devtools::install();" 11 | -------------------------------------------------------------------------------- /_output.yml: -------------------------------------------------------------------------------- 1 | bookdown::gitbook: 2 | css: [css/style.css, css/toc.css] 3 | config: 4 | toc: 5 | collapse: section 6 | before: | 7 |
  • JavaScript for R
  • 8 | edit: https://github.com/JohnCoene/javascript-for-r/edit/master/%s 9 | download: [] 10 | sharing: 11 | facebook: no 12 | twitter: no 13 | github: yes 14 | all: [] 15 | includes: 16 | in_header: [ga.html, social.html] 17 | bookdown::pdf_book: 18 | includes: 19 | in_header: latex/preamble.tex 20 | before_body: latex/before_body.tex 21 | after_body: latex/after_body.tex 22 | keep_tex: true 23 | dev: "cairo_pdf" 24 | latex_engine: xelatex 25 | citation_package: natbib 26 | template: null 27 | pandoc_args: --top-level-division=chapter 28 | toc_depth: 3 29 | toc_unnumbered: no 30 | toc_appendix: yes 31 | quote_footer: ["\\VA{", "}{}"] 32 | highlight_bw: yes 33 | bookdown::epub_book: 34 | stylesheet: css/style.css 35 | -------------------------------------------------------------------------------- /before.R: -------------------------------------------------------------------------------- 1 | library(methods) 2 | 3 | knitr::opts_chunk$set( 4 | comment = "#>", 5 | collapse = TRUE, 6 | cache = TRUE, 7 | fig.pos = "H", 8 | fig.align = 'center', 9 | fig.width = 6, 10 | fig.asp = 0.618, # 1 / phi 11 | fig.show = "hold", 12 | out.width = "100%" 13 | ) 14 | 15 | options(dplyr.print_min = 4, dplyr.print_max = 4) 16 | -------------------------------------------------------------------------------- /book.bib: -------------------------------------------------------------------------------- 1 | @Book{xie2015, 2 | title = {Dynamic Documents with {R} and knitr}, 3 | author = {Yihui Xie}, 4 | publisher = {Chapman and Hall/CRC}, 5 | address = {Boca Raton, Florida}, 6 | year = {2015}, 7 | edition = {2nd}, 8 | note = {ISBN 978-1498716963}, 9 | url = {http://yihui.name/knitr/}, 10 | } 11 | -------------------------------------------------------------------------------- /chord.js: -------------------------------------------------------------------------------- 1 | // !preview r2d3 data = matrix(round(runif(16, 1, 10000)), ncol = 4, nrow = 4) 2 | 3 | // Based on https://bl.ocks.org/mbostock/4062006 4 | 5 | var outerRadius = Math.min(width, height) * 0.5 - 40, 6 | innerRadius = outerRadius - 30; 7 | 8 | var formatValue = d3.formatPrefix(",.0", 1e3); 9 | 10 | var chord = d3.chord() 11 | .padAngle(0.05) 12 | .sortSubgroups(d3.descending); 13 | 14 | var arc = d3.arc() 15 | .innerRadius(innerRadius) 16 | .outerRadius(outerRadius); 17 | 18 | var ribbon = d3.ribbon() 19 | .radius(innerRadius); 20 | 21 | var color = d3.scaleOrdinal() 22 | .domain(d3.range(4)) 23 | .range(["#000000", "#FFDD89", "#957244", "#F26223"]); 24 | 25 | var g = svg.append("g") 26 | .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") 27 | .datum(chord(data)); 28 | 29 | var group = g.append("g") 30 | .attr("class", "groups") 31 | .selectAll("g") 32 | .data(function(chords) { return chords.groups; }) 33 | .enter().append("g"); 34 | 35 | group.append("path") 36 | .style("fill", function(d) { return color(d.index); }) 37 | .style("stroke", function(d) { return d3.rgb(color(d.index)).darker(); }) 38 | .attr("d", arc); 39 | 40 | var groupTick = group.selectAll(".group-tick") 41 | .data(function(d) { return groupTicks(d, 1e3); }) 42 | .enter().append("g") 43 | .attr("class", "group-tick") 44 | .attr("transform", function(d) { return "rotate(" + (d.angle * 180 / Math.PI - 90) + ") translate(" + outerRadius + ",0)"; }); 45 | 46 | groupTick.append("line") 47 | .attr("x2", 6); 48 | 49 | groupTick 50 | .filter(function(d) { return d.value % 5e3 === 0; }) 51 | .append("text") 52 | .attr("x", 8) 53 | .attr("dy", ".35em") 54 | .attr("transform", function(d) { return d.angle > Math.PI ? "rotate(180) translate(-16)" : null; }) 55 | .style("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; }) 56 | .text(function(d) { return formatValue(d.value); }); 57 | 58 | g.append("g") 59 | .attr("class", "ribbons") 60 | .selectAll("path") 61 | .data(function(chords) { return chords; }) 62 | .enter().append("path") 63 | .attr("d", ribbon) 64 | .style("fill", function(d) { return color(d.target.index); }) 65 | .style("stroke", function(d) { return d3.rgb(color(d.target.index)).darker(); }); 66 | 67 | // Returns an array of tick angles and values for a given group and step. 68 | function groupTicks(d, step) { 69 | var k = (d.endAngle - d.startAngle) / d.value; 70 | return d3.range(0, d.value, step).map(function(value) { 71 | return {value: value, angle: value * k + d.startAngle}; 72 | }); 73 | } 74 | -------------------------------------------------------------------------------- /code/README.md: -------------------------------------------------------------------------------- 1 | # Code 2 | 3 | This includes all the code written in the book, all the examples and more. 4 | 5 | [Website](https://javascript-for-r.com) 6 | -------------------------------------------------------------------------------- /code/boxxy/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | boxxy <- function(title, value, color = NULL, animate = TRUE){ 4 | 5 | value <- sum(value) 6 | 7 | # dynamic color 8 | if(is.null(color)) 9 | if(value > 100) 10 | color <- "#ef476f" 11 | else 12 | color <- "#06d6a0" 13 | 14 | list(title = title, value = value, color = color, animate = animate) 15 | } 16 | 17 | boxxyOutput <- function(id){ 18 | el <- shiny::tags$div( 19 | id = id, class = "boxxy", 20 | h1(id = sprintf("%s-boxxy-value", id), class = "boxxy-value"), 21 | p(id = sprintf("%s-boxxy-title", id), class = "boxxy-title") 22 | ) 23 | 24 | path <- normalizePath("assets") 25 | 26 | deps <- list( 27 | htmltools::htmlDependency( 28 | name = "boxxy", 29 | version = "1.0.0", 30 | src = c(file = path), 31 | script = c("binding.js"), # only binding 32 | stylesheet = "styles.css" 33 | ) 34 | ) 35 | 36 | htmltools::attachDependencies(el, deps) 37 | } 38 | 39 | renderBoxxy <- function(expr, env = parent.frame(), quoted = FALSE) { 40 | # Convert the expression + environment into a function 41 | func <- shiny::exprToFunction(expr, env, quoted) 42 | 43 | function(){ 44 | val <- func() 45 | 46 | if(val$animate){ 47 | path <- normalizePath("assets") 48 | 49 | deps <- htmltools::htmlDependency( 50 | name = "countup", 51 | version = "1.8.2", 52 | src = c(file = path), 53 | script = c("countup.js") # only countup 54 | ) 55 | 56 | val$deps <- lapply( 57 | htmltools::resolveDependencies(list(deps)), 58 | shiny::createWebDependency 59 | ) 60 | } 61 | 62 | return(val) 63 | } 64 | } 65 | 66 | ui <- fluidPage( 67 | h2("Custom outputs"), 68 | fluidRow( 69 | column( 70 | 3, boxxyOutput("countries") 71 | ), 72 | column( 73 | 3, boxxyOutput("employees") 74 | ), 75 | column( 76 | 3, boxxyOutput("customers") 77 | ), 78 | column( 79 | 3, boxxyOutput("subs") 80 | ) 81 | ) 82 | ) 83 | 84 | server <- function(input, output){ 85 | output$countries <- renderBoxxy({ 86 | boxxy("Countries", 95, color = "#ef476f", animate = FALSE) 87 | }) 88 | 89 | output$employees <- renderBoxxy({ 90 | boxxy("Thing", 650, color = "#06d6a0") 91 | }) 92 | 93 | output$customers <- renderBoxxy({ 94 | boxxy("Customers", 13592, color = "#118ab2") 95 | }) 96 | 97 | output$subs <- renderBoxxy({ 98 | boxxy("Subscriptions", 16719, color = "#ffd166") 99 | }) 100 | } 101 | 102 | shinyApp(ui, server) -------------------------------------------------------------------------------- /code/boxxy/assets/binding.js: -------------------------------------------------------------------------------- 1 | var boxxyBinding = new Shiny.OutputBinding(); 2 | 3 | $.extend(boxxyBinding, { 4 | find: function(scope) { 5 | return $(scope).find(".boxxy"); 6 | }, 7 | renderValue: function(el, data) { 8 | 9 | el.style.backgroundColor = data.color; 10 | 11 | if(data.animate){ 12 | Shiny.renderDependencies(data.deps); 13 | var counter = new CountUp(el.id + '-boxxy-value', 0, data.value); 14 | counter.start(); 15 | } else { 16 | document.getElementById(el.id + '-boxxy-value').innerText = data.value; 17 | } 18 | 19 | document.getElementById(el.id + '-boxxy-title').innerText = data.title; 20 | } 21 | }); 22 | 23 | Shiny.outputBindings.register(boxxyBinding, "john.boxxy"); -------------------------------------------------------------------------------- /code/boxxy/assets/styles.css: -------------------------------------------------------------------------------- 1 | .boxxy{ 2 | text-align: center; 3 | border-left: 6px solid #073b4c; 4 | padding: 1em; 5 | } 6 | 7 | .boxxy-title{ 8 | text-transform: uppercase; 9 | } 10 | 11 | .boxxy-value{ 12 | font-size: 3em; 13 | } -------------------------------------------------------------------------------- /code/candidate-libraries/README.md: -------------------------------------------------------------------------------- 1 | # Candidate Libraries 2 | 3 | Example code used to showcase candidate libraries in the book. 4 | -------------------------------------------------------------------------------- /code/candidate-libraries/chartjs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /code/candidate-libraries/highcharts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 | 13 | 14 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /code/candidate-libraries/plotly.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 | 13 | 14 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/cookies/README.md: -------------------------------------------------------------------------------- 1 | # Cookies 2 | 3 | Using cookies to store user data in the browser. 4 | 5 | ```r 6 | library(shiny) 7 | 8 | addResourcePath("www", "www") 9 | 10 | ui <- fluidPage( 11 | tags$head( 12 | tags$script( 13 | src = "https://cdn.jsdelivr.net/npm/js-cookie@rc/dist/js.cookie.min.js" 14 | ), 15 | tags$script(src = "www/script.js") 16 | ), 17 | textInput("name_set", "What is your name?"), 18 | actionButton("save", "Save cookie"), 19 | actionButton("remove", "remove cookie"), 20 | uiOutput("name_get") 21 | ) 22 | 23 | server <- function(input, output, session){ 24 | 25 | # save 26 | observeEvent(input$save, { 27 | if(input$name_set != "") 28 | session$sendCustomMessage("cookie-set", list(name = "name", value = input$name_set)) 29 | }) 30 | 31 | # delete 32 | observeEvent(input$remove, { 33 | session$sendCustomMessage("cookie-remove", list(name = "name")) 34 | }) 35 | 36 | # output if cookie is specified 37 | output$name_get <- renderUI({ 38 | if(!is.null(input$cookies$name)) 39 | h3("Hello,", input$cookies$name) 40 | else 41 | h3("Who are you?") 42 | }) 43 | 44 | } 45 | 46 | shinyApp(ui, server) 47 | ``` 48 | -------------------------------------------------------------------------------- /code/cookies/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | addResourcePath("www", "www") 4 | 5 | ui <- fluidPage( 6 | tags$head( 7 | tags$script( 8 | src = "https://cdn.jsdelivr.net/npm/js-cookie@rc/dist/js.cookie.min.js" 9 | ), 10 | tags$script(src = "www/script.js") 11 | ), 12 | textInput("name_set", "What is your name?"), 13 | actionButton("save", "Save cookie"), 14 | actionButton("remove", "remove cookie"), 15 | uiOutput("name_get") 16 | ) 17 | 18 | server <- function(input, output, session){ 19 | 20 | # save 21 | observeEvent(input$save, { 22 | if(input$name_set != "") 23 | session$sendCustomMessage("cookie-set", list(name = "name", value = input$name_set)) 24 | }) 25 | 26 | # delete 27 | observeEvent(input$remove, { 28 | session$sendCustomMessage("cookie-remove", list(name = "name")) 29 | }) 30 | 31 | # output if cookie is specified 32 | output$name_get <- renderUI({ 33 | if(!is.null(input$cookies$name)) 34 | h3("Hello,", input$cookies$name) 35 | else 36 | h3("Who are you?") 37 | }) 38 | 39 | } 40 | 41 | shinyApp(ui, server) -------------------------------------------------------------------------------- /code/cookies/www/script.js: -------------------------------------------------------------------------------- 1 | function getCookies(){ 2 | let res = Cookies.get(); 3 | Shiny.setInputValue('cookies', res); 4 | } 5 | 6 | Shiny.addCustomMessageHandler('cookie-set', function(msg){ 7 | Cookies.set(msg.name, msg.value); 8 | getCookies(); 9 | }) 10 | 11 | Shiny.addCustomMessageHandler('cookie-remove', function(msg){ 12 | Cookies.remove(msg.name); 13 | getCookies(); 14 | }) 15 | 16 | $(document).on('shiny:connected', function(ev){ 17 | getCookies(); 18 | }) 19 | 20 | -------------------------------------------------------------------------------- /code/counter/.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^srcjs$ 2 | ^node_modules$ 3 | ^package\.json$ 4 | ^package-lock\.json$ 5 | ^webpack\.dev\.js$ 6 | ^webpack\.prod\.js$ 7 | ^webpack\.common\.js$ 8 | -------------------------------------------------------------------------------- /code/counter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /code/counter/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: counter 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "First", 6 | family = "Last", 7 | role = c("aut", "cre"), 8 | email = "first.last@example.com", 9 | comment = c(ORCID = "YOUR-ORCID-ID")) 10 | Description: What the package does (one paragraph). 11 | License: `use_mit_license()`, `use_gpl3_license()` or friends to 12 | pick a license 13 | Encoding: UTF-8 14 | LazyData: true 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.1.1.9000 17 | Imports: 18 | htmlwidgets 19 | -------------------------------------------------------------------------------- /code/counter/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(countup) 4 | export(countupOutput) 5 | export(renderCountup) 6 | import(htmlwidgets) 7 | -------------------------------------------------------------------------------- /code/counter/R/countup.R: -------------------------------------------------------------------------------- 1 | #' 2 | #' 3 | #' 4 | #' 5 | #' @import htmlwidgets 6 | #' 7 | #' @export 8 | countup <- function(message, ms = 2000, width = NULL, height = NULL, elementId = NULL) { 9 | 10 | # forward options using x 11 | x = list( 12 | message = message 13 | ) 14 | 15 | # create widget 16 | htmlwidgets::createWidget( 17 | name = 'countup', 18 | x, 19 | width = width, 20 | height = height, 21 | package = 'counter', 22 | elementId = elementId 23 | ) 24 | } 25 | 26 | #' Shiny bindings for countup 27 | #' 28 | #' Output and render functions for using countup within Shiny 29 | #' applications and interactive Rmd documents. 30 | #' 31 | #' @param outputId output variable to read from 32 | #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, 33 | #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 34 | #' string and have \code{'px'} appended. 35 | #' @param expr An expression that generates a countup 36 | #' @param env The environment in which to evaluate \code{expr}. 37 | #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This 38 | #' is useful if you want to save an expression in a variable. 39 | #' 40 | #' @name countup-shiny 41 | #' 42 | #' @export 43 | countupOutput <- function(outputId, width = '100%', height = '400px'){ 44 | htmlwidgets::shinyWidgetOutput(outputId, 'countup', width, height, package = 'counter') 45 | } 46 | 47 | #' @rdname countup-shiny 48 | #' @export 49 | renderCountup <- function(expr, env = parent.frame(), quoted = FALSE) { 50 | if (!quoted) { expr <- substitute(expr) } # force quoted 51 | htmlwidgets::shinyRenderWidget(expr, countupOutput, env, quoted = TRUE) 52 | } 53 | -------------------------------------------------------------------------------- /code/counter/inst/htmlwidgets/countup.yaml: -------------------------------------------------------------------------------- 1 | # (uncomment to add a dependency) 2 | # dependencies: 3 | # - name: 4 | # version: 5 | # src: 6 | # script: 7 | # stylesheet: 8 | -------------------------------------------------------------------------------- /code/counter/man/countup-shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/countup.R 3 | \name{countup-shiny} 4 | \alias{countup-shiny} 5 | \alias{countupOutput} 6 | \alias{renderCountup} 7 | \title{Shiny bindings for countup} 8 | \usage{ 9 | countupOutput(outputId, width = "100\%", height = "400px") 10 | 11 | renderCountup(expr, env = parent.frame(), quoted = FALSE) 12 | } 13 | \arguments{ 14 | \item{outputId}{output variable to read from} 15 | 16 | \item{width, height}{Must be a valid CSS unit (like \code{'100\%'}, 17 | \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 18 | string and have \code{'px'} appended.} 19 | 20 | \item{expr}{An expression that generates a countup} 21 | 22 | \item{env}{The environment in which to evaluate \code{expr}.} 23 | 24 | \item{quoted}{Is \code{expr} a quoted expression (with \code{quote()})? This 25 | is useful if you want to save an expression in a variable.} 26 | } 27 | \description{ 28 | Output and render functions for using countup within Shiny 29 | applications and interactive Rmd documents. 30 | } 31 | -------------------------------------------------------------------------------- /code/counter/man/countup.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/countup.R 3 | \name{countup} 4 | \alias{countup} 5 | \title{} 6 | \usage{ 7 | countup(value, ms = 2000, width = NULL, height = NULL, elementId = NULL) 8 | } 9 | \description{ 10 | 11 | } 12 | -------------------------------------------------------------------------------- /code/counter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "counter", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "none": "webpack --config webpack.dev.js --mode=none", 9 | "development": "webpack --config webpack.dev.js", 10 | "production": "webpack --config webpack.prod.js", 11 | "watch": "webpack --config webpack.config.js -d --watch" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "devDependencies": { 17 | "webpack": "^5.3.0", 18 | "webpack-cli": "^4.1.0", 19 | "webpack-merge": "^5.2.0" 20 | }, 21 | "dependencies": { 22 | "countup": "^1.8.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /code/counter/srcjs/config/entry_points.json: -------------------------------------------------------------------------------- 1 | { 2 | "countup": "./srcjs/widgets/countup.js" 3 | } 4 | -------------------------------------------------------------------------------- /code/counter/srcjs/config/externals.json: -------------------------------------------------------------------------------- 1 | { 2 | "widgets": "HTMLWidgets", 3 | "2": "Shiny", 4 | "3": "jQuery" 5 | } 6 | -------------------------------------------------------------------------------- /code/counter/srcjs/config/loaders.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /code/counter/srcjs/config/misc.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /code/counter/srcjs/config/output_path.json: -------------------------------------------------------------------------------- 1 | "./inst/htmlwidgets" 2 | -------------------------------------------------------------------------------- /code/counter/srcjs/index.js: -------------------------------------------------------------------------------- 1 | import './widgets/countup.js' 2 | -------------------------------------------------------------------------------- /code/counter/srcjs/modules/count.js: -------------------------------------------------------------------------------- 1 | import { CountUp } from 'countup.js'; 2 | 3 | function counter(id, value){ 4 | var countUp = new CountUp(id, value); 5 | countUp.start(); 6 | } 7 | 8 | export { counter }; 9 | -------------------------------------------------------------------------------- /code/counter/srcjs/widgets/countup.js: -------------------------------------------------------------------------------- 1 | import 'widgets'; 2 | import { counter } from '../modules/count.js'; 3 | 4 | HTMLWidgets.widget({ 5 | 6 | name: 'countup', 7 | 8 | type: 'output', 9 | 10 | factory: function(el, width, height) { 11 | 12 | // TODO: define shared variables for this instance 13 | 14 | return { 15 | 16 | renderValue: function(x) { 17 | 18 | counter(el.id, x.message); 19 | 20 | }, 21 | 22 | resize: function(width, height) { 23 | 24 | // TODO: code to re-render the widget with a new size 25 | 26 | } 27 | 28 | }; 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /code/counter/webpack.common.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | 4 | // Read config files 5 | var outputPath = fs.readFileSync('./srcjs/config/output_path.json'); 6 | var entryPoints = fs.readFileSync('./srcjs/config/entry_points.json'); 7 | var externals = fs.readFileSync('./srcjs/config/externals.json'); 8 | var misc = fs.readFileSync('./srcjs/config/misc.json'); 9 | var loaders = fs.readFileSync('./srcjs/config/loaders.json', 'utf8'); 10 | 11 | // parse 12 | loaders = JSON.parse(loaders); 13 | misc = JSON.parse(misc); 14 | externals = JSON.parse(externals); 15 | entryPoints = JSON.parse(entryPoints); 16 | 17 | // parse regex 18 | loaders.forEach((loader) => { 19 | loader.test = RegExp(loader.test); 20 | return(loader); 21 | }) 22 | 23 | // placeholder for plugins 24 | var plugins = [ 25 | ]; 26 | 27 | // define options 28 | var options = { 29 | entry: entryPoints, 30 | output: { 31 | filename: '[name].js', 32 | path: path.resolve(__dirname, JSON.parse(outputPath)), 33 | }, 34 | externals: externals, 35 | module: { 36 | rules: loaders 37 | }, 38 | plugins: plugins 39 | }; 40 | 41 | // add misc 42 | if(misc.resolve) 43 | options.resolve = misc.resolve; 44 | 45 | // export 46 | module.exports = options; 47 | -------------------------------------------------------------------------------- /code/counter/webpack.dev.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'development', 6 | devtool: 'inline-source-map' 7 | }); 8 | -------------------------------------------------------------------------------- /code/counter/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'production', 6 | }); 7 | -------------------------------------------------------------------------------- /code/events/README.md: -------------------------------------------------------------------------------- 1 | # Events 2 | 3 | Leverage shiny events to show a busy indicator. 4 | 5 | ```r 6 | library(shiny) 7 | 8 | shiny::addResourcePath("www", "www") 9 | 10 | ui <- fluidPage( 11 | tags$head( 12 | tags$link(href = "www/style.css", rel = "stylesheet"), 13 | tags$script(src = "www/script.js") 14 | ), 15 | tags$img(src = "www/typing.gif", id = "loading"), 16 | plotOutput("plot"), 17 | actionButton("render", "render") 18 | ) 19 | 20 | server <- function(input, output, session) { 21 | output$plot <- renderPlot({ 22 | input$render 23 | Sys.sleep(10) 24 | plot(cars) 25 | }) 26 | } 27 | 28 | shinyApp(ui, server) 29 | ``` 30 | -------------------------------------------------------------------------------- /code/events/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | shiny::addResourcePath("www", "www") 4 | 5 | ui <- fluidPage( 6 | tags$head( 7 | tags$link(href = "www/style.css", rel = "stylesheet"), 8 | tags$script(src = "www/script.js") 9 | ), 10 | tags$img(src = "www/typing.gif", id = "loading"), 11 | plotOutput("plot"), 12 | actionButton("render", "render") 13 | ) 14 | 15 | server <- function(input, output, session) { 16 | output$plot <- renderPlot({ 17 | input$render 18 | Sys.sleep(10) 19 | plot(cars) 20 | }) 21 | } 22 | 23 | shinyApp(ui, server) 24 | -------------------------------------------------------------------------------- /code/events/www/script.js: -------------------------------------------------------------------------------- 1 | // script.js 2 | $(document).on('shiny:busy', function(event) { 3 | var gif = document.getElementById("loading"); 4 | gif.style.visibility = "visible"; 5 | }); 6 | 7 | $(document).on('shiny:idle', function(event) { 8 | var gif = document.getElementById("loading"); 9 | gif.style.visibility = "hidden"; 10 | }); -------------------------------------------------------------------------------- /code/events/www/style.css: -------------------------------------------------------------------------------- 1 | /* style.css */ 2 | #loading{ 3 | top: 20px; 4 | right: 20px; 5 | height: 200px; 6 | z-index: 9999; 7 | position: absolute; 8 | visibility: hidden; 9 | } -------------------------------------------------------------------------------- /code/events/www/typing.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/events/www/typing.gif -------------------------------------------------------------------------------- /code/gio/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: gio 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "First", 6 | family = "Last", 7 | role = c("aut", "cre"), 8 | email = "first.last@example.com", 9 | comment = c(ORCID = "YOUR-ORCID-ID")) 10 | Description: What the package does (one paragraph). 11 | License: `use_mit_license()`, `use_gpl3_license()` or friends to 12 | pick a license 13 | Encoding: UTF-8 14 | LazyData: true 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.1.1 17 | Imports: 18 | htmlwidgets, 19 | magrittr, 20 | htmltools, 21 | crosstalk, 22 | dplyr, 23 | shiny, 24 | purrr 25 | -------------------------------------------------------------------------------- /code/gio/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export("%>%") 4 | export(gio) 5 | export(gioOutput) 6 | export(gio_clear_data) 7 | export(gio_proxy) 8 | export(gio_send_data) 9 | export(gio_set_style) 10 | export(gio_stats) 11 | export(gio_style) 12 | export(gio_title) 13 | export(renderGio) 14 | import(htmlwidgets) 15 | importFrom(magrittr,"%>%") 16 | -------------------------------------------------------------------------------- /code/gio/R/gio.R: -------------------------------------------------------------------------------- 1 | #' Initialise globe 2 | #' 3 | #' Create the gio globe. 4 | #' 5 | #' @import htmlwidgets 6 | #' 7 | #' @export 8 | gio <- function(data, source, target, value, ..., width = NULL, height = NULL, elementId = NULL) { 9 | 10 | # defaults to NULL 11 | group <- NULL 12 | 13 | if (crosstalk::is.SharedData(data)) { 14 | group <- data$groupName() 15 | data <- data$origData() 16 | } 17 | 18 | data <- dplyr::select( 19 | data, 20 | i = {{ source }}, 21 | e = {{ target }}, 22 | v = {{ value }} 23 | ) 24 | 25 | # forward options using x 26 | x = list( 27 | configs = list(...), 28 | data = data, 29 | style = "default", 30 | crosstalk = list(group = group) 31 | ) 32 | 33 | attr(x, 'TOJSON_ARGS') <- list(dataframe = "rows") 34 | 35 | # create widget 36 | htmlwidgets::createWidget( 37 | name = 'gio', 38 | x, 39 | width = width, 40 | height = height, 41 | package = 'gio', 42 | elementId = elementId, 43 | sizingPolicy = htmlwidgets::sizingPolicy( 44 | padding = 0, 45 | browser.fill = TRUE, 46 | defaultWidth = "100%" 47 | ), 48 | preRenderHook = render_gio, 49 | dependencies = crosstalk::crosstalkLibs() 50 | ) 51 | } 52 | 53 | render_gio <- function(g){ 54 | g$x$data <- g$x$data[,c("e", "v", "i")] 55 | return(g) 56 | } 57 | 58 | #' Shiny bindings for gio 59 | #' 60 | #' Output and render functions for using gio within Shiny 61 | #' applications and interactive Rmd documents. 62 | #' 63 | #' @param outputId output variable to read from 64 | #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, 65 | #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 66 | #' string and have \code{'px'} appended. 67 | #' @param expr An expression that generates a gio 68 | #' @param env The environment in which to evaluate \code{expr}. 69 | #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This 70 | #' is useful if you want to save an expression in a variable. 71 | #' 72 | #' @name gio-shiny 73 | #' 74 | #' @export 75 | gioOutput <- function(outputId, width = '100%', height = '400px'){ 76 | htmlwidgets::shinyWidgetOutput(outputId, 'gio', width, height, package = 'gio') 77 | } 78 | 79 | #' @rdname gio-shiny 80 | #' @export 81 | renderGio <- function(expr, env = parent.frame(), quoted = FALSE) { 82 | if (!quoted) { expr <- substitute(expr) } # force quoted 83 | htmlwidgets::shinyRenderWidget(expr, gioOutput, env, quoted = TRUE) 84 | } 85 | -------------------------------------------------------------------------------- /code/gio/R/handler.R: -------------------------------------------------------------------------------- 1 | # reshape input data 2 | related_countries_handler <- function(x, session, inputname){ 3 | purrr::map_dfr(x, as.data.frame) 4 | } -------------------------------------------------------------------------------- /code/gio/R/proxy.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | gio_proxy <- function(id, session = shiny::getDefaultReactiveDomain()){ 3 | list(id = id, session = session) 4 | } 5 | 6 | #' @export 7 | gio_send_data <- function(proxy, data, source, target, value){ 8 | data <- dplyr::select( 9 | data, 10 | i = {{ source }}, 11 | e = {{ target }}, 12 | v = {{ value }} 13 | ) 14 | 15 | message <- list(id = proxy$id, data = apply(data, 1, as.list)) 16 | proxy$session$sendCustomMessage("send-data", message) 17 | return(proxy) 18 | } 19 | 20 | #' @export 21 | gio_clear_data <- function(proxy){ 22 | message <- list(id = proxy$id) 23 | proxy$session$sendCustomMessage("clear-data", message) 24 | return(proxy) 25 | } 26 | 27 | #' @export 28 | gio_set_style <- function(proxy, style){ 29 | message <- list(id = proxy$id, style = style) 30 | proxy$session$sendCustomMessage("set-style", message) 31 | return(proxy) 32 | } -------------------------------------------------------------------------------- /code/gio/R/stats.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | gio_stats <- function(g){ 3 | # add dependency 4 | path <- system.file("htmlwidgets/stats", package = "gio") 5 | dep <- htmltools::htmlDependency( 6 | name = "stats", 7 | version = "17", 8 | src = c(file = path), 9 | script = "stats.min.js" 10 | ) 11 | 12 | g$dependencies <- append(g$dependencies, list(dep)) 13 | 14 | g$x$stats <- TRUE 15 | 16 | return(g) 17 | } -------------------------------------------------------------------------------- /code/gio/R/style.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | gio_style <- function(g, style = "magic"){ 3 | g$x$style <- style 4 | return(g) 5 | } -------------------------------------------------------------------------------- /code/gio/R/title.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | gio_title <- function(g, title){ 3 | title <- htmltools::h3(title) 4 | htmlwidgets::prependContent(g, title) 5 | } -------------------------------------------------------------------------------- /code/gio/R/utils-pipe.R: -------------------------------------------------------------------------------- 1 | #' Pipe operator 2 | #' 3 | #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 4 | #' 5 | #' @name %>% 6 | #' @rdname pipe 7 | #' @keywords internal 8 | #' @export 9 | #' @importFrom magrittr %>% 10 | #' @usage lhs \%>\% rhs 11 | NULL 12 | -------------------------------------------------------------------------------- /code/gio/R/zzz.R: -------------------------------------------------------------------------------- 1 | # R/zzz.R 2 | .onLoad <- function(libname, pkgname) { 3 | shiny::registerInputHandler("gio.related.countries", related_countries_handler, force = TRUE) 4 | } -------------------------------------------------------------------------------- /code/gio/README.md: -------------------------------------------------------------------------------- 1 | 2 | # gio 3 | 4 | Code put together for the gio package, includes every chapter from start to finish 5 | 6 | ## Example 7 | 8 | ``` r 9 | arcs <- jsonlite::fromJSON("../../data/countries.json") 10 | 11 | gio::gio(arcs) 12 | ``` 13 | 14 | -------------------------------------------------------------------------------- /code/gio/inst/htmlwidgets/gio.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'gio', 4 | 5 | type: 'output', 6 | 7 | factory: function(el, width, height) { 8 | 9 | // TODO: define shared variables for this instance 10 | var controller; 11 | 12 | // selection handle 13 | var sel_handle = new crosstalk.SelectionHandle(); 14 | 15 | sel_handle.on("change", function(e) { 16 | if (e.sender !== sel_handle) { 17 | // clear selection 18 | } 19 | controller.switchCountry(e.value[0]); 20 | }); 21 | 22 | 23 | return { 24 | 25 | renderValue: function(x) { 26 | 27 | el.innerHTML = ''; 28 | controller = new GIO.Controller(el, x.configs); 29 | 30 | // group 31 | sel_handle.setGroup(x.crosstalk.group); 32 | 33 | // add data 34 | controller.addData(x.data); 35 | 36 | controller.setStyle(x.style); 37 | 38 | // callback 39 | controller.onCountryPicked(callback); 40 | 41 | function callback (selectedCountry, relatedCountries) { 42 | sel_handle.set([selectedCountry.ISOCode]); 43 | Shiny.setInputValue(el.id + '_selected', selectedCountry); 44 | Shiny.setInputValue(el.id + '_related:gio.related.countries', relatedCountries); 45 | } 46 | 47 | // use stats 48 | if(x.stats) 49 | controller.enableStats(); 50 | 51 | // render 52 | controller.init(); 53 | 54 | }, 55 | 56 | resize: function(width, height) { 57 | 58 | // TODO: code to re-render the widget with a new size 59 | controller.resizeUpdate() 60 | 61 | }, 62 | 63 | getGlobe: function(){ 64 | return controller; 65 | } 66 | 67 | }; 68 | } 69 | }); 70 | 71 | // retrieve widget 72 | function get_gio(id){ 73 | var widget = HTMLWidgets.find("#" + id); 74 | var globe = widget.getGlobe(); 75 | return globe; 76 | } 77 | 78 | // check if shiny running 79 | if (HTMLWidgets.shinyMode){ 80 | 81 | // send-data message handler 82 | Shiny.addCustomMessageHandler(type = 'send-data', function(message) { 83 | var controller = get_gio(message.id); 84 | controller.addData(message.data); 85 | }); 86 | 87 | // clear data message handler 88 | Shiny.addCustomMessageHandler(type = 'clear-data', function(message) { 89 | var controller = get_gio(message.id); 90 | controller.clearData(); 91 | }); 92 | 93 | // set style message handler 94 | Shiny.addCustomMessageHandler(type = 'set-style', function(message) { 95 | var controller = get_gio(message.id); 96 | controller.setStyle(message.style); 97 | controller.update(); 98 | }); 99 | 100 | } 101 | -------------------------------------------------------------------------------- /code/gio/inst/htmlwidgets/gio.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: three 3 | version: 110 4 | src: htmlwidgets/three 5 | script: three.min.js 6 | - name: gio 7 | version: 2.0 8 | src: htmlwidgets/gio 9 | script: gio.min.js 10 | -------------------------------------------------------------------------------- /code/gio/inst/htmlwidgets/stats/stats.min.js: -------------------------------------------------------------------------------- 1 | // stats.js - http://github.com/mrdoob/stats.js 2 | (function(f,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"===typeof define&&define.amd?define(e):f.Stats=e()})(this,function(){var f=function(){function e(a){c.appendChild(a.dom);return a}function u(a){for(var d=0;d=g+1E3&&(r.update(1E3*a/(c-g),100),g=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/ 4 | 1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){k=this.end()},domElement:c,setMode:u}};f.Panel=function(e,f,l){var c=Infinity,k=0,g=Math.round,a=g(window.devicePixelRatio||1),r=80*a,h=48*a,t=3*a,v=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=h;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,h);b.fillStyle=f;b.fillText(e,t,v); 5 | b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(h,w){c=Math.min(c,h);k=Math.max(k,h);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=f;b.fillText(g(h)+" "+e+" ("+g(c)+"-"+g(k)+")",t,v);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,g((1-h/w)*p))}}};return f}); -------------------------------------------------------------------------------- /code/gio/man/gio-shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/gio.R 3 | \name{gio-shiny} 4 | \alias{gio-shiny} 5 | \alias{gioOutput} 6 | \alias{renderGio} 7 | \title{Shiny bindings for gio} 8 | \usage{ 9 | gioOutput(outputId, width = "100\%", height = "400px") 10 | 11 | renderGio(expr, env = parent.frame(), quoted = FALSE) 12 | } 13 | \arguments{ 14 | \item{outputId}{output variable to read from} 15 | 16 | \item{width, height}{Must be a valid CSS unit (like \code{'100\%'}, 17 | \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 18 | string and have \code{'px'} appended.} 19 | 20 | \item{expr}{An expression that generates a gio} 21 | 22 | \item{env}{The environment in which to evaluate \code{expr}.} 23 | 24 | \item{quoted}{Is \code{expr} a quoted expression (with \code{quote()})? This 25 | is useful if you want to save an expression in a variable.} 26 | } 27 | \description{ 28 | Output and render functions for using gio within Shiny 29 | applications and interactive Rmd documents. 30 | } 31 | -------------------------------------------------------------------------------- /code/gio/man/gio.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/gio.R 3 | \name{gio} 4 | \alias{gio} 5 | \title{Initialise globe} 6 | \usage{ 7 | gio( 8 | data, 9 | source, 10 | target, 11 | value, 12 | ..., 13 | width = NULL, 14 | height = NULL, 15 | elementId = NULL 16 | ) 17 | } 18 | \description{ 19 | Create the gio globe. 20 | } 21 | -------------------------------------------------------------------------------- /code/gio/man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils-pipe.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \description{ 10 | See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /code/increment/.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^srcjs$ 2 | ^node_modules$ 3 | ^package\.json$ 4 | ^package-lock\.json$ 5 | ^webpack\.dev\.js$ 6 | ^webpack\.prod\.js$ 7 | ^webpack\.common\.js$ 8 | -------------------------------------------------------------------------------- /code/increment/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /code/increment/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: increment 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "First", 6 | family = "Last", 7 | role = c("aut", "cre"), 8 | email = "first.last@example.com", 9 | comment = c(ORCID = "YOUR-ORCID-ID")) 10 | Description: What the package does (one paragraph). 11 | License: `use_mit_license()`, `use_gpl3_license()` or friends to 12 | pick a license 13 | Encoding: UTF-8 14 | LazyData: true 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.1.1.9000 17 | Imports: 18 | shiny, 19 | htmltools 20 | -------------------------------------------------------------------------------- /code/increment/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | -------------------------------------------------------------------------------- /code/increment/R/increment.R: -------------------------------------------------------------------------------- 1 | #' increment 2 | #' 3 | #' Incremental button. 4 | #' 5 | #' @param inputId Id of input. 6 | #' @param value Initial value. 7 | #' 8 | #' @examples 9 | #' library(shiny) 10 | #' 11 | #' ui <- fluidPage( 12 | #' incrementInput("theId", 0) 13 | #' ) 14 | #' 15 | #' server <- function(input, output){ 16 | #' 17 | #' observeEvent(input$theId, { 18 | #' print(input$theId) 19 | #' }) 20 | #' 21 | #' } 22 | #' 23 | #' if(interactive()) 24 | #' shinyApp(ui, server) 25 | #' 26 | #' @importFrom shiny tags tagList 27 | #' 28 | #' @export 29 | incrementInput <- function(inputId, value = 0){ 30 | 31 | stopifnot(!missing(inputId)) 32 | stopifnot(is.numeric(value)) 33 | 34 | dep <- htmltools::htmlDependency( 35 | name = "incrementBinding", 36 | version = "1.0.0", 37 | src = c(file = system.file("packer", package = "increment")), 38 | script = "increment.js" 39 | ) 40 | 41 | tagList( 42 | dep, 43 | tags$button( 44 | id = inputId, 45 | class = "incrementBinding btn btn-default", 46 | type = "button", 47 | value 48 | ) 49 | ) 50 | } 51 | -------------------------------------------------------------------------------- /code/increment/inst/packer/increment.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";var n={n:e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},d:(e,t)=>{for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},o:(n,e)=>Object.prototype.hasOwnProperty.call(n,e)};const e=jQuery;var t=n.n(e);Shiny,t()(document).on("click","button.incrementBinding",(function(n){var e=t()(n.target);e.text(parseInt(e.text())+1),e.trigger("change")}));var i=new Shiny.InputBinding;t().extend(i,{find:function(n){return t()(n).find(".incrementBinding")},getValue:function(n){return parseInt(t()(n).text())},setValue:function(n,e){t()(n).text(e)},subscribe:function(n,e){t()(n).on("change.incrementBinding",(function(n){e()}))},unsubscribe:function(n){t()(n).off(".incrementBinding")}}),Shiny.inputBindings.register(i,"increment.incrementBinding")})(); -------------------------------------------------------------------------------- /code/increment/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "increment", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "none": "webpack --config webpack.dev.js --mode=none", 9 | "development": "webpack --config webpack.dev.js", 10 | "production": "webpack --config webpack.prod.js", 11 | "watch": "webpack --config webpack.config.js -d --watch" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "devDependencies": { 17 | "webpack": "^5.2.0", 18 | "webpack-cli": "^4.1.0", 19 | "webpack-merge": "^5.2.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /code/increment/srcjs/config/entry_points.json: -------------------------------------------------------------------------------- 1 | { 2 | "increment": "./srcjs/inputs/increment.js" 3 | } 4 | -------------------------------------------------------------------------------- /code/increment/srcjs/config/externals.json: -------------------------------------------------------------------------------- 1 | { 2 | "shiny": "Shiny", 3 | "jquery": "jQuery" 4 | } 5 | -------------------------------------------------------------------------------- /code/increment/srcjs/config/loaders.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /code/increment/srcjs/config/misc.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /code/increment/srcjs/config/output_path.json: -------------------------------------------------------------------------------- 1 | "./inst/packer" 2 | -------------------------------------------------------------------------------- /code/increment/srcjs/index.js: -------------------------------------------------------------------------------- 1 | import './inputs/increment.js'; 2 | -------------------------------------------------------------------------------- /code/increment/srcjs/inputs/increment.js: -------------------------------------------------------------------------------- 1 | import $ from 'jquery'; 2 | import 'shiny'; 3 | 4 | $(document).on("click", "button.incrementBinding", function(evt) { 5 | // evt.target is the button that was clicked 6 | var el = $(evt.target); 7 | 8 | // Set the button's text to its current value plus 1 9 | el.text(parseInt(el.text()) + 1); 10 | 11 | // Raise an event to signal that the value changed 12 | el.trigger("change"); 13 | }); 14 | 15 | var incrementBinding = new Shiny.InputBinding(); 16 | 17 | $.extend(incrementBinding, { 18 | find: function(scope) { 19 | return $(scope).find(".incrementBinding"); 20 | }, 21 | getValue: function(el) { 22 | return parseInt($(el).text()); 23 | }, 24 | setValue: function(el, value) { 25 | $(el).text(value); 26 | }, 27 | subscribe: function(el, callback) { 28 | $(el).on("change.incrementBinding", function(e) { 29 | callback(); 30 | }); 31 | }, 32 | unsubscribe: function(el) { 33 | $(el).off(".incrementBinding"); 34 | } 35 | }); 36 | 37 | Shiny.inputBindings.register(incrementBinding, "increment.incrementBinding"); 38 | -------------------------------------------------------------------------------- /code/increment/webpack.common.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | 4 | // Read config files 5 | var outputPath = fs.readFileSync('./srcjs/config/output_path.json'); 6 | var entryPoints = fs.readFileSync('./srcjs/config/entry_points.json'); 7 | var externals = fs.readFileSync('./srcjs/config/externals.json'); 8 | var misc = fs.readFileSync('./srcjs/config/misc.json'); 9 | var loaders = fs.readFileSync('./srcjs/config/loaders.json', 'utf8'); 10 | 11 | // parse 12 | loaders = JSON.parse(loaders); 13 | misc = JSON.parse(misc); 14 | externals = JSON.parse(externals); 15 | entryPoints = JSON.parse(entryPoints); 16 | 17 | // parse regex 18 | loaders.forEach((loader) => { 19 | loader.test = RegExp(loader.test); 20 | return(loader); 21 | }) 22 | 23 | // placeholder for plugins 24 | var plugins = [ 25 | ]; 26 | 27 | // define options 28 | var options = { 29 | entry: entryPoints, 30 | output: { 31 | filename: '[name].js', 32 | path: path.resolve(__dirname, JSON.parse(outputPath)), 33 | }, 34 | externals: externals, 35 | module: { 36 | rules: loaders 37 | }, 38 | plugins: plugins 39 | }; 40 | 41 | // add misc 42 | if(misc.resolve) 43 | options.resolve = misc.resolve; 44 | 45 | // export 46 | module.exports = options; 47 | -------------------------------------------------------------------------------- /code/increment/webpack.dev.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'development', 6 | devtool: 'inline-source-map' 7 | }); 8 | -------------------------------------------------------------------------------- /code/increment/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'production', 6 | }); 7 | -------------------------------------------------------------------------------- /code/javascript-intro/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

    Trying JavaScript!

    7 | 8 | 12 | -------------------------------------------------------------------------------- /code/jbox/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | ui <- fluidPage( 4 | tags$head( 5 | tags$script( 6 | src = paste0( 7 | "https://cdn.jsdelivr.net/gh/StephanWagner/", 8 | "jBox@v1.2.0/dist/jBox.all.min.js" 9 | ) 10 | ), 11 | tags$link( 12 | rel = "stylesheet", 13 | href = paste0( 14 | "https://cdn.jsdelivr.net/gh/StephanWagner/", 15 | "jBox@v1.2.0/dist/jBox.all.min.css" 16 | ) 17 | ), 18 | tags$script( 19 | "Shiny.addCustomMessageHandler( 20 | type = 'send-notice', function(message) { 21 | message.onClose = function(){ 22 | Shiny.setInputValue('notice_close', true, {priority: 'event'}); 23 | } 24 | new jBox('Notice', message); 25 | });" 26 | ) 27 | ), 28 | textInput("msg", "A message to show as notice"), 29 | actionButton("show", "Show the notice") 30 | ) 31 | 32 | server <- function(input, output, session){ 33 | 34 | observeEvent(input$show, { 35 | # define notice options 36 | notice = list( 37 | content = input$msg, 38 | color = 'black' 39 | ) 40 | 41 | # send the notice 42 | session$sendCustomMessage( 43 | type = "send-notice", message = notice 44 | ) 45 | }) 46 | 47 | # print the output of the notice_close event (when fired) 48 | observeEvent(input$notice_close, { 49 | print(input$notice_close) 50 | }) 51 | } 52 | 53 | shinyApp(ui, server) -------------------------------------------------------------------------------- /code/ml/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: ml 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "First", 6 | family = "Last", 7 | role = c("aut", "cre"), 8 | email = "first.last@example.com", 9 | comment = c(ORCID = "YOUR-ORCID-ID")) 10 | Description: What the package does (one paragraph). 11 | License: `use_mit_license()`, `use_gpl3_license()` or friends to 12 | pick a license 13 | Encoding: UTF-8 14 | LazyData: true 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.1.0.9000 17 | Imports: 18 | V8 19 | -------------------------------------------------------------------------------- /code/ml/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(predict,mlSimpleRegression) 4 | export(ml_predict) 5 | export(ml_simple_lm) 6 | -------------------------------------------------------------------------------- /code/ml/R/lm.R: -------------------------------------------------------------------------------- 1 | counter <- new.env(parent = emptyenv()) 2 | counter$regressions <- 0 3 | 4 | #' @export 5 | ml_simple_lm <- function(y, x){ 6 | counter$regressions <- counter$regressions + 1 7 | 8 | # assign variables 9 | ml$assign("x", x) 10 | ml$assign("y", y) 11 | 12 | # address 13 | address <- paste0("regressions['", counter$regressions, "']") 14 | 15 | # create regression 16 | code <- paste0(address, " = new ML.SimpleLinearRegression(x, y);") 17 | ml$eval(code) 18 | regression <- ml$get(address) 19 | regression$address <- address 20 | 21 | structure(regression, class = c("mlSimpleRegression", class(regression))) 22 | } 23 | 24 | #' @export 25 | ml_predict <- function(x){ 26 | ml$call("regression.predict", newdata) 27 | } 28 | 29 | #' @export 30 | predict.mlSimpleRegression <- function(object, newdata, ...){ 31 | code <- paste0(object$address, ".predict") 32 | ml$call(code, newdata) 33 | } -------------------------------------------------------------------------------- /code/ml/R/zzz.R: -------------------------------------------------------------------------------- 1 | # zzz.R 2 | ml <- NULL 3 | 4 | .onLoad <- function(libname, pkgname){ 5 | ml <<- V8::v8() 6 | mljs <- system.file("ml.min.js", package = "ml") 7 | ml$source(mljs) 8 | 9 | # array to track regression 10 | ml$eval("var regressions = [];") 11 | } -------------------------------------------------------------------------------- /code/ml/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | # ml 6 | 7 | Example of using JavaScript for machine learning computations. 8 | 9 | ## Example 10 | 11 | ``` r 12 | library(ml) 13 | 14 | # first model 15 | model_cars <- ml_simple_lm(cars$speed, cars$dist) 16 | 17 | predict(model_cars, 15) 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /code/ml5-app/README.md: -------------------------------------------------------------------------------- 1 | # Image Classifier 2 | 3 | Example of image classifier with JavaScript in shiny. 4 | -------------------------------------------------------------------------------- /code/ml5-app/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | # serve images 4 | addResourcePath("assets", "assets") 5 | 6 | # create handler 7 | handler <- function(data, ...){ 8 | purrr::map_dfr(data, as.data.frame) 9 | } 10 | 11 | # register with shiny 12 | shiny::registerInputHandler("ml5.class", handler) 13 | 14 | # ml5js dependency 15 | dependency_ml5 <- htmltools::htmlDependency( 16 | name = "ml5", 17 | version = "0.4.3", 18 | src = c(href = "https://unpkg.com/ml5@0.4.3/dist/"), 19 | script = "ml5.min.js" 20 | ) 21 | 22 | ui <- fluidPage( 23 | dependency_ml5, 24 | tags$head(tags$script(src = "assets/classify.js")), 25 | selectInput( 26 | inputId = "selectedBird", 27 | label = "bird", 28 | choices = c("flamingo", "lorikeet") 29 | ), 30 | actionButton("classify", "Classify"), 31 | uiOutput("birdDisplay"), 32 | tableOutput("results") 33 | ) 34 | 35 | server <- function(input, output, session) { 36 | 37 | output$birdDisplay <- renderUI({ 38 | path <- sprintf("assets/%s.jpg", input$selectedBird) 39 | tags$img(src = path, id = "bird") 40 | }) 41 | 42 | observeEvent(input$classify, { 43 | session$sendCustomMessage("classify", list()) 44 | }) 45 | 46 | output$results <- renderTable({ 47 | input$classification 48 | }) 49 | 50 | } 51 | 52 | shinyApp(ui, server) 53 | -------------------------------------------------------------------------------- /code/ml5-app/assets/classify.js: -------------------------------------------------------------------------------- 1 | // Initialize the Image Classifier method with MobileNet 2 | const classifier = ml5.imageClassifier('MobileNet', modelLoaded); 3 | // When the model is loaded 4 | function modelLoaded() { 5 | console.log('Model Loaded!'); 6 | } 7 | 8 | Shiny.addCustomMessageHandler('classify', function(data){ 9 | // Make a prediction with a selected image 10 | classifier.classify(document.getElementById("bird"), (err, results) => { 11 | Shiny.setInputValue("classification:ml5.class", results); 12 | }); 13 | }); -------------------------------------------------------------------------------- /code/ml5-app/assets/flamingo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/ml5-app/assets/flamingo.jpg -------------------------------------------------------------------------------- /code/ml5-app/assets/fratercula.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/ml5-app/assets/fratercula.jpg -------------------------------------------------------------------------------- /code/ml5-app/assets/gentoo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/ml5-app/assets/gentoo.jpg -------------------------------------------------------------------------------- /code/ml5-app/assets/hummingbird.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/ml5-app/assets/hummingbird.jpg -------------------------------------------------------------------------------- /code/ml5-app/assets/lorikeet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/ml5-app/assets/lorikeet.jpg -------------------------------------------------------------------------------- /code/ml5-pkg-test/app.R: -------------------------------------------------------------------------------- 1 | library(DT) 2 | library(ml5) 3 | library(shiny) 4 | 5 | addResourcePath("assets", "assets") 6 | 7 | ui <- fluidPage( 8 | useMl5(), 9 | selectInput( 10 | inputId = "selectedBird", 11 | label = "bird", 12 | choices = c("flamingo", "lorikeet") 13 | ), 14 | actionButton("classify", "Classify"), 15 | uiOutput("birdDisplay"), 16 | DTOutput("results") 17 | ) 18 | 19 | server <- function(input, output, session) { 20 | 21 | output$birdDisplay <- renderUI({ 22 | path <- sprintf("assets/%s.jpg", input$selectedBird) 23 | tags$img(src = path, id = "bird") 24 | }) 25 | 26 | observeEvent(input$classify, { 27 | classify("bird") 28 | }) 29 | 30 | output$results <- renderDT({ 31 | datatable(input$bird_classification) 32 | }) 33 | 34 | } 35 | 36 | shinyApp(ui, server) -------------------------------------------------------------------------------- /code/ml5-pkg-test/assets/flamingo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/ml5-pkg-test/assets/flamingo.jpg -------------------------------------------------------------------------------- /code/ml5-pkg-test/assets/fratercula.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/ml5-pkg-test/assets/fratercula.jpg -------------------------------------------------------------------------------- /code/ml5-pkg-test/assets/gentoo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/ml5-pkg-test/assets/gentoo.jpg -------------------------------------------------------------------------------- /code/ml5-pkg-test/assets/hummingbird.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/ml5-pkg-test/assets/hummingbird.jpg -------------------------------------------------------------------------------- /code/ml5-pkg-test/assets/lorikeet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/ml5-pkg-test/assets/lorikeet.jpg -------------------------------------------------------------------------------- /code/ml5-pkg/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: ml5 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "First", 6 | family = "Last", 7 | role = c("aut", "cre"), 8 | email = "first.last@example.com", 9 | comment = c(ORCID = "YOUR-ORCID-ID")) 10 | Description: What the package does (one paragraph). 11 | License: `use_mit_license()`, `use_gpl3_license()` or friends to 12 | pick a license 13 | Encoding: UTF-8 14 | LazyData: true 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.1.1.9000 17 | -------------------------------------------------------------------------------- /code/ml5-pkg/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(classify) 4 | export(useMl5) 5 | -------------------------------------------------------------------------------- /code/ml5-pkg/R/classify.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | classify <- function(id, session = shiny::getDefaultReactiveDomain()){ 3 | session$sendCustomMessage("ml5-classify", id) 4 | } -------------------------------------------------------------------------------- /code/ml5-pkg/R/deps.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | useMl5 <- function(cdn = TRUE) { 3 | 4 | pkg <- htmltools::htmlDependency( 5 | name = "ml5-pkg", 6 | version = "1.0.0", 7 | src = "", 8 | script = c(file = "classify.js"), 9 | package = "ml5" 10 | ) 11 | 12 | ml5 <- list() 13 | if(cdn) 14 | ml5 <- htmltools::htmlDependency( 15 | name = "ml5", 16 | version = "0.4.3", 17 | src = c(href = "https://unpkg.com/ml5@0.4.3/dist/"), 18 | script = "ml5.min.js" 19 | ) 20 | else 21 | ml5 <- htmltools::htmlDependency( 22 | name = "ml5", 23 | version = "0.4.3", 24 | src = "", 25 | script = c(file = "ml5.min.js"), 26 | package = "ml5" 27 | ) 28 | 29 | htmltools::tagList(ml5, pkg) 30 | } -------------------------------------------------------------------------------- /code/ml5-pkg/R/handler.R: -------------------------------------------------------------------------------- 1 | # create handler 2 | handler <- function(data, ...){ 3 | purrr::map_dfr(data, as.data.frame) 4 | } 5 | 6 | # register with shiny 7 | .onLoad <- function(...){ 8 | shiny::registerInputHandler("ml5.class", handler) 9 | } -------------------------------------------------------------------------------- /code/ml5-pkg/inst/classify.js: -------------------------------------------------------------------------------- 1 | // Initialize the Image Classifier method with MobileNet 2 | const classifier = ml5.imageClassifier('MobileNet', modelLoaded); 3 | // When the model is loaded 4 | function modelLoaded() { 5 | console.log('Model Loaded!'); 6 | } 7 | 8 | Shiny.addCustomMessageHandler('ml5-classify', function(data){ 9 | // Make a prediction with a selected image 10 | classifier.classify(document.getElementById(data), (err, results) => { 11 | Shiny.setInputValue(data + "_classification:ml5.class", results); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /code/ms/.Rbuildignore: -------------------------------------------------------------------------------- 1 | in.js 2 | ^in\.js$ 3 | -------------------------------------------------------------------------------- /code/ms/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: ms 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "First", 6 | family = "Last", 7 | role = c("aut", "cre"), 8 | email = "first.last@example.com", 9 | comment = c(ORCID = "YOUR-ORCID-ID")) 10 | Description: What the package does (one paragraph). 11 | License: `use_mit_license()`, `use_gpl3_license()` or friends to 12 | pick a license 13 | Encoding: UTF-8 14 | LazyData: true 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.1.1 17 | Imports: 18 | V8 19 | -------------------------------------------------------------------------------- /code/ms/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(to_ms) 4 | -------------------------------------------------------------------------------- /code/ms/R/ms.R: -------------------------------------------------------------------------------- 1 | #' Convert To Millisecond 2 | #' 3 | #' Convert to milliseconds to various formats. 4 | #' 5 | #' @param string String to convert. 6 | #' 7 | #' @export 8 | to_ms <- function(string){ 9 | ms$call("ms", string) 10 | } -------------------------------------------------------------------------------- /code/ms/R/zzz.R: -------------------------------------------------------------------------------- 1 | # zzz.R 2 | ms <- NULL 3 | 4 | .onLoad <- function(libname, pkgname){ 5 | ms <<- V8::v8() 6 | 7 | dep <- system.file("ms.js", package = "ms") 8 | ms$source(dep) 9 | } 10 | 11 | .onUnload <- function(libpath){ 12 | ms$reset() 13 | } -------------------------------------------------------------------------------- /code/ms/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # ms 5 | 6 | Basic example of package using the V8 engine for computations. 7 | 8 | ## Example 9 | 10 | ``` r 11 | ms::ms("1 week") 12 | ``` 13 | 14 | -------------------------------------------------------------------------------- /code/ms/in.js: -------------------------------------------------------------------------------- 1 | global.ms = require('ms'); 2 | -------------------------------------------------------------------------------- /code/ms/man/to_ms.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ms.R 3 | \name{to_ms} 4 | \alias{to_ms} 5 | \title{Convert To Millisecond} 6 | \usage{ 7 | to_ms(string) 8 | } 9 | \arguments{ 10 | \item{string}{String to convert.} 11 | } 12 | \description{ 13 | Convert to milliseconds to various formats. 14 | } 15 | -------------------------------------------------------------------------------- /code/peity/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: peity 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "First", 6 | family = "Last", 7 | role = c("aut", "cre"), 8 | email = "first.last@example.com", 9 | comment = c(ORCID = "YOUR-ORCID-ID")) 10 | Description: What the package does (one paragraph). 11 | License: `use_mit_license()`, `use_gpl3_license()` or friends to 12 | pick a license 13 | Encoding: UTF-8 14 | LazyData: true 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.1.1.9000 17 | -------------------------------------------------------------------------------- /code/peity/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(peity) 4 | export(peityOutput) 5 | export(renderPeity) 6 | import(htmlwidgets) 7 | -------------------------------------------------------------------------------- /code/peity/R/peity.R: -------------------------------------------------------------------------------- 1 | #' 2 | #' 3 | #' 4 | #' 5 | #' @import htmlwidgets 6 | #' 7 | #' @export 8 | peity <- function(data, type = "bar", ..., width = NULL, height = NULL, elementId = NULL) { 9 | 10 | # forward options using x 11 | x = list( 12 | data = data, 13 | type = type, 14 | options = list(...) 15 | ) 16 | 17 | # create widget 18 | htmlwidgets::createWidget( 19 | name = 'peity', 20 | x, 21 | width = width, 22 | height = height, 23 | package = 'peity', 24 | elementId = elementId 25 | ) 26 | } 27 | 28 | peity_html <- function(...){ 29 | htmltools::tags$span(...) 30 | } 31 | 32 | #' Shiny bindings for peity 33 | #' 34 | #' Output and render functions for using peity within Shiny 35 | #' applications and interactive Rmd documents. 36 | #' 37 | #' @param outputId output variable to read from 38 | #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, 39 | #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 40 | #' string and have \code{'px'} appended. 41 | #' @param expr An expression that generates a peity 42 | #' @param env The environment in which to evaluate \code{expr}. 43 | #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This 44 | #' is useful if you want to save an expression in a variable. 45 | #' 46 | #' @name peity-shiny 47 | #' 48 | #' @export 49 | peityOutput <- function(outputId, width = '100%', height = '400px'){ 50 | htmlwidgets::shinyWidgetOutput(outputId, 'peity', width, height, package = 'peity') 51 | } 52 | 53 | #' @rdname peity-shiny 54 | #' @export 55 | renderPeity <- function(expr, env = parent.frame(), quoted = FALSE) { 56 | if (!quoted) { expr <- substitute(expr) } # force quoted 57 | htmlwidgets::shinyRenderWidget(expr, peityOutput, env, quoted = TRUE) 58 | } 59 | -------------------------------------------------------------------------------- /code/peity/inst/htmlwidgets/peity.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'peity', 4 | 5 | type: 'output', 6 | 7 | factory: function(el, width, height) { 8 | 9 | // TODO: define shared variables for this instance 10 | 11 | return { 12 | 13 | renderValue: function(x) { 14 | 15 | // TODO: code to render the widget, e.g. 16 | el.innerText = x.data; 17 | $(el).peity(x.type, x.options); 18 | 19 | }, 20 | 21 | resize: function(width, height) { 22 | 23 | // TODO: code to re-render the widget with a new size 24 | 25 | } 26 | 27 | }; 28 | } 29 | }); -------------------------------------------------------------------------------- /code/peity/inst/htmlwidgets/peity.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: jQuery 3 | version: 3.5.1 4 | src: htmlwidgets/jquery 5 | script: jquery.min.js 6 | - name: peity 7 | version: 3.3.0 8 | src: htmlwidgets/peity 9 | script: jquery.peity.min.js 10 | -------------------------------------------------------------------------------- /code/peity/man/peity-shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/peity.R 3 | \name{peity-shiny} 4 | \alias{peity-shiny} 5 | \alias{peityOutput} 6 | \alias{renderPeity} 7 | \title{Shiny bindings for peity} 8 | \usage{ 9 | peityOutput(outputId, width = "100\%", height = "400px") 10 | 11 | renderPeity(expr, env = parent.frame(), quoted = FALSE) 12 | } 13 | \arguments{ 14 | \item{outputId}{output variable to read from} 15 | 16 | \item{width, height}{Must be a valid CSS unit (like \code{'100\%'}, 17 | \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 18 | string and have \code{'px'} appended.} 19 | 20 | \item{expr}{An expression that generates a peity} 21 | 22 | \item{env}{The environment in which to evaluate \code{expr}.} 23 | 24 | \item{quoted}{Is \code{expr} a quoted expression (with \code{quote()})? This 25 | is useful if you want to save an expression in a variable.} 26 | } 27 | \description{ 28 | Output and render functions for using peity within Shiny 29 | applications and interactive Rmd documents. 30 | } 31 | -------------------------------------------------------------------------------- /code/peity/man/peity.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/peity.R 3 | \name{peity} 4 | \alias{peity} 5 | \title{} 6 | \usage{ 7 | peity(data, type = "bar", ..., width = NULL, height = NULL, elementId = NULL) 8 | } 9 | \description{ 10 | 11 | } 12 | -------------------------------------------------------------------------------- /code/playground/.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^playground\.Rproj$ 2 | ^\.Rproj\.user$ 3 | -------------------------------------------------------------------------------- /code/playground/.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | -------------------------------------------------------------------------------- /code/playground/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: playground 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "First", 6 | family = "Last", 7 | role = c("aut", "cre"), 8 | email = "first.last@example.com", 9 | comment = c(ORCID = "YOUR-ORCID-ID")) 10 | Description: What the package does (one paragraph). 11 | License: `use_mit_license()`, `use_gpl3_license()` or friends to 12 | pick a license 13 | Encoding: UTF-8 14 | LazyData: true 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.1.0 17 | -------------------------------------------------------------------------------- /code/playground/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(play) 4 | export(playOutput) 5 | export(renderPlay) 6 | import(htmlwidgets) 7 | -------------------------------------------------------------------------------- /code/playground/R/play.R: -------------------------------------------------------------------------------- 1 | #' 2 | #' 3 | #' 4 | #' 5 | #' @import htmlwidgets 6 | #' 7 | #' @export 8 | play <- function(message, width = NULL, height = NULL, elementId = NULL) { 9 | 10 | # forward options using x 11 | x = list( 12 | message = as.character(message) 13 | ) 14 | 15 | # create widget 16 | htmlwidgets::createWidget( 17 | name = 'play', 18 | x, 19 | width = width, 20 | height = height, 21 | package = 'playground', 22 | elementId = elementId 23 | ) 24 | } 25 | 26 | #' Shiny bindings for play 27 | #' 28 | #' Output and render functions for using play within Shiny 29 | #' applications and interactive Rmd documents. 30 | #' 31 | #' @param outputId output variable to read from 32 | #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, 33 | #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 34 | #' string and have \code{'px'} appended. 35 | #' @param expr An expression that generates a play 36 | #' @param env The environment in which to evaluate \code{expr}. 37 | #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This 38 | #' is useful if you want to save an expression in a variable. 39 | #' 40 | #' @name play-shiny 41 | #' 42 | #' @export 43 | playOutput <- function(outputId, width = '100%', height = '400px'){ 44 | htmlwidgets::shinyWidgetOutput(outputId, 'play', width, height, package = 'playground') 45 | } 46 | 47 | #' @rdname play-shiny 48 | #' @export 49 | renderPlay <- function(expr, env = parent.frame(), quoted = FALSE) { 50 | if (!quoted) { expr <- substitute(expr) } # force quoted 51 | htmlwidgets::shinyRenderWidget(expr, playOutput, env, quoted = TRUE) 52 | } 53 | -------------------------------------------------------------------------------- /code/playground/inst/htmlwidgets/play.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'play', 4 | 5 | type: 'output', 6 | 7 | factory: function(el, width, height) { 8 | 9 | // TODO: define shared variables for this instance 10 | 11 | return { 12 | 13 | renderValue: function(x) { 14 | 15 | // TODO: code to render the widget, e.g. 16 | console.log(x); 17 | console.log(el.id); 18 | el.innerHTML = x.message; 19 | 20 | }, 21 | 22 | resize: function(width, height) { 23 | 24 | // TODO: code to re-render the widget with a new size 25 | 26 | } 27 | 28 | }; 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /code/playground/inst/htmlwidgets/play.yaml: -------------------------------------------------------------------------------- 1 | # (uncomment to add a dependency) 2 | # dependencies: 3 | # - name: 4 | # version: 5 | # src: 6 | # script: 7 | # stylesheet: 8 | -------------------------------------------------------------------------------- /code/playground/man/play-shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/play.R 3 | \name{play-shiny} 4 | \alias{play-shiny} 5 | \alias{playOutput} 6 | \alias{renderPlay} 7 | \title{Shiny bindings for play} 8 | \usage{ 9 | playOutput(outputId, width = "100\%", height = "400px") 10 | 11 | renderPlay(expr, env = parent.frame(), quoted = FALSE) 12 | } 13 | \arguments{ 14 | \item{outputId}{output variable to read from} 15 | 16 | \item{width, height}{Must be a valid CSS unit (like \code{'100\%'}, 17 | \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 18 | string and have \code{'px'} appended.} 19 | 20 | \item{expr}{An expression that generates a play} 21 | 22 | \item{env}{The environment in which to evaluate \code{expr}.} 23 | 24 | \item{quoted}{Is \code{expr} a quoted expression (with \code{quote()})? This 25 | is useful if you want to save an expression in a variable.} 26 | } 27 | \description{ 28 | Output and render functions for using play within Shiny 29 | applications and interactive Rmd documents. 30 | } 31 | -------------------------------------------------------------------------------- /code/playground/man/play.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/play.R 3 | \name{play} 4 | \alias{play} 5 | \title{} 6 | \usage{ 7 | play(message, width = NULL, height = NULL, elementId = NULL) 8 | } 9 | \description{ 10 | 11 | } 12 | -------------------------------------------------------------------------------- /code/playground/playground.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /code/plotlier/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: plotlier 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "First", 6 | family = "Last", 7 | role = c("aut", "cre"), 8 | email = "first.last@example.com", 9 | comment = c(ORCID = "YOUR-ORCID-ID")) 10 | Description: What the package does (one paragraph). 11 | License: `use_mit_license()`, `use_gpl3_license()` or friends to 12 | pick a license 13 | Encoding: UTF-8 14 | LazyData: true 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.1.1 17 | Imports: 18 | magrittr 19 | -------------------------------------------------------------------------------- /code/plotlier/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export("%>%") 4 | export(plot_add_marker) 5 | export(plot_line) 6 | export(plot_marker) 7 | export(plotly) 8 | export(plotlyOutput) 9 | export(plotlyProxy) 10 | export(renderPlotly) 11 | import(htmlwidgets) 12 | importFrom(magrittr,"%>%") 13 | -------------------------------------------------------------------------------- /code/plotlier/R/add.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | plot_add_marker <- function(proxy, data, x, y){ 3 | data <- list( 4 | x = data[[x]], 5 | y = data[[y]], 6 | type = "scatter", 7 | mode = "markers" 8 | ) 9 | 10 | msg <- list(id = proxy$id, data = data) 11 | proxy$session$sendCustomMessage("add-traces", msg) 12 | return(proxy) 13 | } -------------------------------------------------------------------------------- /code/plotlier/R/layers.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | plot_line <- function(p, x, y){ 3 | add_scatter(p, x, y, mode = "lines") 4 | } 5 | 6 | #' @export 7 | plot_marker <- function(p, x, y){ 8 | add_scatter(p, x, y, mode = "markers") 9 | } 10 | 11 | add_scatter <- function(p, x, y, mode = "markers"){ 12 | layer <- list( 13 | x = dplyr::pull(p$x$data, {{ x }}), 14 | y = dplyr::pull(p$x$data, {{ y }}), 15 | type = "scatter", 16 | mode = mode 17 | ) 18 | 19 | p$x$options <- append(p$x$options, list(layer)) 20 | return(p) 21 | } -------------------------------------------------------------------------------- /code/plotlier/R/plotly.R: -------------------------------------------------------------------------------- 1 | #' 2 | #' 3 | #' 4 | #' 5 | #' @import htmlwidgets 6 | #' 7 | #' @export 8 | plotly <- function(data, width = NULL, height = NULL, elementId = NULL) { 9 | 10 | # forward options using x 11 | x = list( 12 | data = data, 13 | options = list() 14 | ) 15 | 16 | # create widget 17 | htmlwidgets::createWidget( 18 | name = 'plotly', 19 | x, 20 | width = width, 21 | height = height, 22 | package = 'plotlier', 23 | elementId = elementId, 24 | preRenderHook = render_plotlier, 25 | sizingPolicy = sizingPolicy( 26 | defaultWidth = "100%" 27 | ) 28 | ) 29 | } 30 | 31 | render_plotlier <- function(p){ 32 | p$x$data <- NULL 33 | return(p) 34 | } 35 | 36 | #' Shiny bindings for plotly 37 | #' 38 | #' Output and render functions for using plotly within Shiny 39 | #' applications and interactive Rmd documents. 40 | #' 41 | #' @param outputId output variable to read from 42 | #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, 43 | #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 44 | #' string and have \code{'px'} appended. 45 | #' @param expr An expression that generates a plotly 46 | #' @param env The environment in which to evaluate \code{expr}. 47 | #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This 48 | #' is useful if you want to save an expression in a variable. 49 | #' 50 | #' @name plotly-shiny 51 | #' 52 | #' @export 53 | plotlyOutput <- function(outputId, width = '100%', height = '400px'){ 54 | htmlwidgets::shinyWidgetOutput(outputId, 'plotly', width, height, package = 'plotlier') 55 | } 56 | 57 | #' @rdname plotly-shiny 58 | #' @export 59 | renderPlotly <- function(expr, env = parent.frame(), quoted = FALSE) { 60 | if (!quoted) { expr <- substitute(expr) } # force quoted 61 | htmlwidgets::shinyRenderWidget(expr, plotlyOutput, env, quoted = TRUE) 62 | } 63 | 64 | #' @rdname plotly-shiny 65 | #' @export 66 | plotlyProxy <- function(id, session = shiny::getDefaultReactiveDomain()){ 67 | list( 68 | id = id, 69 | session = session 70 | ) 71 | } -------------------------------------------------------------------------------- /code/plotlier/R/utils-pipe.R: -------------------------------------------------------------------------------- 1 | #' Pipe operator 2 | #' 3 | #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 4 | #' 5 | #' @name %>% 6 | #' @rdname pipe 7 | #' @keywords internal 8 | #' @export 9 | #' @importFrom magrittr %>% 10 | #' @usage lhs \%>\% rhs 11 | NULL 12 | -------------------------------------------------------------------------------- /code/plotlier/README.md: -------------------------------------------------------------------------------- 1 | 2 | # plotlier 3 | 4 | Example of htmlwidgets for plotly.js 5 | 6 | ## Example 7 | 8 | use in shiny 9 | 10 | ``` r 11 | library(shiny) 12 | library(plotlier) 13 | 14 | df <- data.frame(x = 1:10, y = runif(10)) 15 | 16 | ui <- fluidPage( 17 | actionButton("add", "Add random trace"), 18 | plotlyOutput("plot") 19 | ) 20 | 21 | server <- function(input, output){ 22 | 23 | output$plot <- renderPlotly({ 24 | df %>% 25 | plotly() %>% 26 | plot_line("x", "y") 27 | }) 28 | 29 | proxy <- plotlyProxy("plot") 30 | 31 | observeEvent(input$add, { 32 | random <- data.frame(x = runif(10, 1, 10), y = runif(10)) 33 | 34 | plot_add_line( 35 | proxy, 36 | random, 37 | "x", "y" 38 | ) 39 | }) 40 | 41 | } 42 | 43 | shinyApp(ui, server) 44 | ``` 45 | 46 | -------------------------------------------------------------------------------- /code/plotlier/inst/htmlwidgets/plotly.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'plotly', 4 | 5 | type: 'output', 6 | 7 | factory: function(el, width, height) { 8 | 9 | // TODO: define shared variables for this instance 10 | 11 | return { 12 | 13 | renderValue: function(x) { 14 | 15 | Plotly.newPlot(el.id, x.options); 16 | 17 | el.on('plotly_click', function(data){ 18 | var coords = [data.points[0].x, data.points[0].y]; 19 | Shiny.setInputValue(el.id + '_clicked', coords); 20 | }); 21 | 22 | }, 23 | 24 | resize: function(width, height) { 25 | 26 | // TODO: code to re-render the widget with a new size 27 | Plotly.relayout(el.id, {width: width, height: height}); 28 | 29 | } 30 | 31 | }; 32 | } 33 | }); 34 | 35 | if(HTMLWidgets.shinyMode){ 36 | 37 | Shiny.addCustomMessageHandler(type = 'add-traces', function(msg){ 38 | Plotly.addTraces(msg.id, msg.data); 39 | }) 40 | 41 | } -------------------------------------------------------------------------------- /code/plotlier/inst/htmlwidgets/plotly.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: plotly 3 | version: 1.54.2 4 | src: htmlwidgets/plotly 5 | script: plotly.min.js 6 | -------------------------------------------------------------------------------- /code/plotlier/man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils-pipe.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \description{ 10 | See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /code/plotlier/man/plotly-shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotly.R 3 | \name{plotly-shiny} 4 | \alias{plotly-shiny} 5 | \alias{plotlyOutput} 6 | \alias{renderPlotly} 7 | \alias{plotlyProxy} 8 | \title{Shiny bindings for plotly} 9 | \usage{ 10 | plotlyOutput(outputId, width = "100\%", height = "400px") 11 | 12 | renderPlotly(expr, env = parent.frame(), quoted = FALSE) 13 | 14 | plotlyProxy(id, session = shiny::getDefaultReactiveDomain()) 15 | } 16 | \arguments{ 17 | \item{outputId}{output variable to read from} 18 | 19 | \item{width, height}{Must be a valid CSS unit (like \code{'100\%'}, 20 | \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 21 | string and have \code{'px'} appended.} 22 | 23 | \item{expr}{An expression that generates a plotly} 24 | 25 | \item{env}{The environment in which to evaluate \code{expr}.} 26 | 27 | \item{quoted}{Is \code{expr} a quoted expression (with \code{quote()})? This 28 | is useful if you want to save an expression in a variable.} 29 | } 30 | \description{ 31 | Output and render functions for using plotly within Shiny 32 | applications and interactive Rmd documents. 33 | } 34 | -------------------------------------------------------------------------------- /code/plotlier/man/plotly.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotly.R 3 | \name{plotly} 4 | \alias{plotly} 5 | \title{} 6 | \usage{ 7 | plotly(data, width = NULL, height = NULL, elementId = NULL) 8 | } 9 | \description{ 10 | 11 | } 12 | -------------------------------------------------------------------------------- /code/rsup/README.md: -------------------------------------------------------------------------------- 1 | # Progress Bar 2 | 3 | Two examples of creating and using progress bars in shiny with JavaScript. 4 | 5 | 1. Programmatic use - called from R server 6 | 2. Automatic use - automagically handled 7 | -------------------------------------------------------------------------------- /code/rsup/app-auto.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | shiny::addResourcePath("www", "www") 4 | 5 | ui <- fluidPage( 6 | tags$head( 7 | tags$script(src = "https://unpkg.com/rsup-progress"), 8 | tags$script(src = "www/auto.js") 9 | ), 10 | br(), 11 | actionButton("render", "render"), 12 | plotOutput("plot") 13 | ) 14 | 15 | server <- function(input, output){ 16 | 17 | output$plot <- renderPlot({ 18 | input$render 19 | Sys.sleep(2) 20 | hist(rnorm(100)) 21 | }) 22 | 23 | } 24 | 25 | shinyApp(ui, server) 26 | -------------------------------------------------------------------------------- /code/rsup/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | shiny::addResourcePath("www", "www") 4 | 5 | ui <- fluidPage( 6 | tags$head( 7 | tags$script(src = "https://unpkg.com/rsup-progress"), 8 | tags$script(src = "www/script.js") 9 | ), 10 | br(), 11 | actionButton("start", "start"), 12 | actionButton("end", "end") 13 | ) 14 | 15 | server <- function(input, output, session){ 16 | 17 | session$sendCustomMessage('rsup-options', list(color = "red")) 18 | 19 | observeEvent(input$start, { 20 | session$sendCustomMessage('rsup-start', list()) 21 | }) 22 | 23 | observeEvent(input$end, { 24 | session$sendCustomMessage('rsup-end', list()) 25 | }) 26 | 27 | } 28 | 29 | shinyApp(ui, server) 30 | -------------------------------------------------------------------------------- /code/rsup/www/auto.js: -------------------------------------------------------------------------------- 1 | var progress; 2 | 3 | $(document).on('shiny:busy', function(event){ 4 | progress = new RsupProgress(); 5 | progress.start(); 6 | }); 7 | 8 | $(document).on('shiny:idle', function(event){ 9 | progress.end(); 10 | }); -------------------------------------------------------------------------------- /code/rsup/www/script.js: -------------------------------------------------------------------------------- 1 | const progress = new RsupProgress(); 2 | 3 | Shiny.addCustomMessageHandler('rsup-options', function(msg){ 4 | progress.setOptions(msg); 5 | }); 6 | 7 | Shiny.addCustomMessageHandler('rsup-start', function(msg){ 8 | progress.start(); 9 | }); 10 | 11 | Shiny.addCustomMessageHandler('rsup-end', function(msg){ 12 | progress.end(); 13 | }); 14 | -------------------------------------------------------------------------------- /code/switch-input/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | switchInput <- function(id, label, checked = TRUE) { 4 | 5 | input <- tags$input( 6 | id = id, 7 | type = "checkbox", 8 | class = "switchInput" 9 | ) 10 | 11 | if(checked) 12 | input <- htmltools::tagAppendAttributes(input, checked = NA) 13 | 14 | form <- tagList( 15 | p(label), 16 | tags$label( 17 | class = "switch", 18 | input, 19 | tags$span(class = "slider") 20 | ) 21 | ) 22 | 23 | path <- normalizePath("./assets") 24 | 25 | deps <- htmltools::htmlDependency( 26 | name = "switchInput", 27 | version = "1.0.0", 28 | src = c(file = path), 29 | script = "binding.js", 30 | stylesheet = "styles.css" 31 | ) 32 | 33 | htmltools::attachDependencies(form, deps) 34 | } 35 | 36 | update_switch_input <- function(id, value, session = shiny::getDefaultReactiveDomain()){ 37 | session$sendInputMessage(id, value) 38 | } 39 | 40 | ui <- fluidPage( 41 | actionButton("chg", "Switch ON"), 42 | switchInput("switch", "Switch input", FALSE), 43 | plotOutput("plot") 44 | ) 45 | 46 | server <- function(input, output, session){ 47 | 48 | output$plot <- renderPlot({ 49 | print(input$switch) 50 | 51 | if(!input$switch) 52 | return() 53 | 54 | plot(cars) 55 | }) 56 | 57 | observeEvent(input$chg, { 58 | update_switch_input("switch", TRUE, session) 59 | }) 60 | } 61 | 62 | shinyApp(ui, server) 63 | -------------------------------------------------------------------------------- /code/switch-input/assets/binding.js: -------------------------------------------------------------------------------- 1 | var switchInput = new Shiny.InputBinding(); 2 | 3 | // $(document).on("click", "input.switchInput", function() { 4 | // $(this).prop("checked", this.checked); 5 | // }) 6 | 7 | $.extend(switchInput, { 8 | find: function(scope) { 9 | return $(scope).find(".switchInput"); 10 | }, 11 | getValue: function(el) { 12 | return $(el).prop("checked"); 13 | }, 14 | setValue: function(el, value) { 15 | $(el).prop("checked", value).change(); 16 | }, 17 | receiveMessage: function(el, value){ 18 | this.setValue(el, value); 19 | }, 20 | subscribe: function (el, callback) { 21 | $(el).on("change.switchInput", function(){ 22 | callback(true); 23 | }); 24 | }, 25 | unsubscribe: function(el) { 26 | $(el).off(".switchInput"); 27 | }, 28 | getRatePolicy: function(){ 29 | return { 30 | policy: 'throttle', 31 | delay: 1000 32 | } 33 | } 34 | }); 35 | 36 | Shiny.inputBindings.register(switchInput, 'john.switch'); 37 | 38 | -------------------------------------------------------------------------------- /code/switch-input/assets/styles.css: -------------------------------------------------------------------------------- 1 | .switch { 2 | position: relative; 3 | display: inline-block; 4 | width: 60px; 5 | height: 34px; 6 | } 7 | 8 | .switch input { 9 | opacity: 0; 10 | width: 0; 11 | height: 0; 12 | } 13 | 14 | .slider { 15 | position: absolute; 16 | cursor: pointer; 17 | top: 0; 18 | left: 0; 19 | right: 0; 20 | bottom: 0; 21 | background-color: #ccc; 22 | -webkit-transition: .4s; 23 | transition: .4s; 24 | } 25 | 26 | .slider:before { 27 | position: absolute; 28 | content: ""; 29 | height: 26px; 30 | width: 26px; 31 | left: 4px; 32 | bottom: 4px; 33 | background-color: white; 34 | -webkit-transition: .4s; 35 | transition: .4s; 36 | } 37 | 38 | input:checked + .slider { 39 | background-color: #0462a1; 40 | } 41 | 42 | input:focus + .slider { 43 | box-shadow: 0 0 1px #0462a1; 44 | } 45 | 46 | input:checked + .slider:before { 47 | -webkit-transform: translateX(26px); 48 | -ms-transform: translateX(26px); 49 | transform: translateX(26px); 50 | } 51 | -------------------------------------------------------------------------------- /code/table-button/README.md: -------------------------------------------------------------------------------- 1 | # Table Buttons 2 | 3 | Example of using JavaScript to include buttons in a shiny table (DT). 4 | 5 | ```r 6 | library(DT) 7 | library(shiny) 8 | 9 | ui <- fluidPage( 10 | DTOutput("table"), 11 | strong("Clicked Model:"), 12 | verbatimTextOutput("model") 13 | ) 14 | 15 | server <- function(input, output) { 16 | output$table <- renderDT({ 17 | onclick <- paste0("Shiny.setInputValue('click', '", rownames(mtcars), "')") 18 | button <- paste0("Click me") 19 | mtcars$button <- button 20 | datatable(mtcars, escape = FALSE, selection = "none", rownames = FALSE) 21 | }) 22 | 23 | output$model <- renderPrint({ 24 | print(input$click) 25 | }) 26 | } 27 | 28 | shinyApp(ui, server) 29 | ``` 30 | -------------------------------------------------------------------------------- /code/table-button/app.R: -------------------------------------------------------------------------------- 1 | library(DT) 2 | library(shiny) 3 | 4 | ui <- fluidPage( 5 | DTOutput("table"), 6 | strong("Clicked Model:"), 7 | verbatimTextOutput("model") 8 | ) 9 | 10 | server <- function(input, output) { 11 | output$table <- renderDT({ 12 | onclick <- paste0("Shiny.setInputValue('click', '", rownames(mtcars), "')") 13 | button <- paste0("Click me") 14 | mtcars$button <- button 15 | datatable(mtcars, escape = FALSE, selection = "none", rownames = FALSE) 16 | }) 17 | 18 | output$model <- renderPrint({ 19 | print(input$click) 20 | }) 21 | } 22 | 23 | shinyApp(ui, server) -------------------------------------------------------------------------------- /code/typed/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: typed 2 | Title: What the Package Does (One Line, Title Case) 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "First", 6 | family = "Last", 7 | role = c("aut", "cre"), 8 | email = "first.last@example.com", 9 | comment = c(ORCID = "YOUR-ORCID-ID")) 10 | Description: What the package does (one paragraph). 11 | License: `use_mit_license()`, `use_gpl3_license()` or friends to 12 | pick a license 13 | Encoding: UTF-8 14 | LazyData: true 15 | Roxygen: list(markdown = TRUE) 16 | RoxygenNote: 7.1.0 17 | -------------------------------------------------------------------------------- /code/typed/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | -------------------------------------------------------------------------------- /code/typed/R/typed.R: -------------------------------------------------------------------------------- 1 | #' 2 | #' 3 | #' 4 | #' 5 | #' @import htmlwidgets 6 | #' 7 | #' @export 8 | typed <- function(message, loop = FALSE, width = NULL, height = NULL, elementId = NULL) { 9 | 10 | # forward options using x 11 | x = list( 12 | loop = loop, 13 | strings = as.list(message) 14 | ) 15 | 16 | # create widget 17 | htmlwidgets::createWidget( 18 | name = 'typed', 19 | x, 20 | width = width, 21 | height = height, 22 | package = 'typed', 23 | elementId = elementId 24 | ) 25 | } 26 | 27 | typed_html <- function(...){ 28 | htmltools::tags$span(...) 29 | } 30 | 31 | #' Shiny bindings for typed 32 | #' 33 | #' Output and render functions for using typed within Shiny 34 | #' applications and interactive Rmd documents. 35 | #' 36 | #' @param outputId output variable to read from 37 | #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, 38 | #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 39 | #' string and have \code{'px'} appended. 40 | #' @param expr An expression that generates a typed 41 | #' @param env The environment in which to evaluate \code{expr}. 42 | #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This 43 | #' is useful if you want to save an expression in a variable. 44 | #' 45 | #' @name typed-shiny 46 | #' 47 | #' @export 48 | typedOutput <- function(outputId, width = '100%', height = '400px'){ 49 | htmlwidgets::shinyWidgetOutput(outputId, 'typed', width, height, package = 'typed') 50 | } 51 | 52 | #' @rdname typed-shiny 53 | #' @export 54 | renderTyped <- function(expr, env = parent.frame(), quoted = FALSE) { 55 | if (!quoted) { expr <- substitute(expr) } # force quoted 56 | htmlwidgets::shinyRenderWidget(expr, typedOutput, env, quoted = TRUE) 57 | } 58 | -------------------------------------------------------------------------------- /code/typed/README.md: -------------------------------------------------------------------------------- 1 | 2 | # typed 3 | 4 | 5 | 6 | 7 | Basic example of htmlwidgets. 8 | 9 | ## Example 10 | 11 | 12 | ``` r 13 | library(typed) 14 | 15 | typed(c("hello", "world")) 16 | ``` 17 | -------------------------------------------------------------------------------- /code/typed/inst/htmlwidgets/typed.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'typed', 4 | 5 | type: 'output', 6 | 7 | factory: function(el, width, height) { 8 | 9 | // TODO: define shared variables for this instance 10 | var typed; 11 | 12 | return { 13 | 14 | renderValue: function(x) { 15 | 16 | typed = new Typed('#' + el.id, x); 17 | 18 | }, 19 | 20 | resize: function(width, height) { 21 | 22 | // TODO: code to re-render the widget with a new size 23 | 24 | } 25 | 26 | }; 27 | } 28 | }); -------------------------------------------------------------------------------- /code/typed/inst/htmlwidgets/typed.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: typed.js 3 | version: 2.0.11 4 | src: htmlwidgets/typed 5 | script: typed.min.js 6 | -------------------------------------------------------------------------------- /code/vuer/.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^data-raw$ 4 | dev_history.R 5 | ^dev$ 6 | $run_dev.* 7 | ^srcjs$ 8 | ^node_modules$ 9 | ^package\.json$ 10 | ^package-lock\.json$ 11 | ^webpack\.dev\.js$ 12 | ^webpack\.prod\.js$ 13 | ^webpack\.common\.js$ 14 | ^\.babelrc$ 15 | -------------------------------------------------------------------------------- /code/vuer/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /code/vuer/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /code/vuer/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: vuer 2 | Title: An Amazing Shiny App 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person(given = "firstname", 6 | family = "lastname", 7 | role = c("aut", "cre"), 8 | email = "your@email.com") 9 | Description: What the package does (one paragraph). 10 | License: What license is it under? 11 | Imports: 12 | config (>= 0.3), 13 | golem (>= 0.3.0), 14 | shiny (>= 1.5.0) 15 | Encoding: UTF-8 16 | LazyData: true 17 | RoxygenNote: 6.1.1 18 | -------------------------------------------------------------------------------- /code/vuer/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(run_app) 4 | import(shiny) 5 | importFrom(golem,activate_js) 6 | importFrom(golem,add_resource_path) 7 | importFrom(golem,bundle_resources) 8 | importFrom(golem,favicon) 9 | importFrom(golem,with_golem_options) 10 | importFrom(shiny,shinyApp) 11 | -------------------------------------------------------------------------------- /code/vuer/R/app_config.R: -------------------------------------------------------------------------------- 1 | #' Access files in the current app 2 | #' 3 | #' NOTE: If you manually change your package name in the DESCRIPTION, 4 | #' don't forget to change it here too, and in the config file. 5 | #' For a safer name change mechanism, use the `golem::set_golem_name()` function. 6 | #' 7 | #' @param ... character vectors, specifying subdirectory and file(s) 8 | #' within your package. The default, none, returns the root of the app. 9 | #' 10 | #' @noRd 11 | app_sys <- function(...){ 12 | system.file(..., package = "vuer") 13 | } 14 | 15 | 16 | #' Read App Config 17 | #' 18 | #' @param value Value to retrieve from the config file. 19 | #' @param config R_CONFIG_ACTIVE value. 20 | #' @param use_parent Logical, scan the parent directory for config file. 21 | #' 22 | #' @noRd 23 | get_golem_config <- function( 24 | value, 25 | config = Sys.getenv("R_CONFIG_ACTIVE", "default"), 26 | use_parent = TRUE 27 | ){ 28 | config::get( 29 | value = value, 30 | config = config, 31 | # Modify this if your config file is somewhere else: 32 | file = app_sys("golem-config.yml"), 33 | use_parent = use_parent 34 | ) 35 | } 36 | 37 | -------------------------------------------------------------------------------- /code/vuer/R/app_server.R: -------------------------------------------------------------------------------- 1 | #' The application server-side 2 | #' 3 | #' @param input,output,session Internal parameters for {shiny}. 4 | #' DO NOT REMOVE. 5 | #' @import shiny 6 | #' @noRd 7 | app_server <- function( input, output, session ) { 8 | # Your application server logic 9 | 10 | } 11 | -------------------------------------------------------------------------------- /code/vuer/R/app_ui.R: -------------------------------------------------------------------------------- 1 | #' The application User-Interface 2 | #' 3 | #' @param request Internal parameter for `{shiny}`. 4 | #' DO NOT REMOVE. 5 | #' @import shiny 6 | #' @noRd 7 | app_ui <- function(request) { 8 | tagList( 9 | # Leave this function for adding external resources 10 | golem_add_external_resources(), 11 | # Your application UI logic 12 | fluidPage( 13 | htmltools::suppressDependencies("bootstrap"), 14 | br(), 15 | tagList( 16 | vueCDN(), 17 | div(id = "app"), 18 | tags$script(src = "www/index.js") 19 | ) 20 | ) 21 | ) 22 | } 23 | 24 | #' Add external Resources to the Application 25 | #' 26 | #' This function is internally used to add external 27 | #' resources inside the Shiny application. 28 | #' 29 | #' @import shiny 30 | #' @importFrom golem add_resource_path activate_js favicon bundle_resources 31 | #' @noRd 32 | golem_add_external_resources <- function(){ 33 | 34 | add_resource_path( 35 | 'www', app_sys('app/www') 36 | ) 37 | 38 | tags$head( 39 | favicon(), 40 | bundle_resources( 41 | path = app_sys('app/www'), 42 | app_title = 'vuer' 43 | ) 44 | # Add here other external resources 45 | # for example, you can add shinyalert::useShinyalert() 46 | ) 47 | } 48 | 49 | -------------------------------------------------------------------------------- /code/vuer/R/run_app.R: -------------------------------------------------------------------------------- 1 | #' Run the Shiny Application 2 | #' 3 | #' @param ... arguments to pass to golem_opts 4 | #' @inheritParams shiny::shinyApp 5 | #' 6 | #' @export 7 | #' @importFrom shiny shinyApp 8 | #' @importFrom golem with_golem_options 9 | run_app <- function( 10 | onStart = NULL, 11 | options = list(), 12 | enableBookmarking = NULL, 13 | ... 14 | ) { 15 | with_golem_options( 16 | app = shinyApp( 17 | ui = app_ui, 18 | server = app_server, 19 | onStart = onStart, 20 | options = options, 21 | enableBookmarking = enableBookmarking 22 | ), 23 | golem_opts = list(...) 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /code/vuer/R/vue_cdn.R: -------------------------------------------------------------------------------- 1 | #' Dependencies for Vue 2 | #' 3 | #' Includes Vue dependencies in a shiny application. 4 | #' 5 | #' @param version Version of Vue to use, if `NULL` uses the latest 6 | #' 7 | #' @keywords internal 8 | vueCDN <- function(version = NULL){ 9 | 10 | version_string <- ".js" 11 | if(!is.null(version)) 12 | version_string <- sprintf("@%d", version) 13 | 14 | vue <- sprintf("https://cdn.jsdelivr.net/npm/vue", version_string) 15 | shiny::singleton( 16 | shiny::tags$head( 17 | shiny::tags$script(src = vue, crossorigin = NA) 18 | ) 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /code/vuer/dev/01_start.R: -------------------------------------------------------------------------------- 1 | # Building a Prod-Ready, Robust Shiny Application. 2 | # 3 | # README: each step of the dev files is optional, and you don't have to 4 | # fill every dev scripts before getting started. 5 | # 01_start.R should be filled at start. 6 | # 02_dev.R should be used to keep track of your development during the project. 7 | # 03_deploy.R should be used once you need to deploy your app. 8 | # 9 | # 10 | ######################################## 11 | #### CURRENT FILE: ON START SCRIPT ##### 12 | ######################################## 13 | 14 | ## Fill the DESCRIPTION ---- 15 | ## Add meta data about your application 16 | ## 17 | ## /!\ Note: if you want to change the name of your app during development, 18 | ## either re-run this function, call golem::set_golem_name(), or don't forget 19 | ## to change the name in the app_sys() function in app_config.R /!\ 20 | ## 21 | golem::fill_desc( 22 | pkg_name = "vuer", # The Name of the package containing the App 23 | pkg_title = "PKG_TITLE", # The Title of the package containing the App 24 | pkg_description = "PKG_DESC.", # The Description of the package containing the App 25 | author_first_name = "AUTHOR_FIRST", # Your First Name 26 | author_last_name = "AUTHOR_LAST", # Your Last Name 27 | author_email = "AUTHOR@MAIL.COM", # Your Email 28 | repo_url = NULL # The URL of the GitHub Repo (optional) 29 | ) 30 | 31 | ## Set {golem} options ---- 32 | golem::set_golem_options() 33 | 34 | ## Create Common Files ---- 35 | ## See ?usethis for more information 36 | usethis::use_mit_license( name = "Golem User" ) # You can set another license here 37 | usethis::use_readme_rmd( open = FALSE ) 38 | usethis::use_code_of_conduct() 39 | usethis::use_lifecycle_badge( "Experimental" ) 40 | usethis::use_news_md( open = FALSE ) 41 | 42 | ## Use git ---- 43 | usethis::use_git() 44 | 45 | ## Init Testing Infrastructure ---- 46 | ## Create a template for tests 47 | golem::use_recommended_tests() 48 | 49 | ## Use Recommended Packages ---- 50 | golem::use_recommended_deps() 51 | 52 | ## Favicon ---- 53 | # If you want to change the favicon (default is golem's one) 54 | golem::use_favicon() # path = "path/to/ico". Can be an online file. 55 | golem::remove_favicon() 56 | 57 | ## Add helper functions ---- 58 | golem::use_utils_ui() 59 | golem::use_utils_server() 60 | 61 | # You're now set! ---- 62 | 63 | # go to dev/02_dev.R 64 | rstudioapi::navigateToFile( "dev/02_dev.R" ) 65 | 66 | -------------------------------------------------------------------------------- /code/vuer/dev/03_deploy.R: -------------------------------------------------------------------------------- 1 | # Building a Prod-Ready, Robust Shiny Application. 2 | # 3 | # README: each step of the dev files is optional, and you don't have to 4 | # fill every dev scripts before getting started. 5 | # 01_start.R should be filled at start. 6 | # 02_dev.R should be used to keep track of your development during the project. 7 | # 03_deploy.R should be used once you need to deploy your app. 8 | # 9 | # 10 | ###################################### 11 | #### CURRENT FILE: DEPLOY SCRIPT ##### 12 | ###################################### 13 | 14 | # Test your app 15 | 16 | ## Run checks ---- 17 | ## Check the package before sending to prod 18 | devtools::check() 19 | rhub::check_for_cran() 20 | 21 | # Deploy 22 | 23 | ## RStudio ---- 24 | ## If you want to deploy on RStudio related platforms 25 | golem::add_rstudioconnect_file() 26 | golem::add_shinyappsio_file() 27 | golem::add_shinyserver_file() 28 | 29 | ## Docker ---- 30 | ## If you want to deploy via a generic Dockerfile 31 | golem::add_dockerfile() 32 | 33 | ## If you want to deploy to ShinyProxy 34 | golem::add_dockerfile_shinyproxy() 35 | 36 | ## If you want to deploy to Heroku 37 | golem::add_dockerfile_heroku() 38 | -------------------------------------------------------------------------------- /code/vuer/dev/run_dev.R: -------------------------------------------------------------------------------- 1 | # Set options here 2 | options(golem.app.prod = FALSE) # TRUE = production mode, FALSE = development mode 3 | 4 | # Detach all loaded packages and clean your environment 5 | golem::detach_all_attached() 6 | # rm(list=ls(all.names = TRUE)) 7 | 8 | # Document and reload your package 9 | golem::document_and_reload() 10 | 11 | # Run the application 12 | run_app() 13 | -------------------------------------------------------------------------------- /code/vuer/inst/app/www/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/code/vuer/inst/app/www/favicon.ico -------------------------------------------------------------------------------- /code/vuer/inst/app/www/index.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * BootstrapVue Icons, generated from Bootstrap Icons 1.0.0 3 | * 4 | * @link https://icons.getbootstrap.com/ 5 | * @license MIT 6 | * https://github.com/twbs/icons/blob/master/LICENSE.md 7 | */ 8 | 9 | /*! 10 | * Vue.js v2.6.12 11 | * (c) 2014-2020 Evan You 12 | * Released under the MIT License. 13 | */ 14 | -------------------------------------------------------------------------------- /code/vuer/inst/golem-config.yml: -------------------------------------------------------------------------------- 1 | default: 2 | golem_name: vuer 3 | golem_version: 0.0.0.9000 4 | app_prod: no 5 | production: 6 | app_prod: yes 7 | dev: 8 | golem_wd: !expr here::here() 9 | -------------------------------------------------------------------------------- /code/vuer/man/run_app.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/run_app.R 3 | \name{run_app} 4 | \alias{run_app} 5 | \title{Run the Shiny Application} 6 | \usage{ 7 | run_app(onStart = NULL, options = list(), enableBookmarking = NULL, 8 | ...) 9 | } 10 | \arguments{ 11 | \item{onStart}{A function that will be called before the app is actually run. 12 | This is only needed for \code{shinyAppObj}, since in the \code{shinyAppDir} 13 | case, a \code{global.R} file can be used for this purpose.} 14 | 15 | \item{options}{Named options that should be passed to the \code{runApp} call 16 | (these can be any of the following: "port", "launch.browser", "host", "quiet", 17 | "display.mode" and "test.mode"). You can also specify \code{width} and 18 | \code{height} parameters which provide a hint to the embedding environment 19 | about the ideal height/width for the app.} 20 | 21 | \item{enableBookmarking}{Can be one of \code{"url"}, \code{"server"}, or 22 | \code{"disable"}. This is equivalent to calling the 23 | \code{\link[=enableBookmarking]{enableBookmarking()}} function just before calling 24 | \code{shinyApp()}. With the default value (\code{NULL}), the app will 25 | respect the setting from any previous calls to \code{enableBookmarking()}. 26 | See \code{\link[=enableBookmarking]{enableBookmarking()}} for more information.} 27 | 28 | \item{...}{arguments to pass to golem_opts} 29 | } 30 | \description{ 31 | Run the Shiny Application 32 | } 33 | -------------------------------------------------------------------------------- /code/vuer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuer", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "directories": { 7 | "man": "man" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1", 11 | "none": "webpack --config webpack.dev.js --mode=none", 12 | "development": "webpack --config webpack.dev.js", 13 | "production": "webpack --config webpack.prod.js", 14 | "watch": "webpack --config webpack.config.js -d --watch" 15 | }, 16 | "keywords": [], 17 | "author": "", 18 | "license": "ISC", 19 | "devDependencies": { 20 | "@babel/core": "^7.12.3", 21 | "@babel/preset-env": "^7.12.1", 22 | "babel-loader": "^8.1.0", 23 | "css-loader": "^5.0.0", 24 | "style-loader": "^2.0.0", 25 | "vue": "^2.6.12", 26 | "vue-loader": "^15.9.4", 27 | "vue-template-compiler": "^2.6.12", 28 | "webpack": "^5.3.1", 29 | "webpack-cli": "^4.1.0", 30 | "webpack-merge": "^5.2.0" 31 | }, 32 | "dependencies": { 33 | "bootstrap": "^4.5.3", 34 | "bootstrap-vue": "^2.18.1" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /code/vuer/srcjs/Home.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | -------------------------------------------------------------------------------- /code/vuer/srcjs/config/entry_points.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": "./srcjs/index.js" 3 | } 4 | -------------------------------------------------------------------------------- /code/vuer/srcjs/config/externals.json: -------------------------------------------------------------------------------- 1 | { 2 | "shiny": "Shiny", 3 | "jquery": "jQuery" 4 | } 5 | -------------------------------------------------------------------------------- /code/vuer/srcjs/config/loaders.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "test": "\\.(js|jsx)$", 4 | "use": [ 5 | "babel-loader" 6 | ], 7 | "exclude": "/node_modules/" 8 | }, 9 | { 10 | "test": "\\.vue$", 11 | "use": [ 12 | "vue-loader" 13 | ], 14 | "exclude": "/node_modules/" 15 | }, 16 | { 17 | "test": "\\.css$", 18 | "use": [ 19 | "style-loader", 20 | "css-loader" 21 | ] 22 | } 23 | ] 24 | -------------------------------------------------------------------------------- /code/vuer/srcjs/config/misc.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolve": { 3 | "alias": { 4 | "vue": "vue/dist/vue.esm.js" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code/vuer/srcjs/config/output_path.json: -------------------------------------------------------------------------------- 1 | "./inst/app/www" 2 | -------------------------------------------------------------------------------- /code/vuer/srcjs/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import { BootstrapVue, IconsPlugin } from 'bootstrap-vue' 3 | import 'bootstrap/dist/css/bootstrap.css' 4 | import 'bootstrap-vue/dist/bootstrap-vue.css' 5 | import App from "./Home.vue"; 6 | 7 | Vue.use(BootstrapVue) 8 | Vue.use(IconsPlugin) 9 | 10 | new Vue({ 11 | el: "#app", 12 | template: "", 13 | components: { App } 14 | }); 15 | -------------------------------------------------------------------------------- /code/vuer/webpack.common.js: -------------------------------------------------------------------------------- 1 | const VueLoaderPlugin = require('vue-loader/lib/plugin'); 2 | const path = require('path'); 3 | const fs = require('fs'); 4 | 5 | // Read config files 6 | var outputPath = fs.readFileSync('./srcjs/config/output_path.json'); 7 | var entryPoints = fs.readFileSync('./srcjs/config/entry_points.json'); 8 | var externals = fs.readFileSync('./srcjs/config/externals.json'); 9 | var misc = fs.readFileSync('./srcjs/config/misc.json'); 10 | var loaders = fs.readFileSync('./srcjs/config/loaders.json', 'utf8'); 11 | 12 | // parse 13 | loaders = JSON.parse(loaders); 14 | misc = JSON.parse(misc); 15 | externals = JSON.parse(externals); 16 | entryPoints = JSON.parse(entryPoints); 17 | 18 | // parse regex 19 | loaders.forEach((loader) => { 20 | loader.test = RegExp(loader.test); 21 | return(loader); 22 | }) 23 | 24 | // placeholder for plugins 25 | var plugins = [ 26 | new VueLoaderPlugin() 27 | ]; 28 | 29 | // define options 30 | var options = { 31 | entry: entryPoints, 32 | output: { 33 | filename: '[name].js', 34 | path: path.resolve(__dirname, JSON.parse(outputPath)), 35 | }, 36 | externals: externals, 37 | module: { 38 | rules: loaders 39 | }, 40 | plugins: plugins 41 | }; 42 | 43 | // add misc 44 | if(misc.resolve) 45 | options.resolve = misc.resolve; 46 | 47 | // export 48 | module.exports = options; 49 | -------------------------------------------------------------------------------- /code/vuer/webpack.dev.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'development', 6 | devtool: 'inline-source-map' 7 | }); 8 | -------------------------------------------------------------------------------- /code/vuer/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'production', 6 | }); 7 | -------------------------------------------------------------------------------- /code/webpack-intro/app.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | 3 | mainJs <- htmltools::htmlDependency( 4 | name = "main", 5 | version = "1.0.0", 6 | src = "./dist", 7 | script = c(file = "main.js") 8 | ) 9 | 10 | ui <- fluidPage( 11 | mainJs, 12 | p("Type the secret phrase"), 13 | uiOutput("hello"), 14 | plotOutput("plot") 15 | ) 16 | 17 | server <- function(input, output) { 18 | output$hello <- renderUI({ 19 | req(input$secret) 20 | h2("You got the secret right!") 21 | }) 22 | 23 | output$plot <- renderPlot({ 24 | req(input$secret) 25 | hist(cars$speed) 26 | }) 27 | } 28 | 29 | shinyApp(ui, server) 30 | 31 | -------------------------------------------------------------------------------- /code/webpack-intro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myapp", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build-prod": "webpack --mode=production", 9 | "build-dev": "webpack --mode=development" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "webpack": "^5.2.0", 16 | "webpack-cli": "^4.1.0" 17 | }, 18 | "dependencies": { 19 | "mousetrap": "^1.6.5" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /code/webpack-intro/src/index.js: -------------------------------------------------------------------------------- 1 | import './input.js'; -------------------------------------------------------------------------------- /code/webpack-intro/src/input.js: -------------------------------------------------------------------------------- 1 | import Shiny from 'shiny' 2 | import { secret } from './secret.js'; 3 | import 'mousetrap'; 4 | 5 | Mousetrap.bind(secret, function() { 6 | Shiny.setInputValue('secret', true); 7 | }); 8 | 9 | -------------------------------------------------------------------------------- /code/webpack-intro/src/secret.js: -------------------------------------------------------------------------------- 1 | export let secret = 's e c r e t'; 2 | -------------------------------------------------------------------------------- /code/webpack-intro/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './src/index.js', 3 | externals: { 4 | shiny: 'Shiny' 5 | } 6 | }; -------------------------------------------------------------------------------- /css/toc.css: -------------------------------------------------------------------------------- 1 | .book .book-summary { 2 | position: absolute; 3 | top: 0; 4 | left: -300px; 5 | width: 300px; 6 | bottom: 0; 7 | z-index: 1; 8 | color: #FFFFFF; 9 | background: #0462a1; 10 | } 11 | 12 | .book .book-summary ul.summary li a, .book .book-summary ul.summary li span { 13 | margin: 5px 5px 5px 5px; 14 | display: block; 15 | padding: 10px 20px 10px 20px; 16 | color: #FFFFFF; 17 | background: 0 0; 18 | text-overflow: ellipsis; 19 | overflow: hidden; 20 | white-space: nowrap; 21 | position: relative; 22 | } 23 | 24 | .book .book-summary ul.summary li.active>a { 25 | padding-left: 5px; 26 | color: #FFFFFF; 27 | font-weight: bold; 28 | border-left:4px solid #ffcb00; 29 | text-decoration: none; 30 | } 31 | 32 | .book .book-summary ul.summary li a:hover { 33 | padding-left: 5px; 34 | color: #FFFFFF; 35 | font-weight: bold; 36 | border-left:4px solid #ffcb00; 37 | text-decoration: none; 38 | } 39 | 40 | td, tr, th { 41 | color:white !important; 42 | background-color: transparent !important; 43 | } 44 | 45 | table { 46 | color:white !important; 47 | background-color: #0462a1 !important; 48 | } 49 | 50 | 51 | .part{ 52 | padding-top: 2em; 53 | text-transform: uppercase; 54 | font-size: .95em; 55 | } 56 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/favicon.ico -------------------------------------------------------------------------------- /ga.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /images/01-d3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/01-d3.png -------------------------------------------------------------------------------- /images/01-plotly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/01-plotly.png -------------------------------------------------------------------------------- /images/01-reactable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/01-reactable.png -------------------------------------------------------------------------------- /images/02-dom-viz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/02-dom-viz.png -------------------------------------------------------------------------------- /images/03-DT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/03-DT.png -------------------------------------------------------------------------------- /images/03-crosstalk-gio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/03-crosstalk-gio.png -------------------------------------------------------------------------------- /images/03-crosstalk-grps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/03-crosstalk-grps.png -------------------------------------------------------------------------------- /images/03-crosstalk-viz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/03-crosstalk-viz.png -------------------------------------------------------------------------------- /images/03-ggplotly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/03-ggplotly.png -------------------------------------------------------------------------------- /images/03-htmlwidget-viz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/03-htmlwidget-viz.png -------------------------------------------------------------------------------- /images/03-htmlwidgets-internals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/03-htmlwidgets-internals.png -------------------------------------------------------------------------------- /images/03-plotly-multiple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/03-plotly-multiple.png -------------------------------------------------------------------------------- /images/03-plotly-scatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/03-plotly-scatter.png -------------------------------------------------------------------------------- /images/04-custom-msg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/04-custom-msg.png -------------------------------------------------------------------------------- /images/04-shiny-complex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/04-shiny-complex.png -------------------------------------------------------------------------------- /images/04-shiny-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/04-shiny-input.png -------------------------------------------------------------------------------- /images/04-shiny-websocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/04-shiny-websocket.png -------------------------------------------------------------------------------- /images/04-websocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/04-websocket.png -------------------------------------------------------------------------------- /images/07-webpack-shiny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/07-webpack-shiny.png -------------------------------------------------------------------------------- /images/DT-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/DT-example.png -------------------------------------------------------------------------------- /images/alert-shiny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/alert-shiny.png -------------------------------------------------------------------------------- /images/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/alert.png -------------------------------------------------------------------------------- /images/boxxy-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/boxxy-example.png -------------------------------------------------------------------------------- /images/candidate-chartjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/candidate-chartjs.png -------------------------------------------------------------------------------- /images/candidate-highcharts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/candidate-highcharts.png -------------------------------------------------------------------------------- /images/candidate-plotly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/candidate-plotly.png -------------------------------------------------------------------------------- /images/checkbox-switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/checkbox-switch.png -------------------------------------------------------------------------------- /images/console-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/console-table.png -------------------------------------------------------------------------------- /images/coronavirus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/coronavirus.png -------------------------------------------------------------------------------- /images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/cover.jpg -------------------------------------------------------------------------------- /images/crosstalk-gio-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/crosstalk-gio-1.png -------------------------------------------------------------------------------- /images/crosstalk-gio-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/crosstalk-gio-2.png -------------------------------------------------------------------------------- /images/crosstalk-shiny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/crosstalk-shiny.png -------------------------------------------------------------------------------- /images/crosstalk-three-dots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/crosstalk-three-dots.png -------------------------------------------------------------------------------- /images/crosstalk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/crosstalk.png -------------------------------------------------------------------------------- /images/custom-output-boxxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/custom-output-boxxy.png -------------------------------------------------------------------------------- /images/devtools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/devtools.png -------------------------------------------------------------------------------- /images/dt-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/dt-button.png -------------------------------------------------------------------------------- /images/dt-crosstalk-intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/dt-crosstalk-intro.png -------------------------------------------------------------------------------- /images/gio-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-100.png -------------------------------------------------------------------------------- /images/gio-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-data.png -------------------------------------------------------------------------------- /images/gio-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-example.png -------------------------------------------------------------------------------- /images/gio-fit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-fit.png -------------------------------------------------------------------------------- /images/gio-init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-init.png -------------------------------------------------------------------------------- /images/gio-input-handler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-input-handler.png -------------------------------------------------------------------------------- /images/gio-shiny-clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-shiny-clear.png -------------------------------------------------------------------------------- /images/gio-shiny-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-shiny-error.png -------------------------------------------------------------------------------- /images/gio-shiny-input-no-handler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-shiny-input-no-handler.png -------------------------------------------------------------------------------- /images/gio-shiny-style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-shiny-style.png -------------------------------------------------------------------------------- /images/gio-size-issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-size-issue.png -------------------------------------------------------------------------------- /images/gio-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-small.png -------------------------------------------------------------------------------- /images/gio-style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-style.png -------------------------------------------------------------------------------- /images/gio-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/gio-title.png -------------------------------------------------------------------------------- /images/hotkeys-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/hotkeys-console.png -------------------------------------------------------------------------------- /images/htmlwidgets-performances.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/htmlwidgets-performances.png -------------------------------------------------------------------------------- /images/javascript-intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/javascript-intro.png -------------------------------------------------------------------------------- /images/jbox-custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/jbox-custom.png -------------------------------------------------------------------------------- /images/jbox-end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/jbox-end.png -------------------------------------------------------------------------------- /images/jbox-init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/jbox-init.png -------------------------------------------------------------------------------- /images/jbox-r2js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/jbox-r2js.png -------------------------------------------------------------------------------- /images/jbox-recreate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/jbox-recreate.png -------------------------------------------------------------------------------- /images/lena-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/lena-demo.png -------------------------------------------------------------------------------- /images/lena-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/lena-test.png -------------------------------------------------------------------------------- /images/ml5-init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/ml5-init.png -------------------------------------------------------------------------------- /images/ml5-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/ml5-output.png -------------------------------------------------------------------------------- /images/ml5-pkg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/ml5-pkg.png -------------------------------------------------------------------------------- /images/ml5-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/ml5-table.png -------------------------------------------------------------------------------- /images/mousetrap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/mousetrap.png -------------------------------------------------------------------------------- /images/note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/note.png -------------------------------------------------------------------------------- /images/open-in-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/open-in-browser.png -------------------------------------------------------------------------------- /images/peity-div.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/peity-div.png -------------------------------------------------------------------------------- /images/peity-span.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/peity-span.png -------------------------------------------------------------------------------- /images/playground-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/playground-1.png -------------------------------------------------------------------------------- /images/playground-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/playground-color.png -------------------------------------------------------------------------------- /images/playground-console-el.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/playground-console-el.png -------------------------------------------------------------------------------- /images/playground-console-x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/playground-console-x.png -------------------------------------------------------------------------------- /images/playground-deps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/playground-deps.png -------------------------------------------------------------------------------- /images/playground-h1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/playground-h1.png -------------------------------------------------------------------------------- /images/playground-source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/playground-source.png -------------------------------------------------------------------------------- /images/plotlier-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/plotlier-add.png -------------------------------------------------------------------------------- /images/plotlier-responsive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/plotlier-responsive.png -------------------------------------------------------------------------------- /images/plotlier-scatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/plotlier-scatter.png -------------------------------------------------------------------------------- /images/rstudio-create-package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/rstudio-create-package.png -------------------------------------------------------------------------------- /images/rsup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/rsup.png -------------------------------------------------------------------------------- /images/shiny-complete-classify-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/shiny-complete-classify-console.png -------------------------------------------------------------------------------- /images/shiny-complete-skeleton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/shiny-complete-skeleton.png -------------------------------------------------------------------------------- /images/shiny-complete-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/shiny-complete-table.png -------------------------------------------------------------------------------- /images/shiny-cookies-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/shiny-cookies-1.png -------------------------------------------------------------------------------- /images/shiny-cookies-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/shiny-cookies-2.png -------------------------------------------------------------------------------- /images/shiny-cookies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/shiny-cookies.png -------------------------------------------------------------------------------- /images/shiny-events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/shiny-events.png -------------------------------------------------------------------------------- /images/social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/social.png -------------------------------------------------------------------------------- /images/stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/stats.png -------------------------------------------------------------------------------- /images/switch-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/switch-example.png -------------------------------------------------------------------------------- /images/tryingjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/tryingjs.png -------------------------------------------------------------------------------- /images/typed-deps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/typed-deps.png -------------------------------------------------------------------------------- /images/vue-bs4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/vue-bs4.png -------------------------------------------------------------------------------- /images/waiter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoene/javascript-for-r/77fd95c7a5c89caf5fca266149cb230cc4a05a4e/images/waiter.png -------------------------------------------------------------------------------- /latex/after_body.tex: -------------------------------------------------------------------------------- 1 | \backmatter 2 | \printindex 3 | -------------------------------------------------------------------------------- /latex/before_body.tex: -------------------------------------------------------------------------------- 1 | % you may need to leave a few empty pages before the dedication page 2 | 3 | %\cleardoublepage\newpage\thispagestyle{empty}\null 4 | %\cleardoublepage\newpage\thispagestyle{empty}\null 5 | %\cleardoublepage\newpage 6 | \thispagestyle{empty} 7 | 8 | \begin{center} 9 | %\includegraphics{images/dedication.pdf} 10 | \end{center} 11 | 12 | \setlength{\abovedisplayskip}{-5pt} 13 | \setlength{\abovedisplayshortskip}{-5pt} 14 | -------------------------------------------------------------------------------- /latex/preamble.tex: -------------------------------------------------------------------------------- 1 | \usepackage{booktabs} 2 | \usepackage{longtable} 3 | \usepackage[bf,singlelinecheck=off]{caption} 4 | 5 | \usepackage{framed,color} 6 | \definecolor{shadecolor}{RGB}{248,248,248} 7 | 8 | \renewcommand{\textfraction}{0.05} 9 | \renewcommand{\topfraction}{0.8} 10 | \renewcommand{\bottomfraction}{0.8} 11 | \renewcommand{\floatpagefraction}{0.75} 12 | 13 | \renewenvironment{quote}{\begin{VF}}{\end{VF}} 14 | \let\oldhref\href 15 | \renewcommand{\href}[2]{#2\footnote{\url{#1}}} 16 | 17 | \makeatletter 18 | \newenvironment{kframe}{% 19 | \medskip{} 20 | \setlength{\fboxsep}{.8em} 21 | \def\at@end@of@kframe{}% 22 | \ifinner\ifhmode% 23 | \def\at@end@of@kframe{\end{minipage}}% 24 | \begin{minipage}{\columnwidth}% 25 | \fi\fi% 26 | \def\FrameCommand##1{\hskip\@totalleftmargin \hskip-\fboxsep 27 | \colorbox{shadecolor}{##1}\hskip-\fboxsep 28 | % There is no \\@totalrightmargin, so: 29 | \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}% 30 | \MakeFramed {\advance\hsize-\width 31 | \@totalleftmargin\z@ \linewidth\hsize 32 | \@setminipage}}% 33 | {\par\unskip\endMakeFramed% 34 | \at@end@of@kframe} 35 | \makeatother 36 | 37 | \renewenvironment{Shaded}{\begin{kframe}}{\end{kframe}} 38 | 39 | \newenvironment{rmdblock}[1] 40 | { 41 | \begin{itemize} 42 | \renewcommand{\labelitemi}{ 43 | \raisebox{-.7\height}[0pt][0pt]{ 44 | {\setkeys{Gin}{width=3em,keepaspectratio}\includegraphics{images/#1}} 45 | } 46 | } 47 | \setlength{\fboxsep}{1em} 48 | \begin{kframe} 49 | \item 50 | } 51 | { 52 | \end{kframe} 53 | \end{itemize} 54 | } 55 | \newenvironment{rmdnote} 56 | {\begin{rmdblock}{note}} 57 | {\end{rmdblock}} 58 | \newenvironment{rmdcaution} 59 | {\begin{rmdblock}{caution}} 60 | {\end{rmdblock}} 61 | \newenvironment{rmdimportant} 62 | {\begin{rmdblock}{important}} 63 | {\end{rmdblock}} 64 | \newenvironment{rmdtip} 65 | {\begin{rmdblock}{tip}} 66 | {\end{rmdblock}} 67 | \newenvironment{rmdwarning} 68 | {\begin{rmdblock}{warning}} 69 | {\end{rmdblock}} 70 | 71 | \usepackage{makeidx} 72 | \makeindex 73 | 74 | \urlstyle{tt} 75 | 76 | \usepackage{amsthm} 77 | \makeatletter 78 | \def\thm@space@setup{% 79 | \thm@preskip=8pt plus 2pt minus 4pt 80 | \thm@postskip=\thm@preskip 81 | } 82 | \makeatother 83 | 84 | \usepackage{float} 85 | 86 | \frontmatter 87 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | html: 2 | Rscript -e 'bookdown::render_book(".", output_format = "bookdown::gitbook")' 3 | 4 | pdf: 5 | Rscript -e 'bookdown::render_book(".", output_format = "bookdown::pdf_book")' 6 | 7 | install: 8 | Rscript -e "setwd('./code/gio');devtools::install();" 9 | Rscript -e "setwd('./code/ms');devtools::install();" 10 | Rscript -e "setwd('./code/playground');devtools::install();" 11 | Rscript -e "setwd('./code/typed');devtools::install();" 12 | Rscript -e "setwd('./code/peity');devtools::install();" 13 | Rscript -e "setwd('./code/playground');devtools::install();" 14 | Rscript -e "setwd('./code/ml');devtools::install();" 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r-n-js-crc", 3 | "version": "1.0.0", 4 | "description": "JavaScript for R, the book.", 5 | "main": "ms.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "ms": "^2.1.2", 14 | "natural": "^0.6.3", 15 | "neuro.js": "^0.1.7", 16 | "xterm": "^4.7.0" 17 | }, 18 | "devDependencies": {}, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/JohnCoene/javascript-for-r.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/JohnCoene/javascript-for-r/issues" 25 | }, 26 | "homepage": "https://javascript-for-r.com" 27 | } 28 | -------------------------------------------------------------------------------- /social.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /try.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

    Trying JavaScript!

    7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /utils.R: -------------------------------------------------------------------------------- 1 | include_widget <- function(w, img_path) { 2 | if (knitr::is_latex_output()) { 3 | img <- paste0("images/", img_path) 4 | knitr::include_graphics(img) 5 | } else { 6 | w 7 | } 8 | } --------------------------------------------------------------------------------