├── .Rbuildignore ├── .bumpversion.cfg ├── .gitattributes ├── .gitignore ├── .travis.yml ├── DESCRIPTION ├── LICENSE ├── LICENSE.note ├── NAMESPACE ├── NEWS ├── R ├── editAddin.R ├── misc.R ├── rhandsontable-package.R ├── rhandsontable.R └── zzz.R ├── README.md ├── appveyor.yml ├── docs ├── custom.css ├── include │ └── footer.html ├── index.Rmd ├── index.html └── libs │ ├── bootstrap-3.3.5 │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ ├── cerulean.min.css │ │ ├── cosmo.min.css │ │ ├── darkly.min.css │ │ ├── flatly.min.css │ │ ├── fonts │ │ │ ├── Lato.ttf │ │ │ ├── LatoBold.ttf │ │ │ ├── LatoItalic.ttf │ │ │ ├── NewsCycle.ttf │ │ │ ├── NewsCycleBold.ttf │ │ │ ├── OpenSans.ttf │ │ │ ├── OpenSansBold.ttf │ │ │ ├── OpenSansBoldItalic.ttf │ │ │ ├── OpenSansItalic.ttf │ │ │ ├── OpenSansLight.ttf │ │ │ ├── OpenSansLightItalic.ttf │ │ │ ├── Raleway.ttf │ │ │ ├── RalewayBold.ttf │ │ │ ├── Roboto.ttf │ │ │ ├── RobotoBold.ttf │ │ │ ├── RobotoLight.ttf │ │ │ ├── RobotoMedium.ttf │ │ │ ├── SourceSansPro.ttf │ │ │ ├── SourceSansProBold.ttf │ │ │ ├── SourceSansProItalic.ttf │ │ │ ├── SourceSansProLight.ttf │ │ │ └── Ubuntu.ttf │ │ ├── journal.min.css │ │ ├── lumen.min.css │ │ ├── paper.min.css │ │ ├── readable.min.css │ │ ├── sandstone.min.css │ │ ├── simplex.min.css │ │ ├── spacelab.min.css │ │ ├── united.min.css │ │ └── yeti.min.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ └── npm.js │ └── shim │ │ ├── html5shiv.min.js │ │ └── respond.min.js │ ├── chroma-1.3.3 │ └── chroma.min.js │ ├── handsontable-6.2.2 │ ├── all.min.js │ ├── handsontable.full.min.css │ └── handsontable.full.min.js │ ├── header-attrs-2.8 │ └── header-attrs.js │ ├── highlightjs-9.12.0 │ ├── default.css │ ├── highlight.js │ └── textmate.css │ ├── htmlwidgets-1.5.1 │ └── htmlwidgets.js │ ├── htmlwidgets-1.5.3 │ └── htmlwidgets.js │ ├── jquery-3.2.1 │ └── jquery.min.js │ ├── jqueryui-1.11.4 │ ├── README │ ├── images │ │ ├── ui-icons_444444_256x240.png │ │ ├── ui-icons_555555_256x240.png │ │ ├── ui-icons_777620_256x240.png │ │ ├── ui-icons_777777_256x240.png │ │ ├── ui-icons_cc0000_256x240.png │ │ └── ui-icons_ffffff_256x240.png │ ├── index.html │ ├── jquery-ui.css │ ├── jquery-ui.js │ ├── jquery-ui.min.css │ ├── jquery-ui.min.js │ ├── jquery-ui.structure.css │ ├── jquery-ui.structure.min.css │ ├── jquery-ui.theme.css │ └── jquery-ui.theme.min.css │ ├── navigation-1.1 │ ├── codefolding.js │ ├── sourceembed.js │ └── tabsets.js │ ├── numbro.languages-2.0.6 │ └── languages.min.js │ ├── rhandsontable-0.3.7 │ ├── lib │ │ ├── chroma │ │ │ └── chroma.min.js │ │ ├── handsontable │ │ │ ├── all.min.js │ │ │ ├── handsontable.full.min.css │ │ │ └── handsontable.full.min.js │ │ ├── jquery │ │ │ └── jquery.min.js │ │ ├── numbro │ │ │ └── languages.min.js │ │ └── sparkline │ │ │ └── jquery.sparkline.min.js │ ├── rhandsontable.css │ ├── rhandsontable.js │ └── rhandsontable.yaml │ ├── rhandsontable-binding-0.3.7 │ └── rhandsontable.js │ ├── rhandsontable-binding-0.3.707 │ └── rhandsontable.js │ ├── rhandsontable-binding-0.3.8 │ └── rhandsontable.js │ ├── sparkline-2.1.2 │ └── jquery.sparkline.min.js │ └── tocify-1.9.1 │ ├── jquery.tocify.css │ └── jquery.tocify.js ├── inst ├── examples │ ├── context_menu.R │ ├── images │ │ └── rhandsontable_readme.png │ ├── rhandsontable_comment │ │ ├── server.R │ │ └── ui.R │ ├── rhandsontable_corr │ │ ├── returns.rds │ │ ├── rsconnect │ │ │ └── shinyapps.io │ │ │ │ └── jrowen │ │ │ │ └── rhandsontable_corr.dcf │ │ ├── server.R │ │ └── ui.R │ ├── rhandsontable_dash │ │ └── app.R │ ├── rhandsontable_datafile │ │ ├── mtcars.csv │ │ ├── rsconnect │ │ │ └── shinyapps.io │ │ │ │ └── jrowen │ │ │ │ └── rhandsontable_datafile.dcf │ │ ├── server.R │ │ └── ui.R │ ├── rhandsontable_frontier │ │ ├── returns.rds │ │ ├── rsconnect │ │ │ └── shinyapps.io │ │ │ │ └── jrowen │ │ │ │ └── rhandsontable_frontier.dcf │ │ ├── server.R │ │ └── ui.R │ ├── rhandsontable_highlight │ │ └── app.R │ ├── rhandsontable_output │ │ ├── rsconnect │ │ │ └── shinyapps.io │ │ │ │ └── jrowen │ │ │ │ └── rhandsontable_output.dcf │ │ ├── server.R │ │ └── ui.R │ ├── rhandsontable_portfolio │ │ ├── returns.rds │ │ ├── rsconnect │ │ │ └── shinyapps.io │ │ │ │ └── jrowen │ │ │ │ └── rhandsontable_portfolio.dcf │ │ ├── server.R │ │ └── ui.R │ ├── rhandsontable_search │ │ ├── life_expectancy.csv │ │ ├── rsconnect │ │ │ └── shinyapps.io │ │ │ │ └── ginberg │ │ │ │ └── rhandsontable_search.dcf │ │ ├── server.R │ │ └── ui.R │ ├── rmarkdown │ │ ├── flexdash_example.Rmd │ │ └── flexdash_example.html │ ├── sparkline.R │ └── types.R ├── htmlwidgets │ ├── lib │ │ ├── chroma │ │ │ └── chroma.min.js │ │ ├── handsontable │ │ │ ├── all.min.js │ │ │ ├── handsontable.full.min.css │ │ │ └── handsontable.full.min.js │ │ ├── jquery │ │ │ └── jquery.min.js │ │ ├── numbro │ │ │ └── languages.min.js │ │ └── sparkline │ │ │ └── jquery.sparkline.min.js │ ├── rhandsontable.css │ ├── rhandsontable.js │ └── rhandsontable.yaml └── rstudio │ └── addins.dcf ├── man ├── editAddin.Rd ├── hot_cell.Rd ├── hot_col.Rd ├── hot_cols.Rd ├── hot_context_menu.Rd ├── hot_heatmap.Rd ├── hot_row.Rd ├── hot_rows.Rd ├── hot_table.Rd ├── hot_to_r.Rd ├── hot_validate_character.Rd ├── hot_validate_numeric.Rd ├── rHandsontableOutput.Rd ├── renderRHandsontable.Rd ├── rhandsontable-exports.Rd ├── rhandsontable-package.Rd ├── rhandsontable.Rd └── set_data.Rd ├── rhandsontable.Rproj └── vignettes └── intro_rhandsontable.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^\.gitignore 2 | ^.*\.Rproj$ 3 | ^\.Rproj\.user$ 4 | README.md 5 | ^\.travis\.yml$ 6 | ^appveyor\.yml$ 7 | docs$ 8 | inst/examples$ 9 | ^.bumpversion.cfg$ 10 | -------------------------------------------------------------------------------- /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 0.3.7 3 | commit = False 4 | tag = False 5 | 6 | [bumpversion:file:DESCRIPTION] 7 | 8 | [bumpversion:file:NEWS] 9 | 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | data/* binary 3 | src/* text=lf 4 | R/* text=lf 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | inst/doc 5 | vignettes/rsconnect 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: r 2 | cache: packages 3 | 4 | r: 5 | - oldrel 6 | - release 7 | - devel 8 | 9 | addons: 10 | apt: 11 | packages: 12 | - libv8-dev 13 | 14 | r_github_packages: 15 | rstudio/rstudioapi 16 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: rhandsontable 2 | Type: Package 3 | Title: Interface to the 'Handsontable.js' Library 4 | Version: 0.3.9 5 | Authors@R: c( 6 | person("Jonathan", "Owen", email = "jonathanro@gmail.com", 7 | role = c("aut", "cre", "cph")), 8 | person("Jeff", "Allen", role = c("ctb")), 9 | person("Yihui", "Xie", role = c("ctb")), 10 | person("Enzo", "Martoglio", 11 | email = "enzo@smartinsightsfromdata.com", role = c("ctb")), 12 | person("Inberg", "Ger", role = c("ctb")), 13 | person("Warpechowski", "Marcin", role = c("ctb", "cph"), comment = "Handsontable.js library"), 14 | person("Handsoncode sp. z o.o.", role = c("ctb", "cph"), comment = "Handsontable.js library"), 15 | person("Aisch", "Gregor", role = c("ctb", "cph"), comment = "Chroma.js library"), 16 | person("Företagsplatsen", role = c("ctb", "cph"), comment = "Numbro.js library"), 17 | person("Draper", "Adam", role = c("ctb", "cph"), comment = "Numeral.js library"), 18 | person("Wood", "Tim", role = c("ctb", "cph"), comment = "Moment.js library"), 19 | person("Chernev", "Iskren", role = c("ctb", "cph"), comment = "Moment.js library"), 20 | person("Moment.js contributors", role = c("ctb", "cph"), comment = "Moment.js library"), 21 | person("Bushell", "David", role = c("ctb", "cph"), comment = "Pikaday.js library"), 22 | person("jQuery Foundation", role = c("ctb", "cph"), comment = "jQuery.js library"), 23 | person("Splunk Inc", role = c("ctb", "cph"), comment = "Sparkline.js library"), 24 | person("Russell", "Kent", role = c("ctb", "cph"), comment = "Sparkline.js library"), 25 | person("Rohan", "Jon", role = c("ctb", "cph"), comment = "ZeroClipboard library"), 26 | person("Greene", "James", role = c("ctb", "cph"), comment = "ZeroClipboard library"), 27 | person("Hammill", "Dillon", role = c("ctb"))) 28 | Maintainer: Jonathan Owen 29 | Description: An R interface to the 'Handsontable' JavaScript library, which is a 30 | minimalist Excel-like data grid editor. See for details. 31 | License: MIT + file LICENSE 32 | URL: http://jrowen.github.io/rhandsontable/ 33 | BugReports: https://github.com/jrowen/rhandsontable/issues 34 | Imports: 35 | jsonlite, 36 | htmlwidgets (>= 0.3.3), 37 | magrittr, 38 | methods, 39 | utils 40 | Suggests: 41 | knitr, 42 | rmarkdown, 43 | shiny (>= 0.13), 44 | miniUI (>= 0.1.1), 45 | rstudioapi (>= 0.6), 46 | htmltools 47 | VignetteBuilder: knitr 48 | RoxygenNote: 7.1.1 49 | Encoding: UTF-8 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2015-2018 2 | COPYRIGHT HOLDER: Marcin Warpechowski, Handsoncode sp. z o.o., Gregor Aisch, Tim Wood, Iskren Chernev, Moment.js contributors, David Bushell, jQuery Foundation, Splunk Inc, Jon Rohan, James M. Greeneand, Företagsplatsen, Kent Russell and Jonathan Owen 3 | -------------------------------------------------------------------------------- /LICENSE.note: -------------------------------------------------------------------------------- 1 | The rhandsontable package as a whole is distributed under MIT. 2 | 3 | The rhandsontable package includes other open source software components. The following 4 | is a list of these components (full copies of the license agreements used by 5 | these components are included below): 6 | 7 | - handsontable.js, http://handsontable.com/ 8 | - chroma.js, http://old.driven-by-data.net/about/chromajs/ 9 | - moment.js, http://momentjs.com/ 10 | - pikaday.js, https://github.com/dbushell/Pikaday 11 | - ZeroClipboard, http://zeroclipboard.org/ 12 | - jquery, https://github.com/jquery/jquery 13 | - sparkline.js, http://omnipotent.net/jquery.sparkline/ 14 | - numbro.js, http://numbrojs.com/ 15 | 16 | handsontable.js license 17 | --------------------------------------------------------------------- 18 | (The MIT License) 19 | 20 | Copyright (c) 2012-2014 Marcin Warpechowski 21 | Copyright (c) 2015 Handsoncode sp. z o.o. 22 | 23 | Permission is hereby granted, free of charge, to any person obtaining 24 | a copy of this software and associated documentation files (the 25 | 'Software'), to deal in the Software without restriction, including 26 | without limitation the rights to use, copy, modify, merge, publish, 27 | distribute, sublicense, and/or sell copies of the Software, and to 28 | permit persons to whom the Software is furnished to do so, subject to 29 | the following conditions: 30 | 31 | The above copyright notice and this permission notice shall be 32 | included in all copies or substantial portions of the Software. 33 | 34 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 35 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 36 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 37 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 38 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 39 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 40 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 41 | 42 | chroma.js - JavaScript library for color conversions 43 | 44 | Copyright (c) 2011-2017, Gregor Aisch 45 | All rights reserved. 46 | 47 | Redistribution and use in source and binary forms, with or without 48 | modification, are permitted provided that the following conditions are met: 49 | 50 | 1. Redistributions of source code must retain the above copyright notice, this 51 | list of conditions and the following disclaimer. 52 | 53 | 2. Redistributions in binary form must reproduce the above copyright notice, 54 | this list of conditions and the following disclaimer in the documentation 55 | and/or other materials provided with the distribution. 56 | 57 | 3. The name Gregor Aisch may not be used to endorse or promote products 58 | derived from this software without specific prior written permission. 59 | 60 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 61 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 63 | DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 64 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 65 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 66 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 67 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 68 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 69 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 70 | 71 | moment.js license 72 | --------------------------------------------------------------------- 73 | Copyright (c) JS Foundation and other contributors 74 | 75 | Permission is hereby granted, free of charge, to any person 76 | obtaining a copy of this software and associated documentation 77 | files (the "Software"), to deal in the Software without 78 | restriction, including without limitation the rights to use, 79 | copy, modify, merge, publish, distribute, sublicense, and/or sell 80 | copies of the Software, and to permit persons to whom the 81 | Software is furnished to do so, subject to the following 82 | conditions: 83 | 84 | The above copyright notice and this permission notice shall be 85 | included in all copies or substantial portions of the Software. 86 | 87 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 88 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 89 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 90 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 91 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 92 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 94 | OTHER DEALINGS IN THE SOFTWARE. 95 | 96 | pikaday.js license 97 | --------------------------------------------------------------------- 98 | Copyright (c) 2014 David Bushell BSD & MIT license 99 | 100 | The MIT License (MIT) 101 | 102 | Copyright (c) 2014 David Bushell 103 | 104 | Permission is hereby granted, free of charge, to any person obtaining a copy 105 | of this software and associated documentation files (the "Software"), to deal 106 | in the Software without restriction, including without limitation the rights 107 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 108 | copies of the Software, and to permit persons to whom the Software is 109 | furnished to do so, subject to the following conditions: 110 | 111 | The above copyright notice and this permission notice shall be included in 112 | all copies or substantial portions of the Software. 113 | 114 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 115 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 116 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 117 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 118 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 119 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 120 | THE SOFTWARE. 121 | 122 | The BSD License 123 | 124 | Copyright (c) 2014 David Bushell 125 | All rights reserved. 126 | 127 | Redistribution and use in source and binary forms, with or without 128 | modification, are permitted provided that the following conditions are met: 129 | 130 | 1. Redistributions of source code must retain the above copyright notice, 131 | this list of conditions and the following disclaimer. 132 | 133 | 2. Redistributions in binary form must reproduce the above copyright notice, 134 | this list of conditions and the following disclaimer in the documentation 135 | and/or other materials provided with the distribution. 136 | 137 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 138 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 139 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 140 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 141 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 142 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 143 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 144 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 145 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 146 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 147 | THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 148 | 149 | ZeroClipboard license 150 | --------------------------------------------------------------------- 151 | The MIT License (MIT) 152 | Copyright (c) 2009-2017 Jon Rohan, James M. Greene 153 | 154 | Permission is hereby granted, free of charge, to any person obtaining a 155 | copy of this software and associated documentation files (the "Software"), 156 | to deal in the Software without restriction, including without limitation 157 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 158 | and/or sell copies of the Software, and to permit persons to whom the 159 | Software is furnished to do so, subject to the following conditions: 160 | 161 | The above copyright notice and this permission notice shall be included 162 | in all copies or substantial portions of the Software. 163 | 164 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 165 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 166 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 167 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 168 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 169 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 170 | 171 | jQuery license 172 | ---------------------------------------------------------------------- 173 | Copyright JS Foundation and other contributors, https://js.foundation/ 174 | 175 | This software consists of voluntary contributions made by many 176 | individuals. For exact contribution history, see the revision history 177 | available at https://github.com/jquery/jquery 178 | 179 | The following license applies to all parts of this software except as 180 | documented below: 181 | 182 | ==== 183 | 184 | Permission is hereby granted, free of charge, to any person obtaining 185 | a copy of this software and associated documentation files (the 186 | "Software"), to deal in the Software without restriction, including 187 | without limitation the rights to use, copy, modify, merge, publish, 188 | distribute, sublicense, and/or sell copies of the Software, and to 189 | permit persons to whom the Software is furnished to do so, subject to 190 | the following conditions: 191 | 192 | The above copyright notice and this permission notice shall be 193 | included in all copies or substantial portions of the Software. 194 | 195 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 196 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 197 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 198 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 199 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 200 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 201 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 202 | 203 | ==== 204 | 205 | All files located in the node_modules and external directories are 206 | externally maintained libraries used by this software which have their 207 | own licenses; we recommend you read them, as their terms may differ from 208 | the terms above. 209 | 210 | sparkline.js license 211 | ---------------------------------------------------------------------- 212 | License: New BSD License 213 | 214 | Copyright (c) 2012, Splunk Inc. 215 | All rights reserved. 216 | 217 | Redistribution and use in source and binary forms, with or without modification, 218 | are permitted provided that the following conditions are met: 219 | 220 | * Redistributions of source code must retain the above copyright notice, 221 | this list of conditions and the following disclaimer. 222 | * Redistributions in binary form must reproduce the above copyright notice, 223 | this list of conditions and the following disclaimer in the documentation 224 | and/or other materials provided with the distribution. 225 | * Neither the name of Splunk Inc nor the names of its contributors may 226 | be used to endorse or promote products derived from this software without 227 | specific prior written permission. 228 | 229 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 230 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 231 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 232 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 233 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 234 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 235 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 236 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 237 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 239 | 240 | numbro.js license 241 | ---------------------------------------------------------------------- 242 | Copyright (c) 2015-2017 Företagsplatsen 243 | Copyright (c) 2017 Benjamin Van Ryseghem 244 | 245 | Permission is hereby granted, free of charge, to any person 246 | obtaining a copy of this software and associated documentation 247 | files (the "Software"), to deal in the Software without 248 | restriction, including without limitation the rights to use, 249 | copy, modify, merge, publish, distribute, sublicense, and/or sell 250 | copies of the Software, and to permit persons to whom the 251 | Software is furnished to do so, subject to the following 252 | conditions: 253 | 254 | The above copyright notice and this permission notice shall be 255 | included in all copies or substantial portions of the Software. 256 | 257 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 258 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 259 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 260 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 261 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 262 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 263 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 264 | OTHER DEALINGS IN THE SOFTWARE. 265 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export("%>%") 4 | export(editAddin) 5 | export(hot_cell) 6 | export(hot_col) 7 | export(hot_cols) 8 | export(hot_context_menu) 9 | export(hot_heatmap) 10 | export(hot_row) 11 | export(hot_rows) 12 | export(hot_table) 13 | export(hot_to_r) 14 | export(hot_validate_character) 15 | export(hot_validate_numeric) 16 | export(rHandsontableOutput) 17 | export(renderRHandsontable) 18 | export(rhandsontable) 19 | export(set_data) 20 | import(htmlwidgets) 21 | import(jsonlite) 22 | importFrom(magrittr,"%>%") 23 | importFrom(methods,as) 24 | importFrom(utils,capture.output) 25 | importFrom(utils,head) 26 | importFrom(utils,modifyList) 27 | importFrom(utils,tail) 28 | importFrom(utils,type.convert) 29 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | rhandsontable 0.3.8 2 | ------------------------- 3 | 4 | * Fix typo in `hot_context_menu()` to throw warning when `useTypes = TRUE` and `allowColEdit = TRUE` (#360) 5 | 6 | * Make sure `genRowHeaders` code is only called after a `afterCreateRow` or `afterRemoveRow` event (#360) 7 | 8 | * Use `utils::type_convert()` to handle type conversion of column initiated with logical class (#360) 9 | 10 | * Bypass NA to FALSE conversion when rows are added to empty columns (#360) 11 | 12 | rhandsontable 0.3.7 13 | ------------------------- 14 | 15 | * Updated to handsontable 6.2.2; fixed language support 16 | 17 | * Added the set_data function to wrap handsontable.setDataAtCell (#279) 18 | 19 | * Fixed heatmap formating (#250) 20 | 21 | * Fix shiny search example to use new plugin (#285) 22 | 23 | * Fix valign (#231) 24 | 25 | * Fix decimal values (#256) 26 | 27 | * Modified the select callback to return all indices of multi-row/col selections (#257) 28 | 29 | * Add a callback for afterRowMove event (#289) 30 | 31 | rhandsontable 0.3.6 32 | ------------------------- 33 | 34 | * Adjust JavaScript to support RStudio viewer 35 | 36 | * Updated numeric formatting to support handsontable changes (#213) 37 | 38 | * Fix sync issue in shiny when table first loads (#216) 39 | 40 | * Added readOnly option for rows and cells (#214) 41 | 42 | rhandsontable 0.3.5 43 | ------------------------- 44 | 45 | * Improved data.table and tibble handing (#115, #186) 46 | 47 | * Improved NA handling (#189, thanks to marciz for submitting) 48 | 49 | * Added search functionality to Shiny (#203, thanks to Ger Inburg for submitting) 50 | 51 | * Updated csvString to support additional file formats (#209, thanks to camold for submitting) 52 | 53 | * Made some changes to prevent double table loading in shiny (#188, #137, thanks to marciz for suggesting) 54 | 55 | * Added encoding to DESCRIPTION and updated LICENSE files 56 | 57 | * Updated to handsontable 0.35.0, numbro 1.10.1, chroma 1.3.3 and jquery 3.2.1 (see https://github.com/handsontable/handsontable/releases). 58 | 59 | * Fixed an issue with copying data into the table (#124) 60 | 61 | * Fixed and issues with shiny updates when new row are added (#125, #160) 62 | 63 | * Updated documentation to refer to Numbro.js and fixed renderer examples 64 | 65 | * Changed NA behavior to null (#153, thanks to @marciz for submitting) 66 | 67 | * Add support for empty tables (#171, thanks to Tim Jones for submitting) 68 | 69 | * Fixed a bug when not specifying headers on a read-only table (#174) 70 | 71 | * Fixed comment callback index for sorted tables (#183, thanks to Ryan Kennedy for submitting) 72 | 73 | rhandsontable 0.3.4 74 | ------------------------- 75 | 76 | * Added the ability to pass custom parameters to the table. A good example of their use can be found in the row Custom Renderer Using an R Parameter example (http://jrowen.github.io/rhandsontable/#custom_renderer) and rhandsontable_highlight shiny app. 77 | 78 | * Updated to handsontable 0.28.4 (see https://github.com/handsontable/handsontable/releases). 79 | 80 | * Fixed an issue with the auto column width (#109) 81 | 82 | * Fixed an issues with row.names (#112) 83 | 84 | * Fixed an issue with update event order (#111, #113) 85 | 86 | * Fixed an issue with the rhandsontable_datafile example (#117) 87 | 88 | rhandsontable 0.3.3 89 | ------------------------- 90 | 91 | * POSSIBLE BREAKING CHANGE: Updated shiny logic to fire an afterChange event when the table is first populated. This should not initialize the table input when first loaded and simplify shiny logic. 92 | 93 | * Updated to handsontable 0.26.1 (see https://github.com/handsontable/handsontable/releases). Note the the number formatting library has switched to numbro.js (http://numbrojs.com/languages.html), and the format for the language parameter has changed slightly (e.g. en-US, de-DE, ja-JP, etc.) 94 | 95 | * Updated toR parser to support data.table. 96 | 97 | * Fixed bug with toR when table column names differ from data column names (#100) 98 | 99 | rhandsontable 0.3.2 100 | ------------------------- 101 | 102 | * Updates to handsontable 0.25.1 (see https://github.com/handsontable/handsontable/releases). 103 | 104 | * Added Edit a Data Frame addin for RStudio 105 | 106 | * Added a language parameter to hot_col that supports changing the column formatting locale 107 | 108 | * Added rowHeaderWidth to hot_table to allow specifying the rowHeader column width 109 | 110 | * Added digits to rhandsontable, which is passed to jsonlite::toJSON 111 | 112 | * Fixed shiny bug with mixed numeric and character column names (#77) 113 | 114 | rhandsontable 0.3.1 115 | ------------------------- 116 | 117 | * Fixed bug with comments (#66) 118 | 119 | * Fixed bug with single column table (#69) 120 | 121 | * Added overflow parameter to hot_table 122 | 123 | * Updates to handsontable 0.23.0 (see https://github.com/handsontable/handsontable/releases). 124 | 125 | rhandsontable 0.3 126 | ------------------------- 127 | 128 | * Updated to handsontable 0.20.1 (see https://github.com/handsontable/handsontable/releases). Row and column grouping no longer supported in open source version. 129 | 130 | * Fixed a bug that didn't return the changed column and row index when the table is sorted (#56) 131 | 132 | * Fixed a bug that didn't allow column formatting when the column headers were NULL (#57) 133 | 134 | rhandsontable 0.2.2 135 | ------------------------- 136 | 137 | * Added support in shiny for default column values when new row added (#33) 138 | 139 | * Fixed bug that jumbled columns when some column names were numeric (#47, #52) 140 | 141 | * Fixed a bug in the validation logic that was preventing the call background from changing to red for invalid entries when allowInvalid = TRUE (#48) 142 | 143 | rhandsontable 0.2.1 144 | ------------------------- 145 | 146 | * Added a new function, hot_context_menu, to better control right-click menu. The option to export to csv has been removed for now, but a new context_menu example has been added that shows how to enable the option. The example also shows how to enable the table search functionality (#38, #41). 147 | 148 | * Added a new comments parameter to rhandsontable to allow bulk comment specification. 149 | 150 | * Added a new shiny _comment callback to track changes to table comments. See the new rhandsontable_comment example for more details. 151 | 152 | * Added dateFormat to hot_col and allow passing additional column parameters. Future updates should hopefully allow more control over date formatting. 153 | 154 | * Fixed a table resize bug (#26) 155 | 156 | * Fixed hot_to_r to preserve original data classes when useTypes = FALSE (#39). See the rhandsontable_output example for more details. 157 | 158 | * Fixed shiny select callback to use 1-based indices (instead of JavaScripts 0-based indices). 159 | 160 | rhandsontable 0.2 161 | ------------------------- 162 | 163 | * Added a project page at http://jrowen.github.io/rhandsontable 164 | 165 | * Upgraded to handsontable 0.16.1 166 | 167 | * Improved mapping between R classes and handsontable column types. Numeric columns 168 | in R are now mapped to numeric columns in the table, and factors are now 169 | mapped as dropdown columns (#30). 170 | 171 | * Numeric columns are now formatted as '0' for integers and '0.00' for all other 172 | numeric columns. See http://http://numeraljs.com/ for more details on 173 | formatting options. 174 | 175 | * Sparkline charts (http://omnipotent.net/jquery.sparkline/) can now be added to the 176 | table. See the project page for examples, and thanks to the sparkline package and 177 | Ramnath Vaidyanathan for inspiration. The sparkline chart width will be 178 | set to fit within the specified column width. The feature is still evolving, so 179 | please pass along feedback. 180 | 181 | * Display NA values as blank cells in the table. This requires changing colums with NA 182 | values to character when displaying in handsontable and may require special handling 183 | for Date and factor columns. See the examples on the project page for more details. 184 | Thanks to Melanie Bacou for the suggestion. 185 | 186 | * Added stretchH parameter to hot_table. 187 | 188 | * Fixed a bug where the table was not updated when resized. 189 | 190 | * Fixed a bug with row indices when sorting rows (#34) 191 | 192 | * Set overflow: auto and specified a default height = 400 in shiny (#21). 193 | 194 | rhandsontable 0.1 195 | ------------------------- 196 | 197 | * Initial version. 198 | -------------------------------------------------------------------------------- /R/editAddin.R: -------------------------------------------------------------------------------- 1 | #' Edit a Data Frame. 2 | #' 3 | #' Interactively edit a \code{data.frame} or \code{data.table}. The resulting 4 | #' code will be emitted as a call to reload the data from a temp RDS file. 5 | #' 6 | #' This addin can be used to interactively edit. The intended way to use this is 7 | #' as follows: 8 | #' 9 | #' 1. Highlight a symbol naming a \code{data.frame} or \code{data.table} in your 10 | #' R session, e.g. \code{mtcars}. 2. Execute this addin, to interactively edit 11 | #' it. 12 | #' 13 | #' When you're done, the code performing this operation will be emitted at the 14 | #' cursor position. 15 | #' 16 | #' This function borrows heavily from 17 | #' \href{https://github.com/rstudio/addinexamples/blob/master/R/subsetAddin.R}{rstudio/addinexamples/subsetAddin} 18 | #' 19 | #' @export 20 | editAddin <- function() { 21 | 22 | # Get the document context. 23 | context <- rstudioapi::getActiveDocumentContext() 24 | 25 | # Set the default data to use based on the selection. 26 | text <- context$selection[[1]]$text 27 | defaultData <- text 28 | 29 | # create a temp file 30 | fname = gsub("\\\\", "/", tempfile()) 31 | 32 | # Generate UI for the gadget. 33 | ui <- miniUI::miniPage( 34 | miniUI::gadgetTitleBar("Edit a data.frame"), 35 | miniUI::miniContentPanel( 36 | stableColumnLayout( 37 | shiny::textInput("data", "Data", value = defaultData), 38 | shiny::radioButtons("outType", "Output type", 39 | choices = c("Update original data" = "update", 40 | "Print updates to script (no update)" = "print") 41 | ) 42 | ), 43 | shiny::uiOutput("pending"), 44 | rHandsontableOutput("hot") 45 | ) 46 | ) 47 | 48 | # Server code for the gadget. 49 | server <- function(input, output, session) { 50 | values = shiny::reactiveValues() 51 | setHot = function(x) values[["hot"]] = x 52 | 53 | reactiveData <- shiny::reactive({ 54 | 55 | # Collect inputs. 56 | dataString <- input$data 57 | 58 | # Check to see if there is data called 'data', 59 | # and access it if possible. 60 | if (!nzchar(dataString)) 61 | return(errorMessage("data", "No dataset available.")) 62 | 63 | if (!exists(dataString, envir = .GlobalEnv)) 64 | return(errorMessage("data", paste("No dataset named '", dataString, "' available."))) 65 | 66 | data <- get(dataString, envir = .GlobalEnv) 67 | 68 | data 69 | }) 70 | 71 | output$pending <- shiny::renderUI({ 72 | data <- reactiveData() 73 | if (isErrorMessage(data)) 74 | htmltools::h4(style = "color: #AA7732;", data$message) 75 | }) 76 | 77 | output$hot <- renderRHandsontable({ 78 | data <- reactiveData() 79 | if (isErrorMessage(data)) 80 | return(NULL) 81 | 82 | if (is.null(input$hot)) 83 | DF = data 84 | else 85 | DF = hot_to_r(input$hot) 86 | 87 | setHot(DF) 88 | rhandsontable(DF) %>% 89 | hot_table(highlightCol = TRUE, highlightRow = TRUE) 90 | }) 91 | 92 | # Listen for 'done'. 93 | shiny::observeEvent(input$done, { 94 | 95 | if (input$outType == "print") { 96 | rslt <- capture.output(dput(values[["hot"]])) 97 | rstudioapi::insertText(Inf, paste0(input$data, " = ", 98 | paste(rslt, collapse = "\n"))) 99 | } else { 100 | if (nzchar(input$data) && !is.null(values[["hot"]])) { 101 | saveRDS(values[["hot"]], fname) 102 | code <- paste(input$data, " = readRDS('", fname, "')", sep = "") 103 | rstudioapi::sendToConsole(code) 104 | } 105 | } 106 | 107 | invisible(shiny::stopApp()) 108 | }) 109 | } 110 | 111 | # Use a modal dialog as a viewr. 112 | viewer <- shiny::dialogViewer("Edit", width = 1000, height = 800) 113 | shiny::runGadget(ui, server, viewer = viewer) 114 | 115 | } 116 | 117 | # these functions come from rstudio/addinexamples 118 | stableColumnLayout <- function(...) { 119 | dots <- list(...) 120 | n <- length(dots) 121 | width <- 12 / n 122 | class <- sprintf("col-xs-%s col-md-%s", width, width) 123 | shiny::fluidRow( 124 | lapply(dots, function(el) { 125 | shiny::div(class = class, el) 126 | }) 127 | ) 128 | } 129 | 130 | isErrorMessage <- function(object) { 131 | inherits(object, "error_message") 132 | } 133 | 134 | errorMessage <- function(type, message) { 135 | structure( 136 | list(type = type, message = message), 137 | class = "error_message" 138 | ) 139 | } 140 | -------------------------------------------------------------------------------- /R/misc.R: -------------------------------------------------------------------------------- 1 | # Map R classes to handsontable.js types 2 | get_col_types = function(data) { 3 | if (is.matrix(data)) { 4 | types = rep(typeof(data), ncol(data)) 5 | } else if (is.data.frame(data)){ 6 | types = as.character(lapply(data, class)) 7 | } else{ 8 | stop("Unsupported object type: ", class(data), " Can't extract column types.") 9 | } 10 | 11 | types <- sapply(types, function(type) { 12 | if (grepl("factor", type)) return("factor") 13 | 14 | switch(type, 15 | integer="integer", 16 | double="numeric", 17 | numeric="numeric", 18 | character="text", 19 | logical="checkbox", 20 | Date="date", 21 | "text") 22 | }) 23 | 24 | as.character(types) 25 | } 26 | 27 | # Convert handsontable to R object 28 | toR = function(data, changes, params, ...) { 29 | rClass = params$rClass 30 | colHeaders = unlist(params$rColHeaders) 31 | rowHeaders = unlist(params$rRowHeaders) 32 | rColClasses = unlist(params$rColClasses)[colHeaders] 33 | 34 | out = data 35 | 36 | # copy/paste may add rows without firing an afterCreateRow event (still needed?) 37 | # if (length(out) != length(rowHeaders)) 38 | # changes$event = "afterCreateRow" 39 | 40 | # remove spare empty rows; autofill fix (not working) 41 | # if (!is.null(changes$source) && changes$source == "autofill") { 42 | # rm_inds = sapply(out, function(x) all(unlist(x) == "NA")) 43 | # rm_inds = suppressWarnings(min(which(diff(rm_inds) == -1))) 44 | # if (rm_inds != Inf) 45 | # out = out[-(length(out) - rm_inds + 1)] 46 | # } 47 | 48 | # pre-conversion updates; afterCreateCol moved to end of function 49 | # if (changes$event == "afterCreateRow") { 50 | # inds = seq(changes$ind + 1, length.out = changes$ct) 51 | # # prevent duplicates 52 | # nm = 1 53 | # while (nm %in% rowHeaders) { 54 | # nm = nm + 1 55 | # } 56 | # rowHeaders = c(head(rowHeaders, inds - 1), nm, 57 | # tail(rowHeaders, length(rowHeaders) - inds + 1)) 58 | # } else if (changes$event == "afterRemoveRow") { 59 | # inds = seq(changes$ind + 1, length.out = changes$ct) 60 | # rowHeaders = rowHeaders[-inds] 61 | if (changes$event == "afterRemoveCol") { 62 | if (!("matrix" %in% rClass)) { 63 | inds = seq(changes$ind + 1, 1, length.out = changes$ct) 64 | rColClasses = rColClasses[-inds] 65 | } 66 | } 67 | 68 | # convert 69 | if ("matrix" %in% rClass) { 70 | nr = length(out) 71 | out = unlist(out, recursive = FALSE) 72 | # replace NULL with NA 73 | out = unlist(lapply(out, function(x) if (is.null(x)) NA else x)) 74 | 75 | # If there is no data create empty matrix 76 | if (length(out) == 0) { 77 | out = matrix(nrow = 0, ncol = length(colHeaders)) 78 | } else { 79 | out = matrix(out, nrow = nr, byrow = TRUE) 80 | } 81 | 82 | class(out) = params$rColClasses 83 | 84 | } else if ("data.frame" %in% rClass) { 85 | nr = length(out) 86 | 87 | out = unlist(out, recursive = FALSE) 88 | # replace NULL with NA 89 | out = unlist(lapply(out, function(x) if (is.null(x)) NA else x)) 90 | 91 | # If there is no data create empty matrix 92 | if (length(out) == 0) { 93 | out = matrix(nrow = 0, ncol = length(colHeaders)) 94 | } else { 95 | out = matrix(out, nrow = nr, byrow = TRUE) 96 | } 97 | 98 | out = colClasses(as.data.frame(out, stringsAsFactors = FALSE), 99 | rColClasses, params$columns, ...) 100 | } else { 101 | stop("Conversion not implemented: ", rClass) 102 | } 103 | 104 | 105 | # post-conversion updates 106 | if (changes$event == "afterCreateRow") { 107 | # default logical NA in data.frame to FALSE 108 | if (!("matrix" %in% rClass)) { 109 | inds_logical = which(rColClasses == "logical") 110 | for (i in inds_logical) 111 | # bypass empty columns 112 | if(!all(is.na(out[[i]]))) { 113 | out[[i]] = ifelse(is.na(out[[i]]), FALSE, out[[i]]) 114 | } 115 | } 116 | } 117 | 118 | if (ncol(out) != length(colHeaders)) 119 | colHeaders = genColHeaders(changes, colHeaders) 120 | 121 | if (nrow(out) != length(rowHeaders) && !is.null(rowHeaders)) 122 | rowHeaders = genRowHeaders(changes, rowHeaders) 123 | 124 | colnames(out) = colHeaders 125 | rownames(out) = rowHeaders 126 | 127 | if ("data.table" %in% rClass) 128 | out = as(out, "data.table") 129 | 130 | out 131 | } 132 | 133 | # Coerces data.frame columns to the specified classes 134 | # see http://stackoverflow.com/questions/9214819/supply-a-vector-to-classes-of-dataframe 135 | colClasses <- function(d, colClasses, cols, date_fmt = "%m/%d/%Y", ...) { 136 | colClasses <- rep(colClasses, len=length(d)) 137 | for(i in seq_along(d)) 138 | d[[i]] = switch( 139 | colClasses[i], 140 | numeric = as.numeric(d[[i]]), 141 | Date = as.Date(d[[i]], origin='1970-01-01', 142 | format = date_fmt), 143 | POSIXct = as.POSIXct(d[[i]], origin='1970-01-01', 144 | format = date_fmt), 145 | factor = factor(d[[i]], 146 | levels = c(unlist(cols[[i]]$source), 147 | unique(d[[i]][!(d[[i]] %in% unlist(cols[[i]]$source))])), 148 | ordered = TRUE), 149 | json = jsonlite::toJSON(d[[i]]), 150 | logical = type.convert(d[[i]], as.is = TRUE), # new columns - character/numeric 151 | suppressWarnings(as(d[[i]], colClasses[i]))) 152 | d 153 | } 154 | 155 | genColHeaders <- function(changes, colHeaders) { 156 | ind_ct = length(which(grepl("V[0-9]{1,}", colHeaders))) 157 | 158 | if (changes$event == "afterRemoveCol") { 159 | colHeaders[-(seq(changes$ind, length = changes$ct) + 1)] 160 | } else if (changes$event == "afterCreateCol") { 161 | # create new column names 162 | new_cols = paste0("V", changes$ct + ind_ct) 163 | # insert into vector 164 | inds = seq(changes$ind + 1, 1, length.out = changes$ct) 165 | c(colHeaders, new_cols)[order(c(seq_along(colHeaders), inds - 0.5))] 166 | } else { 167 | stop("Change no recognized:", changes$event) 168 | } 169 | } 170 | 171 | genRowHeaders <- function(changes, rowHeaders) { 172 | if(changes$event %in% c("afterCreateRow", "afterRemoveRow")) { 173 | inds = seq(changes$ind + 1, length.out = changes$ct) 174 | if (changes$event == "afterCreateRow") { 175 | # prevent duplicates 176 | nm = 1 177 | while (nm %in% rowHeaders) { 178 | nm = nm + 1 179 | } 180 | c(head(rowHeaders, inds - 1), nm, 181 | tail(rowHeaders, length(rowHeaders) - inds + 1)) 182 | } else if (changes$event == "afterRemoveRow") { 183 | rowHeaders[-inds] 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /R/rhandsontable-package.R: -------------------------------------------------------------------------------- 1 | #' rhandsontable 2 | #' 3 | #' R interface for creating tables using Handsontable, url{https://handsontable.com/} 4 | #' 5 | #' For full documentation on the package, visit \url{https://jrowen.github.io/rhandsontable/} 6 | #' @name rhandsontable-package 7 | #' @docType package 8 | #' @import htmlwidgets jsonlite 9 | #' @importFrom utils modifyList capture.output head tail type.convert 10 | #' @importFrom methods as 11 | NULL 12 | 13 | #' rhandsontable exported operators 14 | #' 15 | #' The following functions are imported and then re-exported 16 | #' from the rhandsontable package to enable use of the magrittr 17 | #' pipe operator with no additional library calls 18 | #' 19 | #' @name rhandsontable-exports 20 | NULL 21 | 22 | #' @importFrom magrittr %>% 23 | #' @name %>% 24 | #' @export 25 | #' @rdname rhandsontable-exports 26 | NULL 27 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | .onLoad <- function(...) { 2 | 3 | tryCatch( { 4 | shiny::registerInputHandler("rhandsontable.customSelectDeserializer", 5 | function(x, session, inputName) { 6 | result <- x 7 | result$select$rAll <- unlist(x$select$rAll) 8 | result$select$cAll <- unlist(x$select$cAll) 9 | result}, 10 | force = TRUE ) 11 | }, error = function(err) {}) 12 | } 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/jrowen/rhandsontable.svg?branch=master)](https://travis-ci.org/jrowen/rhandsontable) 2 | [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/jrowen/rhandsontable?branch=master&svg=true)](https://ci.appveyor.com/project/jrowen/rhandsontable) 3 | [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/rhandsontable)](https://cran.r-project.org/package=rhandsontable) 4 | [![CRAN_Download_Badge](https://cranlogs.r-pkg.org/badges/grand-total/rhandsontable)](https://cran.r-project.org/package=rhandsontable) 5 | 6 | **See the [project website](https://jrowen.github.io/rhandsontable/) for more details and live examples, and see below for important details on use in shiny apps.** 7 | 8 | An [`htmlwidgets`](https://www.htmlwidgets.org/) implementation of [Handsontable.js](https://handsontable.com). Per the website: 9 | 10 | *Handsontable is a minimalist Excel-like data grid editor for HTML & JavaScript* 11 | 12 | This library was inspired by the [`shinyTable`](https://github.com/trestletech/shinyTable) package. Most of the original functionality was preserved, and the `htmlwidgets` framework made it possible to leverage even more of the Handsontable.js functionality. 13 | 14 | Note: With v7, `handsontable` went to a more [restrictive license for commercial use](https://github.com/handsontable/handsontable#license-key). To avoid license violations for existing users, `rhandsontable` will not update `handsontable` beyond v6.2.2. This may change in the future if a way is found to manage multiple `handsontable` versions. 15 | 16 | **See the [vignette](https://rpubs.com/jrowen/intro_rhandsontable) for detailed examples and links to shiny apps.** 17 | 18 | To install from CRAN use 19 | ```R 20 | install.packages("rhandsontable") 21 | ``` 22 | For the latest development version use 23 | ```R 24 | devtools::install_github("jrowen/rhandsontable") 25 | ``` 26 | 27 | A simple example 28 | ```R 29 | library(rhandsontable) 30 | 31 | DF = data.frame(int = 1:10, 32 | numeric = rnorm(10), 33 | logical = TRUE, 34 | character = LETTERS[1:10], 35 | fact = factor(letters[1:10]), 36 | date = seq(from = Sys.Date(), by = "days", length.out = 10), 37 | stringsAsFactors = FALSE) 38 | 39 | # add a sparkline chart 40 | DF$chart = sapply(1:10, function(x) jsonlite::toJSON(list(values=rnorm(10)))) 41 | 42 | rhandsontable(DF, rowHeaders = NULL) %>% 43 | hot_col("chart", renderer = htmlwidgets::JS("renderSparkline")) 44 | ``` 45 | ![alt tag](https://raw.github.com/jrowen/rhandsontable/master/inst/examples/images/rhandsontable_readme.png "A simple example") 46 | 47 | A more involved `shiny` example 48 | ```R 49 | shiny::runGitHub("rhandsontable", "jrowen", subdir = "inst/examples/rhandsontable_corr") 50 | ``` 51 | 52 | **Important note on shiny use:** The `htmlwidgets` package creates widgets as shiny output bindings. The `rhandsontable` package also attempts to expose the table as a *pseudo* shiny input binding using handsontable change events (see [here](https://github.com/jrowen/rhandsontable/blob/master/inst/htmlwidgets/rhandsontable.js) for the supported events). **This means the table (e.g. `hot`) can be accessed in shiny using either `input$hot` or `output$hot`, but these values may not be in-sync.** The timing of updates will depend on the particular reactive path followed by your shiny application. 53 | 54 | Since the widget is not currently able to use the standard shiny input binding functionality, you will need to explicitly call the `hot_to_r` function to convert the handsontable data to an R object. 55 | 56 | Two additional inputs are also enabled, `input$hot_select` and `input$hot_comment`, which will fire when a cell selection or a comment changes, respectively (if you would like to see more options, please post an issue or create a PR). 57 | 58 | This functionality is still evolving, so please don't hesitate to share suggestions and PRs. 59 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE the "init" and "install" sections below 2 | 3 | # Download script file from GitHub 4 | init: 5 | ps: | 6 | $ErrorActionPreference = "Stop" 7 | Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" 8 | Import-Module '..\appveyor-tool.ps1' 9 | 10 | install: 11 | ps: Bootstrap 12 | 13 | # Adapt as necessary starting from here 14 | 15 | build_script: 16 | - travis-tool.sh install_deps 17 | 18 | test_script: 19 | - travis-tool.sh run_tests 20 | 21 | on_failure: 22 | - 7z a failure.zip *.Rcheck\* 23 | - appveyor PushArtifact failure.zip 24 | 25 | artifacts: 26 | - path: '*.Rcheck\**\*.log' 27 | name: Logs 28 | 29 | - path: '*.Rcheck\**\*.out' 30 | name: Logs 31 | 32 | - path: '*.Rcheck\**\*.fail' 33 | name: Logs 34 | 35 | - path: '*.Rcheck\**\*.Rout' 36 | name: Logs 37 | 38 | - path: '\*_*.tar.gz' 39 | name: Bits 40 | 41 | - path: '\*_*.zip' 42 | name: Bits 43 | -------------------------------------------------------------------------------- /docs/custom.css: -------------------------------------------------------------------------------- 1 | #TOC { 2 | position: fixed; 3 | left: 0; 4 | top: 50; 5 | width: 250px; 6 | height: 100%; 7 | overflow: auto; 8 | } 9 | 10 | body { 11 | max-width: 800px; 12 | margin: auto; 13 | margin-left:260px; 14 | line-height: 20px; 15 | } -------------------------------------------------------------------------------- /docs/include/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/Lato.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/Lato.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/LatoBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/LatoBold.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/LatoItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/LatoItalic.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/NewsCycle.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/NewsCycle.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/NewsCycleBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/NewsCycleBold.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/OpenSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/OpenSans.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/OpenSansBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/OpenSansBold.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/OpenSansBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/OpenSansBoldItalic.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/OpenSansItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/OpenSansItalic.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/OpenSansLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/OpenSansLight.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/OpenSansLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/OpenSansLightItalic.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/Raleway.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/Raleway.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/RalewayBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/RalewayBold.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/Roboto.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/Roboto.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/RobotoBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/RobotoBold.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/RobotoLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/RobotoLight.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/RobotoMedium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/RobotoMedium.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/SourceSansPro.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/SourceSansPro.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/SourceSansProBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/SourceSansProBold.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/SourceSansProItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/SourceSansProItalic.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/SourceSansProLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/SourceSansProLight.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/css/fonts/Ubuntu.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/css/fonts/Ubuntu.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/bootstrap-3.3.5/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/shim/html5shiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | // Only run this code in IE 8 5 | if (!!window.navigator.userAgent.match("MSIE 8")) { 6 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document); 7 | }; 8 | -------------------------------------------------------------------------------- /docs/libs/bootstrap-3.3.5/shim/respond.min.js: -------------------------------------------------------------------------------- 1 | /*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl 2 | * Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT 3 | * */ 4 | 5 | // Only run this code in IE 8 6 | if (!!window.navigator.userAgent.match("MSIE 8")) { 7 | !function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='­',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b :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 | -------------------------------------------------------------------------------- /docs/libs/highlightjs-9.12.0/default.css: -------------------------------------------------------------------------------- 1 | .hljs-literal { 2 | color: #990073; 3 | } 4 | 5 | .hljs-number { 6 | color: #099; 7 | } 8 | 9 | .hljs-comment { 10 | color: #998; 11 | font-style: italic; 12 | } 13 | 14 | .hljs-keyword { 15 | color: #900; 16 | font-weight: bold; 17 | } 18 | 19 | .hljs-string { 20 | color: #d14; 21 | } 22 | -------------------------------------------------------------------------------- /docs/libs/highlightjs-9.12.0/textmate.css: -------------------------------------------------------------------------------- 1 | .hljs-literal { 2 | color: rgb(88, 72, 246); 3 | } 4 | 5 | .hljs-number { 6 | color: rgb(0, 0, 205); 7 | } 8 | 9 | .hljs-comment { 10 | color: rgb(76, 136, 107); 11 | } 12 | 13 | .hljs-keyword { 14 | color: rgb(0, 0, 255); 15 | } 16 | 17 | .hljs-string { 18 | color: rgb(3, 106, 7); 19 | } 20 | -------------------------------------------------------------------------------- /docs/libs/jqueryui-1.11.4/README: -------------------------------------------------------------------------------- 1 | This a jQuery UI custom build, downloaded from: 2 | http://jqueryui.com/download/#!version=1.11.4&components=1111111111110111111111111111111111111 3 | 4 | It includes all components except the datepicker, because it conflicts with 5 | bootstrap-datepicker that is packaged with Shiny. 6 | 7 | The copy of jQuery that is bundled with the download, under external/, is not 8 | included because Shiny already has its own copy of jQuery. 9 | -------------------------------------------------------------------------------- /docs/libs/jqueryui-1.11.4/images/ui-icons_444444_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/jqueryui-1.11.4/images/ui-icons_444444_256x240.png -------------------------------------------------------------------------------- /docs/libs/jqueryui-1.11.4/images/ui-icons_555555_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/jqueryui-1.11.4/images/ui-icons_555555_256x240.png -------------------------------------------------------------------------------- /docs/libs/jqueryui-1.11.4/images/ui-icons_777620_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/jqueryui-1.11.4/images/ui-icons_777620_256x240.png -------------------------------------------------------------------------------- /docs/libs/jqueryui-1.11.4/images/ui-icons_777777_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/jqueryui-1.11.4/images/ui-icons_777777_256x240.png -------------------------------------------------------------------------------- /docs/libs/jqueryui-1.11.4/images/ui-icons_cc0000_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/jqueryui-1.11.4/images/ui-icons_cc0000_256x240.png -------------------------------------------------------------------------------- /docs/libs/jqueryui-1.11.4/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/docs/libs/jqueryui-1.11.4/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /docs/libs/jqueryui-1.11.4/jquery-ui.structure.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.11.4 - 2016-01-05 2 | * http://jqueryui.com 3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 4 | 5 | .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:0.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:0.4em 2.1em 0.4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px} -------------------------------------------------------------------------------- /docs/libs/jqueryui-1.11.4/jquery-ui.theme.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.11.4 - 2016-01-05 2 | * http://jqueryui.com 3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 4 | 5 | .ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#2b2b2b;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:0 0 0 0;padding:5px;background:#666;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px} -------------------------------------------------------------------------------- /docs/libs/navigation-1.1/codefolding.js: -------------------------------------------------------------------------------- 1 | 2 | window.initializeCodeFolding = function(show) { 3 | 4 | // handlers for show-all and hide all 5 | $("#rmd-show-all-code").click(function() { 6 | $('div.r-code-collapse').each(function() { 7 | $(this).collapse('show'); 8 | }); 9 | }); 10 | $("#rmd-hide-all-code").click(function() { 11 | $('div.r-code-collapse').each(function() { 12 | $(this).collapse('hide'); 13 | }); 14 | }); 15 | 16 | // index for unique code element ids 17 | var currentIndex = 1; 18 | 19 | // select all R code blocks 20 | var rCodeBlocks = $('pre.r, pre.python, pre.bash, pre.sql, pre.cpp, pre.stan, pre.julia, pre.foldable'); 21 | rCodeBlocks.each(function() { 22 | 23 | // create a collapsable div to wrap the code in 24 | var div = $('
'); 25 | var showThis = (show || $(this).hasClass('fold-show')) && !$(this).hasClass('fold-hide'); 26 | var id = 'rcode-643E0F36' + currentIndex++; 27 | div.attr('id', id); 28 | $(this).before(div); 29 | $(this).detach().appendTo(div); 30 | 31 | // add a show code button right above 32 | var showCodeText = $('' + (showThis ? 'Hide' : 'Code') + ''); 33 | var showCodeButton = $(''); 34 | showCodeButton.append(showCodeText); 35 | showCodeButton 36 | .attr('data-toggle', 'collapse') 37 | .attr('data-target', '#' + id) 38 | .attr('aria-expanded', showThis) 39 | .attr('aria-controls', id); 40 | 41 | var buttonRow = $('
'); 42 | var buttonCol = $('
'); 43 | 44 | buttonCol.append(showCodeButton); 45 | buttonRow.append(buttonCol); 46 | 47 | div.before(buttonRow); 48 | 49 | // show the div if necessary 50 | if (showThis) div.collapse('show'); 51 | 52 | // update state of button on show/hide 53 | // * Change text 54 | // * add a class for intermediate states styling 55 | div.on('hide.bs.collapse', function () { 56 | showCodeText.text('Code'); 57 | showCodeButton.addClass('btn-collapsing'); 58 | }); 59 | div.on('hidden.bs.collapse', function () { 60 | showCodeButton.removeClass('btn-collapsing'); 61 | }); 62 | div.on('show.bs.collapse', function () { 63 | showCodeText.text('Hide'); 64 | showCodeButton.addClass('btn-expanding'); 65 | }); 66 | div.on('shown.bs.collapse', function () { 67 | showCodeButton.removeClass('btn-expanding'); 68 | }); 69 | 70 | }); 71 | 72 | } 73 | -------------------------------------------------------------------------------- /docs/libs/navigation-1.1/sourceembed.js: -------------------------------------------------------------------------------- 1 | 2 | window.initializeSourceEmbed = function(filename) { 3 | $("#rmd-download-source").click(function() { 4 | var src = $("#rmd-source-code").html(); 5 | var a = document.createElement('a'); 6 | a.href = "data:text/x-r-markdown;base64," + src; 7 | a.download = filename; 8 | document.body.appendChild(a); 9 | a.click(); 10 | document.body.removeChild(a); 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /docs/libs/navigation-1.1/tabsets.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | /** 4 | * jQuery Plugin: Sticky Tabs 5 | * 6 | * @author Aidan Lister 7 | * adapted by Ruben Arslan to activate parent tabs too 8 | * http://www.aidanlister.com/2014/03/persisting-the-tab-state-in-bootstrap/ 9 | */ 10 | (function($) { 11 | "use strict"; 12 | $.fn.rmarkdownStickyTabs = function() { 13 | var context = this; 14 | // Show the tab corresponding with the hash in the URL, or the first tab 15 | var showStuffFromHash = function() { 16 | var hash = window.location.hash; 17 | var selector = hash ? 'a[href="' + hash + '"]' : 'li.active > a'; 18 | var $selector = $(selector, context); 19 | if($selector.data('toggle') === "tab") { 20 | $selector.tab('show'); 21 | // walk up the ancestors of this element, show any hidden tabs 22 | $selector.parents('.section.tabset').each(function(i, elm) { 23 | var link = $('a[href="#' + $(elm).attr('id') + '"]'); 24 | if(link.data('toggle') === "tab") { 25 | link.tab("show"); 26 | } 27 | }); 28 | } 29 | }; 30 | 31 | 32 | // Set the correct tab when the page loads 33 | showStuffFromHash(context); 34 | 35 | // Set the correct tab when a user uses their back/forward button 36 | $(window).on('hashchange', function() { 37 | showStuffFromHash(context); 38 | }); 39 | 40 | // Change the URL when tabs are clicked 41 | $('a', context).on('click', function(e) { 42 | history.pushState(null, null, this.href); 43 | showStuffFromHash(context); 44 | }); 45 | 46 | return this; 47 | }; 48 | }(jQuery)); 49 | 50 | window.buildTabsets = function(tocID) { 51 | 52 | // build a tabset from a section div with the .tabset class 53 | function buildTabset(tabset) { 54 | 55 | // check for fade and pills options 56 | var fade = tabset.hasClass("tabset-fade"); 57 | var pills = tabset.hasClass("tabset-pills"); 58 | var navClass = pills ? "nav-pills" : "nav-tabs"; 59 | 60 | // determine the heading level of the tabset and tabs 61 | var match = tabset.attr('class').match(/level(\d) /); 62 | if (match === null) 63 | return; 64 | var tabsetLevel = Number(match[1]); 65 | var tabLevel = tabsetLevel + 1; 66 | 67 | // find all subheadings immediately below 68 | var tabs = tabset.find("div.section.level" + tabLevel); 69 | if (!tabs.length) 70 | return; 71 | 72 | // create tablist and tab-content elements 73 | var tabList = $(''); 74 | $(tabs[0]).before(tabList); 75 | var tabContent = $('
'); 76 | $(tabs[0]).before(tabContent); 77 | 78 | // build the tabset 79 | var activeTab = 0; 80 | tabs.each(function(i) { 81 | 82 | // get the tab div 83 | var tab = $(tabs[i]); 84 | 85 | // get the id then sanitize it for use with bootstrap tabs 86 | var id = tab.attr('id'); 87 | 88 | // see if this is marked as the active tab 89 | if (tab.hasClass('active')) 90 | activeTab = i; 91 | 92 | // remove any table of contents entries associated with 93 | // this ID (since we'll be removing the heading element) 94 | $("div#" + tocID + " li a[href='#" + id + "']").parent().remove(); 95 | 96 | // sanitize the id for use with bootstrap tabs 97 | id = id.replace(/[.\/?&!#<>]/g, '').replace(/\s/g, '_'); 98 | tab.attr('id', id); 99 | 100 | // get the heading element within it, grab it's text, then remove it 101 | var heading = tab.find('h' + tabLevel + ':first'); 102 | var headingText = heading.html(); 103 | heading.remove(); 104 | 105 | // build and append the tab list item 106 | var a = $('' + headingText + ''); 107 | a.attr('href', '#' + id); 108 | a.attr('aria-controls', id); 109 | var li = $('
  • '); 110 | li.append(a); 111 | tabList.append(li); 112 | 113 | // set it's attributes 114 | tab.attr('role', 'tabpanel'); 115 | tab.addClass('tab-pane'); 116 | tab.addClass('tabbed-pane'); 117 | if (fade) 118 | tab.addClass('fade'); 119 | 120 | // move it into the tab content div 121 | tab.detach().appendTo(tabContent); 122 | }); 123 | 124 | // set active tab 125 | $(tabList.children('li')[activeTab]).addClass('active'); 126 | var active = $(tabContent.children('div.section')[activeTab]); 127 | active.addClass('active'); 128 | if (fade) 129 | active.addClass('in'); 130 | 131 | if (tabset.hasClass("tabset-sticky")) 132 | tabset.rmarkdownStickyTabs(); 133 | } 134 | 135 | // convert section divs with the .tabset class to tabsets 136 | var tabsets = $("div.section.tabset"); 137 | tabsets.each(function(i) { 138 | buildTabset($(tabsets[i])); 139 | }); 140 | }; 141 | 142 | -------------------------------------------------------------------------------- /docs/libs/rhandsontable-0.3.7/rhandsontable.css: -------------------------------------------------------------------------------- 1 | .handsontable .currentRow { 2 | background-color: #E7E8EF; 3 | } 4 | 5 | .handsontable .currentCol { 6 | background-color: #F9F9FB; 7 | } 8 | 9 | .handsontable { 10 | overflow: auto; 11 | } 12 | 13 | /* fix for sparkline hover */ 14 | .jqstooltip{ 15 | width: auto !important; 16 | height: auto !important; 17 | } 18 | 19 | /* fix for shiny datepicker */ 20 | .datepicker { 21 | z-index: 1000 !important; 22 | } 23 | 24 | .handsontable table thead th { 25 | white-space: pre-line; 26 | /*max-width: /* enter here your max header width */ 27 | } 28 | -------------------------------------------------------------------------------- /docs/libs/rhandsontable-0.3.7/rhandsontable.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'rhandsontable', 4 | 5 | type: 'output', 6 | 7 | params: null, 8 | 9 | initialize: function(el, width, height) { 10 | 11 | return { 12 | 13 | }; 14 | 15 | }, 16 | 17 | renderValue: function(el, x, instance) { 18 | 19 | // convert json to array 20 | if (x.data.length > 0 && x.data[0].constructor === Array) { 21 | x.data = x.data; 22 | } else { 23 | x.data = toArray(x.data.map(function(d) { 24 | return x.rColnames.map(function(ky) { 25 | return d[ky]; 26 | }); 27 | })); 28 | } 29 | 30 | if (x.isHeatmap === true) { 31 | x.afterLoadData = this.initHeatmap; 32 | x.beforeChangeRender = this.updateHeatmap; 33 | } 34 | 35 | if (x.overflow) { 36 | $("#" + el.id).css('overflow', x.overflow); 37 | } 38 | 39 | if (x.rowHeaderWidth) { 40 | $("#" + el.id).css('col.rowHeader', x.rowHeaderWidth + 'px'); 41 | } 42 | 43 | //this.afterRender(x); 44 | 45 | this.params = x; 46 | 47 | if (instance.hot) { // update existing instance 48 | if (x.debug && x.debug > 0) { 49 | console.log("rhandsontable: update table"); 50 | } 51 | 52 | instance.hot.params = x; 53 | instance.hot.updateSettings(x); 54 | } else { // create new instance 55 | if (x.debug && x.debug > 0) { 56 | console.log("rhandsontable: new table"); 57 | } 58 | 59 | instance.hot = new Handsontable(el, x); 60 | 61 | this.afterChangeCallback(x); 62 | this.afterCellMetaCallback(x); 63 | this.afterRowAndColChange(x); 64 | 65 | if (x.selectCallback) { 66 | this.afterSelectCallback(x); 67 | } 68 | 69 | instance.hot.params = x; 70 | instance.hot.updateSettings(x); 71 | 72 | var searchField = document.getElementById('searchField'); 73 | if (typeof(searchField) != 'undefined' && searchField !== null) { 74 | Handsontable.dom.addEvent(searchField, 'keyup', function (event) { 75 | var search = instance.hot.getPlugin('search'); 76 | var queryResult = search.query(this.value); 77 | instance.hot.render(); 78 | }); 79 | } 80 | } 81 | }, 82 | 83 | resize: function(el, width, height, instance) { 84 | 85 | }, 86 | 87 | afterRender: function(x) { 88 | x.afterRender = function(isForced) { 89 | var plugin = this.getPlugin('autoColumnSize'); 90 | if (plugin.isEnabled() && this.params) { 91 | if (this.params && this.params.debug) { 92 | if (this.params.debug > 0) { 93 | console.log("rhandsontable: resizing column widths"); 94 | } 95 | } 96 | 97 | var wdths = plugin.widths; 98 | for(var i = 0, colCount = this.countCols(); i < colCount ; i++) { 99 | if (this.params.columns && this.params.columns[i].renderer.name != "customRenderer") { 100 | plugin.calculateColumnsWidth(i, 300, true); 101 | } 102 | } 103 | } 104 | }; 105 | }, 106 | 107 | afterChangeCallback: function(x) { 108 | 109 | x.afterChange = function(changes, source) { 110 | if (this.params && this.params.debug) { 111 | if (this.params.debug > 0) { 112 | console.log("afterChange: " + source); 113 | } 114 | if (this.params.debug > 1) { 115 | console.log("afterChange:"); 116 | console.log(changes); 117 | } 118 | } 119 | 120 | if (HTMLWidgets.shinyMode) { 121 | if (changes && (changes[0][2] !== null || changes[0][3] !== null)) { 122 | if (this.sortIndex && this.sortIndex.length !== 0) { 123 | c = [this.sortIndex[changes[0][0]][0], changes[0].slice(1, 1 + 3)]; 124 | } else { 125 | c = changes; 126 | } 127 | 128 | if (this.params && this.params.debug) { 129 | if (this.params.debug > 0) { 130 | console.log("afterChange: Shiny.onInputChange: " + this.rootElement.id); 131 | } 132 | } 133 | Shiny.onInputChange(this.rootElement.id, { 134 | data: this.getData(), 135 | changes: { event: "afterChange", changes: c, source: source }, 136 | params: this.params 137 | }); 138 | } else if (source == "loadData" && this.params) { 139 | 140 | if (this.params && this.params.debug) { 141 | if (this.params.debug > 0) { 142 | console.log("afterChange: Shiny.onInputChange: " + this.rootElement.id); 143 | } 144 | } 145 | // push input change to shiny so input$hot and output$hot are in sync (see #137) 146 | Shiny.onInputChange(this.rootElement.id, { 147 | data: this.getData(), 148 | changes: { event: "afterChange", changes: null }, 149 | params: this.params 150 | }); 151 | } 152 | } 153 | 154 | }; 155 | 156 | x.afterLoadData = function(firstTime) { 157 | if (this.params && this.params.debug) { 158 | if (this.params.debug > 0) { 159 | console.log("afterLoadData: " + firstTime); 160 | } 161 | } 162 | }; 163 | 164 | x.afterChangesObserved = function(firstTime) { 165 | if (this.params && this.params.debug) { 166 | if (this.params.debug > 0) { 167 | console.log("afterChangesObserved"); 168 | } 169 | } 170 | }; 171 | 172 | x.afterInit = function() { 173 | if (this.params && this.params.debug) { 174 | if (this.params.debug > 0) { 175 | console.log("afterInit"); 176 | } 177 | } 178 | }; 179 | }, 180 | 181 | afterCellMetaCallback: function(x) { 182 | 183 | x.afterSetCellMeta = function(r, c, key, val) { 184 | 185 | if (HTMLWidgets.shinyMode && key === "comment") { 186 | if (this.params && this.params.debug) { 187 | if (this.params.debug > 0) { 188 | console.log("afterSetCellMeta: Shiny.onInputChange: " + this.rootElement.id); 189 | } 190 | } 191 | Shiny.onInputChange(this.rootElement.id + "_comment", { 192 | data: this.getData(), 193 | comment: { r: r + 1, c: c + 1, key: key, val: val}, 194 | params: this.params 195 | }); 196 | } 197 | 198 | }; 199 | }, 200 | 201 | afterSelectCallback: function(x) { 202 | 203 | x.afterSelectionEnd = function(r, c, r2, c2) { 204 | 205 | var r_all = []; 206 | var c_all = []; 207 | if (HTMLWidgets.shinyMode) { 208 | if ( r2 < r ) { r2 = [r, r = r2][0]; } 209 | for ( var i=r; i <= r2; i++ ) { 210 | r_all.push( this.toPhysicalRow(i) + 1 ); 211 | } 212 | if ( c2 < c ) { c2 = [c, c = c2][0]; } 213 | for ( var ii=c; ii <= c2; ii++ ) { 214 | c_all.push( this.toPhysicalColumn(ii) + 1 ); 215 | } 216 | 217 | if (this.params && this.params.debug) { 218 | if (this.params.debug > 0) { 219 | console.log("afterSelectionEnd: Shiny.onInputChange: " + this.rootElement.id); 220 | } 221 | } 222 | Shiny.onInputChange(this.rootElement.id + "_select:rhandsontable.customSelectDeserializer", { 223 | data: this.getData(), 224 | select: { r: r + 1, 225 | c: c + 1, 226 | r2: r2 + 1, 227 | c2: c2 + 1, 228 | rAll: r_all, 229 | cAll: c_all }, 230 | params: this.params 231 | }); 232 | } 233 | 234 | }; 235 | }, 236 | 237 | afterRowAndColChange: function(x) { 238 | 239 | x.afterCreateRow = function(ind, ct) { 240 | 241 | if (HTMLWidgets.shinyMode) { 242 | 243 | if (this.params && this.params.columns) { 244 | for(var i = 0, colCount = this.countCols(); i < colCount ; i++) { 245 | this.setDataAtCell(ind, i, this.params.columns[i].default); 246 | } 247 | } 248 | 249 | if (this.params && this.params.debug) { 250 | if (this.params.debug > 0) { 251 | console.log("afterCreateRow: Shiny.onInputChange: " + this.rootElement.id); 252 | } 253 | } 254 | Shiny.onInputChange(this.rootElement.id, { 255 | data: this.getData(), 256 | changes: { event: "afterCreateRow", ind: ind, ct: ct }, 257 | params: this.params 258 | }); 259 | } 260 | }; 261 | 262 | x.afterRemoveRow = function(ind, ct) { 263 | 264 | if (HTMLWidgets.shinyMode) { 265 | if (this.params && this.params.debug) { 266 | if (this.params.debug > 0) { 267 | console.log("afterRemoveRow: Shiny.onInputChange: " + this.rootElement.id); 268 | } 269 | } 270 | Shiny.onInputChange(this.rootElement.id, { 271 | data: this.getData(), 272 | changes: { event: "afterRemoveRow", ind: ind, ct: ct }, 273 | params: this.params 274 | }); 275 | } 276 | }; 277 | 278 | x.afterCreateCol = function(ind, ct) { 279 | 280 | if (HTMLWidgets.shinyMode) { 281 | if (this.params && this.params.debug) { 282 | if (this.params.debug > 0) { 283 | console.log("afterCreateCol: Shiny.onInputChange: " + this.rootElement.id); 284 | } 285 | } 286 | Shiny.onInputChange(this.rootElement.id, { 287 | data: this.getData(), 288 | changes: { event: "afterCreateCol", ind: ind, ct: ct }, 289 | params: this.params 290 | }); 291 | } 292 | }; 293 | 294 | x.afterRemoveCol = function(ind, ct) { 295 | 296 | if (HTMLWidgets.shinyMode) 297 | if (this.params && this.params.debug) { 298 | if (this.params.debug > 0) { 299 | console.log("afterRemoveCol: Shiny.onInputChange: " + this.rootElement.id); 300 | } 301 | } 302 | Shiny.onInputChange(this.rootElement.id, { 303 | data: this.getData(), 304 | changes: { event: "afterRemoveCol", ind: ind, ct: ct }, 305 | params: this.params 306 | }); 307 | }; 308 | 309 | x.afterRowMove = function(ind, ct) { 310 | 311 | if (HTMLWidgets.shinyMode) 312 | if (this.params && this.params.debug) { 313 | if (this.params.debug > 0) { 314 | console.log("afterRowMove: Shiny.onInputChange: " + this.rootElement.id); 315 | } 316 | } 317 | Shiny.onInputChange(this.rootElement.id, { 318 | data: this.getData(), 319 | changes: { event: "afterRowMove", ind: ind, ct: ct }, 320 | params: this.params 321 | }); 322 | }; 323 | 324 | }, 325 | 326 | // see http://handsontable.com/demo/heatmaps.html 327 | initHeatmap: function(firstTime, source) { 328 | this.heatmap = []; 329 | 330 | for(var i = 0, colCount = this.countCols(); i < colCount ; i++) { 331 | this.heatmap[i] = generateHeatmapData.call(this, i); 332 | } 333 | }, 334 | 335 | updateHeatmap: function(change, source) { 336 | this.heatmap[change[0][1]] = generateHeatmapData.call(this, change[0][1]); 337 | } 338 | 339 | }); 340 | 341 | function generateHeatmapData(colId) { 342 | 343 | var values = this.getDataAtCol(colId); 344 | 345 | return { 346 | min: Math.min.apply(null, values), 347 | max: Math.max.apply(null, values) 348 | }; 349 | } 350 | 351 | // https://stackoverflow.com/questions/22477612/converting-array-of-objects-into-array-of-arrays 352 | function toArray(input) { 353 | var result = input.map(function(obj) { 354 | return Object.keys(obj).map(function(key) { 355 | return obj[key]; 356 | }); 357 | }); 358 | return result; 359 | } 360 | 361 | // csv logic adapted from https://github.com/juantascon/jquery-handsontable-csv 362 | function csvString(instance, sep, dec) { 363 | 364 | var headers = instance.getColHeader(); 365 | 366 | var csv = headers.join(sep) + "\n"; 367 | 368 | for (var i = 0; i < instance.countRows(); i++) { 369 | var row = []; 370 | for (var h in headers) { 371 | var col = instance.propToCol(h); 372 | var value = instance.getDataAtRowProp(i, col); 373 | if ( !isNaN(value) ) { 374 | value = value.toString().replace(".", dec); 375 | } 376 | row.push(value); 377 | } 378 | 379 | csv += row.join(sep); 380 | csv += "\n"; 381 | } 382 | 383 | return csv; 384 | } 385 | 386 | function customRenderer(instance, TD, row, col, prop, value, cellProperties) { 387 | if (['date', 'handsontable', 'dropdown'].indexOf(cellProperties.type) > -1) { 388 | type = 'autocomplete'; 389 | } else { 390 | type = cellProperties.type; 391 | } 392 | Handsontable.renderers.getRenderer(type)(instance, TD, row, col, prop, value, cellProperties); 393 | } 394 | 395 | function renderSparkline(instance, td, row, col, prop, value, cellProperties) { 396 | try { 397 | val = JSON.parse(value); 398 | 399 | nm = 'sparklines_r' + row + '_c' + col; 400 | td.innerHTML = ''; 401 | 402 | // adjust for cell padding 403 | if (val.options && val.options.type && 404 | ['bar', 'tristate'].indexOf(val.options.type[0]) > -1) { 405 | val.options.barSpacing = 1; 406 | val.options.barWidth = Math.max(1, Math.round((instance.getColWidth(col) - 8 - (val.values.length - 1)) / val.values.length)); 407 | } else { 408 | if (!val.options) { 409 | val.options = {}; 410 | } 411 | val.options.width = (instance.getColWidth(col) - 8) + "px"; 412 | } 413 | 414 | $('.' + nm).sparkline(val.values, val.options); 415 | } catch(err) { 416 | td.innerHTML = ''; 417 | } 418 | 419 | return td; 420 | } 421 | 422 | // http://docs.handsontable.com/0.16.1/demo-custom-renderers.html 423 | function strip_tags(input, allowed) { 424 | var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, 425 | commentsAndPhpTags = /|<\?(?:php)?[\s\S]*?\?>/gi; 426 | 427 | // making sure the allowed arg is a string containing only tags in lowercase () 428 | allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); 429 | 430 | return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) { 431 | return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''; 432 | }); 433 | } 434 | 435 | function safeHtmlRenderer(instance, td, row, col, prop, value, cellProperties) { 436 | var escaped = Handsontable.helper.stringify(value); 437 | if (instance.getSettings().allowedTags) { 438 | tags = instance.getSettings().allowedTags; 439 | } else { 440 | tags = ''; 441 | } 442 | escaped = strip_tags(escaped, tags); //be sure you only allow certain HTML tags to avoid XSS threats (you should also remove unwanted HTML attributes) 443 | td.innerHTML = escaped; 444 | 445 | return td; 446 | } 447 | 448 | 449 | // if the table is in an ineractive session, shiny mode, 450 | // then we register the handler for setting data interactively 451 | if (HTMLWidgets.shinyMode) { 452 | Shiny.addCustomMessageHandler( 453 | "handler_setDataAtCell", 454 | function(message) { 455 | var hot = window.HTMLWidgets.find('#' + message.id).hot; 456 | var count = message.size; 457 | 458 | // setDataAtCell is overloaded so there's different parameters to send one value 459 | if( count == 1 ) { 460 | hot.setDataAtCell(message.row, message.col, message.val); 461 | return; 462 | } 463 | // if sending 2+ values to the table then we use an array of arrays 464 | var datArr = []; 465 | // when the table is sorted we need to send the values to their visual locations 466 | if ( hot.getPlugin('columnSorting').isSorted() ) { 467 | for ( var i=0; i < count; i++ ) { 468 | datArr[datArr.length] = [hot.toVisualRow(message.row[i]), 469 | hot.toVisualColumn(message.col[i]), 470 | message.val[i]]; 471 | } 472 | } else { 473 | // when not sorted we just use the values from R 474 | for ( var i=0; i < count; i++ ) { 475 | datArr[datArr.length] = [message.row[i], message.col[i], message.val[i]]; 476 | } 477 | } 478 | hot.setDataAtCell(datArr); 479 | }); 480 | } 481 | 482 | -------------------------------------------------------------------------------- /docs/libs/rhandsontable-0.3.7/rhandsontable.yaml: -------------------------------------------------------------------------------- 1 | # (uncomment to add a dependency) 2 | dependencies: 3 | - name: handsontable 4 | version: 6.2.2 5 | src: "htmlwidgets/lib/handsontable" 6 | script: 7 | - handsontable.full.min.js 8 | - all.min.js 9 | stylesheet: handsontable.full.min.css 10 | - name: numbro.languages 11 | version: 2.0.6 12 | src: "htmlwidgets/lib/numbro" 13 | script: languages.min.js 14 | - name: chroma 15 | version: 1.3.3 16 | src: "htmlwidgets/lib/chroma" 17 | script: chroma.min.js 18 | - name: jquery 19 | version: 3.2.1 20 | src: "htmlwidgets/lib/jquery" 21 | script: jquery.min.js 22 | - name: sparkline 23 | version: 2.1.2 24 | src: "htmlwidgets/lib/sparkline" 25 | script: jquery.sparkline.min.js 26 | - name: rhandsontable 27 | version: 0.3.7 28 | src: "htmlwidgets" 29 | stylesheet: rhandsontable.css 30 | -------------------------------------------------------------------------------- /docs/libs/rhandsontable-binding-0.3.7/rhandsontable.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'rhandsontable', 4 | 5 | type: 'output', 6 | 7 | params: null, 8 | 9 | initialize: function(el, width, height) { 10 | 11 | return { 12 | 13 | }; 14 | 15 | }, 16 | 17 | renderValue: function(el, x, instance) { 18 | 19 | // convert json to array 20 | if (x.data.length > 0 && x.data[0].constructor === Array) { 21 | x.data = x.data; 22 | } else { 23 | x.data = toArray(x.data.map(function(d) { 24 | return x.rColnames.map(function(ky) { 25 | return d[ky]; 26 | }); 27 | })); 28 | } 29 | 30 | if (x.isHeatmap === true) { 31 | x.afterLoadData = this.initHeatmap; 32 | x.beforeChangeRender = this.updateHeatmap; 33 | } 34 | 35 | if (x.overflow) { 36 | $("#" + el.id).css('overflow', x.overflow); 37 | } 38 | 39 | if (x.rowHeaderWidth) { 40 | $("#" + el.id).css('col.rowHeader', x.rowHeaderWidth + 'px'); 41 | } 42 | 43 | //this.afterRender(x); 44 | 45 | this.params = x; 46 | 47 | if (instance.hot) { // update existing instance 48 | if (x.debug && x.debug > 0) { 49 | console.log("rhandsontable: update table"); 50 | } 51 | 52 | instance.hot.params = x; 53 | instance.hot.updateSettings(x); 54 | } else { // create new instance 55 | if (x.debug && x.debug > 0) { 56 | console.log("rhandsontable: new table"); 57 | } 58 | 59 | instance.hot = new Handsontable(el, x); 60 | 61 | this.afterChangeCallback(x); 62 | this.afterCellMetaCallback(x); 63 | this.afterRowAndColChange(x); 64 | 65 | if (x.selectCallback) { 66 | this.afterSelectCallback(x); 67 | } 68 | 69 | instance.hot.params = x; 70 | instance.hot.updateSettings(x); 71 | 72 | var searchField = document.getElementById('searchField'); 73 | if (typeof(searchField) != 'undefined' && searchField !== null) { 74 | Handsontable.dom.addEvent(searchField, 'keyup', function (event) { 75 | var search = instance.hot.getPlugin('search'); 76 | var queryResult = search.query(this.value); 77 | instance.hot.render(); 78 | }); 79 | } 80 | } 81 | }, 82 | 83 | resize: function(el, width, height, instance) { 84 | 85 | }, 86 | 87 | afterRender: function(x) { 88 | x.afterRender = function(isForced) { 89 | var plugin = this.getPlugin('autoColumnSize'); 90 | if (plugin.isEnabled() && this.params) { 91 | if (this.params && this.params.debug) { 92 | if (this.params.debug > 0) { 93 | console.log("rhandsontable: resizing column widths"); 94 | } 95 | } 96 | 97 | var wdths = plugin.widths; 98 | for(var i = 0, colCount = this.countCols(); i < colCount ; i++) { 99 | if (this.params.columns && this.params.columns[i].renderer.name != "customRenderer") { 100 | plugin.calculateColumnsWidth(i, 300, true); 101 | } 102 | } 103 | } 104 | }; 105 | }, 106 | 107 | afterChangeCallback: function(x) { 108 | 109 | x.afterChange = function(changes, source) { 110 | if (this.params && this.params.debug) { 111 | if (this.params.debug > 0) { 112 | console.log("afterChange: " + source); 113 | } 114 | if (this.params.debug > 1) { 115 | console.log("afterChange:"); 116 | console.log(changes); 117 | } 118 | } 119 | 120 | if (HTMLWidgets.shinyMode) { 121 | if (changes && (changes[0][2] !== null || changes[0][3] !== null)) { 122 | if (this.sortIndex && this.sortIndex.length !== 0) { 123 | c = [this.sortIndex[changes[0][0]][0], changes[0].slice(1, 1 + 3)]; 124 | } else { 125 | c = changes; 126 | } 127 | 128 | if (this.params && this.params.debug) { 129 | if (this.params.debug > 0) { 130 | console.log("afterChange: Shiny.onInputChange: " + this.rootElement.id); 131 | } 132 | } 133 | Shiny.onInputChange(this.rootElement.id, { 134 | data: this.getData(), 135 | changes: { event: "afterChange", changes: c, source: source }, 136 | params: this.params 137 | }); 138 | } else if (source == "loadData" && this.params) { 139 | 140 | if (this.params && this.params.debug) { 141 | if (this.params.debug > 0) { 142 | console.log("afterChange: Shiny.onInputChange: " + this.rootElement.id); 143 | } 144 | } 145 | // push input change to shiny so input$hot and output$hot are in sync (see #137) 146 | Shiny.onInputChange(this.rootElement.id, { 147 | data: this.getData(), 148 | changes: { event: "afterChange", changes: null }, 149 | params: this.params 150 | }); 151 | } 152 | } 153 | 154 | }; 155 | 156 | x.afterLoadData = function(firstTime) { 157 | if (this.params && this.params.debug) { 158 | if (this.params.debug > 0) { 159 | console.log("afterLoadData: " + firstTime); 160 | } 161 | } 162 | }; 163 | 164 | x.afterChangesObserved = function(firstTime) { 165 | if (this.params && this.params.debug) { 166 | if (this.params.debug > 0) { 167 | console.log("afterChangesObserved"); 168 | } 169 | } 170 | }; 171 | 172 | x.afterInit = function() { 173 | if (this.params && this.params.debug) { 174 | if (this.params.debug > 0) { 175 | console.log("afterInit"); 176 | } 177 | } 178 | }; 179 | }, 180 | 181 | afterCellMetaCallback: function(x) { 182 | 183 | x.afterSetCellMeta = function(r, c, key, val) { 184 | 185 | if (HTMLWidgets.shinyMode && key === "comment") { 186 | if (this.params && this.params.debug) { 187 | if (this.params.debug > 0) { 188 | console.log("afterSetCellMeta: Shiny.onInputChange: " + this.rootElement.id); 189 | } 190 | } 191 | Shiny.onInputChange(this.rootElement.id + "_comment", { 192 | data: this.getData(), 193 | comment: { r: r + 1, c: c + 1, key: key, val: val}, 194 | params: this.params 195 | }); 196 | } 197 | 198 | }; 199 | }, 200 | 201 | afterSelectCallback: function(x) { 202 | 203 | x.afterSelectionEnd = function(r, c, r2, c2) { 204 | 205 | var r_all = []; 206 | var c_all = []; 207 | if (HTMLWidgets.shinyMode) { 208 | if ( r2 < r ) { r2 = [r, r = r2][0]; } 209 | for ( var i=r; i <= r2; i++ ) { 210 | r_all.push( this.toPhysicalRow(i) + 1 ); 211 | } 212 | if ( c2 < c ) { c2 = [c, c = c2][0]; } 213 | for ( var ii=c; ii <= c2; ii++ ) { 214 | c_all.push( this.toPhysicalColumn(ii) + 1 ); 215 | } 216 | 217 | if (this.params && this.params.debug) { 218 | if (this.params.debug > 0) { 219 | console.log("afterSelectionEnd: Shiny.onInputChange: " + this.rootElement.id); 220 | } 221 | } 222 | Shiny.onInputChange(this.rootElement.id + "_select:rhandsontable.customSelectDeserializer", { 223 | data: this.getData(), 224 | select: { r: r + 1, 225 | c: c + 1, 226 | r2: r2 + 1, 227 | c2: c2 + 1, 228 | rAll: r_all, 229 | cAll: c_all }, 230 | params: this.params 231 | }); 232 | } 233 | 234 | }; 235 | }, 236 | 237 | afterRowAndColChange: function(x) { 238 | 239 | x.afterCreateRow = function(ind, ct) { 240 | 241 | if (HTMLWidgets.shinyMode) { 242 | 243 | if (this.params && this.params.columns) { 244 | for(var i = 0, colCount = this.countCols(); i < colCount ; i++) { 245 | this.setDataAtCell(ind, i, this.params.columns[i].default); 246 | } 247 | } 248 | 249 | if (this.params && this.params.debug) { 250 | if (this.params.debug > 0) { 251 | console.log("afterCreateRow: Shiny.onInputChange: " + this.rootElement.id); 252 | } 253 | } 254 | Shiny.onInputChange(this.rootElement.id, { 255 | data: this.getData(), 256 | changes: { event: "afterCreateRow", ind: ind, ct: ct }, 257 | params: this.params 258 | }); 259 | } 260 | }; 261 | 262 | x.afterRemoveRow = function(ind, ct) { 263 | 264 | if (HTMLWidgets.shinyMode) { 265 | if (this.params && this.params.debug) { 266 | if (this.params.debug > 0) { 267 | console.log("afterRemoveRow: Shiny.onInputChange: " + this.rootElement.id); 268 | } 269 | } 270 | Shiny.onInputChange(this.rootElement.id, { 271 | data: this.getData(), 272 | changes: { event: "afterRemoveRow", ind: ind, ct: ct }, 273 | params: this.params 274 | }); 275 | } 276 | }; 277 | 278 | x.afterCreateCol = function(ind, ct) { 279 | 280 | if (HTMLWidgets.shinyMode) { 281 | if (this.params && this.params.debug) { 282 | if (this.params.debug > 0) { 283 | console.log("afterCreateCol: Shiny.onInputChange: " + this.rootElement.id); 284 | } 285 | } 286 | Shiny.onInputChange(this.rootElement.id, { 287 | data: this.getData(), 288 | changes: { event: "afterCreateCol", ind: ind, ct: ct }, 289 | params: this.params 290 | }); 291 | } 292 | }; 293 | 294 | x.afterRemoveCol = function(ind, ct) { 295 | 296 | if (HTMLWidgets.shinyMode) 297 | if (this.params && this.params.debug) { 298 | if (this.params.debug > 0) { 299 | console.log("afterRemoveCol: Shiny.onInputChange: " + this.rootElement.id); 300 | } 301 | } 302 | Shiny.onInputChange(this.rootElement.id, { 303 | data: this.getData(), 304 | changes: { event: "afterRemoveCol", ind: ind, ct: ct }, 305 | params: this.params 306 | }); 307 | }; 308 | 309 | }, 310 | 311 | // see http://handsontable.com/demo/heatmaps.html 312 | initHeatmap: function(firstTime, source) { 313 | this.heatmap = []; 314 | 315 | for(var i = 0, colCount = this.countCols(); i < colCount ; i++) { 316 | this.heatmap[i] = generateHeatmapData.call(this, i); 317 | } 318 | }, 319 | 320 | updateHeatmap: function(change, source) { 321 | this.heatmap[change[0][1]] = generateHeatmapData.call(this, change[0][1]); 322 | } 323 | 324 | }); 325 | 326 | function generateHeatmapData(colId) { 327 | 328 | var values = this.getDataAtCol(colId); 329 | 330 | return { 331 | min: Math.min.apply(null, values), 332 | max: Math.max.apply(null, values) 333 | }; 334 | } 335 | 336 | // https://stackoverflow.com/questions/22477612/converting-array-of-objects-into-array-of-arrays 337 | function toArray(input) { 338 | var result = input.map(function(obj) { 339 | return Object.keys(obj).map(function(key) { 340 | return obj[key]; 341 | }); 342 | }); 343 | return result; 344 | } 345 | 346 | // csv logic adapted from https://github.com/juantascon/jquery-handsontable-csv 347 | function csvString(instance, sep, dec) { 348 | 349 | var headers = instance.getColHeader(); 350 | 351 | var csv = headers.join(sep) + "\n"; 352 | 353 | for (var i = 0; i < instance.countRows(); i++) { 354 | var row = []; 355 | for (var h in headers) { 356 | var col = instance.propToCol(h); 357 | var value = instance.getDataAtRowProp(i, col); 358 | if ( !isNaN(value) ) { 359 | value = value.toString().replace(".", dec); 360 | } 361 | row.push(value); 362 | } 363 | 364 | csv += row.join(sep); 365 | csv += "\n"; 366 | } 367 | 368 | return csv; 369 | } 370 | 371 | function customRenderer(instance, TD, row, col, prop, value, cellProperties) { 372 | if (['date', 'handsontable', 'dropdown'].indexOf(cellProperties.type) > -1) { 373 | type = 'autocomplete'; 374 | } else { 375 | type = cellProperties.type; 376 | } 377 | Handsontable.renderers.getRenderer(type)(instance, TD, row, col, prop, value, cellProperties); 378 | } 379 | 380 | function renderSparkline(instance, td, row, col, prop, value, cellProperties) { 381 | try { 382 | val = JSON.parse(value); 383 | 384 | nm = 'sparklines_r' + row + '_c' + col; 385 | td.innerHTML = ''; 386 | 387 | // adjust for cell padding 388 | if (val.options && val.options.type && 389 | ['bar', 'tristate'].indexOf(val.options.type[0]) > -1) { 390 | val.options.barSpacing = 1; 391 | val.options.barWidth = Math.max(1, Math.round((instance.getColWidth(col) - 8 - (val.values.length - 1)) / val.values.length)); 392 | } else { 393 | if (!val.options) { 394 | val.options = {}; 395 | } 396 | val.options.width = (instance.getColWidth(col) - 8) + "px"; 397 | } 398 | 399 | $('.' + nm).sparkline(val.values, val.options); 400 | } catch(err) { 401 | td.innerHTML = ''; 402 | } 403 | 404 | return td; 405 | } 406 | 407 | // http://docs.handsontable.com/0.16.1/demo-custom-renderers.html 408 | function strip_tags(input, allowed) { 409 | var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, 410 | commentsAndPhpTags = /|<\?(?:php)?[\s\S]*?\?>/gi; 411 | 412 | // making sure the allowed arg is a string containing only tags in lowercase () 413 | allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); 414 | 415 | return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) { 416 | return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''; 417 | }); 418 | } 419 | 420 | function safeHtmlRenderer(instance, td, row, col, prop, value, cellProperties) { 421 | var escaped = Handsontable.helper.stringify(value); 422 | if (instance.getSettings().allowedTags) { 423 | tags = instance.getSettings().allowedTags; 424 | } else { 425 | tags = ''; 426 | } 427 | escaped = strip_tags(escaped, tags); //be sure you only allow certain HTML tags to avoid XSS threats (you should also remove unwanted HTML attributes) 428 | td.innerHTML = escaped; 429 | 430 | return td; 431 | } 432 | -------------------------------------------------------------------------------- /docs/libs/tocify-1.9.1/jquery.tocify.css: -------------------------------------------------------------------------------- 1 | /* 2 | * jquery.tocify.css 1.9.1 3 | * Author: @gregfranko 4 | */ 5 | 6 | /* The Table of Contents container element */ 7 | .tocify { 8 | width: 20%; 9 | max-height: 90%; 10 | overflow: auto; 11 | margin-left: 2%; 12 | position: fixed; 13 | border: 1px solid #ccc; 14 | border-radius: 6px; 15 | } 16 | 17 | /* The Table of Contents is composed of multiple nested unordered lists. These styles remove the default styling of an unordered list because it is ugly. */ 18 | .tocify ul, .tocify li { 19 | list-style: none; 20 | margin: 0; 21 | padding: 0; 22 | border: none; 23 | line-height: 30px; 24 | } 25 | 26 | /* Top level header elements */ 27 | .tocify-header { 28 | text-indent: 10px; 29 | } 30 | 31 | /* Top level subheader elements. These are the first nested items underneath a header element. */ 32 | .tocify-subheader { 33 | text-indent: 20px; 34 | display: none; 35 | } 36 | 37 | /* Makes the font smaller for all subheader elements. */ 38 | .tocify-subheader li { 39 | font-size: 12px; 40 | } 41 | 42 | /* Further indents second level subheader elements. */ 43 | .tocify-subheader .tocify-subheader { 44 | text-indent: 30px; 45 | } 46 | .tocify-subheader .tocify-subheader .tocify-subheader { 47 | text-indent: 40px; 48 | } 49 | .tocify-subheader .tocify-subheader .tocify-subheader .tocify-subheader { 50 | text-indent: 50px; 51 | } 52 | .tocify-subheader .tocify-subheader .tocify-subheader .tocify-subheader .tocify-subheader { 53 | text-indent: 60px; 54 | } 55 | 56 | /* Twitter Bootstrap Override Style */ 57 | .tocify .tocify-item > a, .tocify .nav-list .nav-header { 58 | margin: 0px; 59 | } 60 | 61 | /* Twitter Bootstrap Override Styles */ 62 | .tocify .tocify-item a, .tocify .list-group-item { 63 | padding: 5px; 64 | } 65 | 66 | .tocify .nav-pills > li { 67 | float: none; 68 | } 69 | 70 | /* We don't override the bootstrap colors because this gives us the 71 | wrong selection colors when using bootstrap themes 72 | 73 | .tocify .list-group-item:hover, .tocify .list-group-item:focus { 74 | background-color: #f5f5f5; 75 | } 76 | 77 | .tocify .list-group-item.active:hover, .tocify .list-group-item.active:focus { 78 | background-color: #428bca; 79 | } 80 | */ 81 | 82 | /* End Twitter Bootstrap Override Styles */ 83 | -------------------------------------------------------------------------------- /inst/examples/context_menu.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | DF = data.frame(val = 1:10, 4 | bool = TRUE, 5 | big = LETTERS[1:10], 6 | small = factor(letters[1:10]), 7 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 8 | stringsAsFactors = FALSE) 9 | 10 | rhandsontable(DF, search = TRUE) %>% 11 | hot_context_menu( 12 | customOpts = list( 13 | search = list(name = "Search", 14 | callback = htmlwidgets::JS( 15 | "function (key, options) { 16 | var srch = prompt('Search criteria'); 17 | 18 | this.search.query(srch); 19 | this.render(); 20 | }")))) 21 | 22 | rhandsontable(DF) %>% 23 | hot_context_menu( 24 | customOpts = list( 25 | csv = list(name = "Download to CSV", 26 | callback = htmlwidgets::JS( 27 | "function (key, options) { 28 | var csv = csvString(this); 29 | 30 | var link = document.createElement('a'); 31 | link.setAttribute('href', 'data:text/plain;charset=utf-8,' + 32 | encodeURIComponent(csv)); 33 | link.setAttribute('download', 'data.csv'); 34 | 35 | document.body.appendChild(link); 36 | link.click(); 37 | document.body.removeChild(link); 38 | }")))) 39 | -------------------------------------------------------------------------------- /inst/examples/images/rhandsontable_readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/inst/examples/images/rhandsontable_readme.png -------------------------------------------------------------------------------- /inst/examples/rhandsontable_comment/server.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | shinyServer(function(input, output, session) { 4 | values = reactiveValues() 5 | 6 | data = reactive({ 7 | if (is.null(input$hot)) { 8 | MAT = matrix(rnorm(50), nrow = 10, dimnames = list(LETTERS[1:10], 9 | letters[1:5])) 10 | vals = rep(NA, 50) 11 | vals[sample(1:50, 5)] = paste0(LETTERS[1:5], letters[1:5]) 12 | CMTS = matrix(vals, nrow = 10, ncol = 5, dimnames = list(LETTERS[1:10], 13 | letters[1:5])) 14 | } else { 15 | MAT = hot_to_r(input$hot) 16 | } 17 | 18 | MAT 19 | }) 20 | 21 | comments = reactive({ 22 | if (is.null(input$hot_comment)) { 23 | vals = rep(NA, 50) 24 | vals[sample(1:50, 5)] = paste0(LETTERS[1:5], letters[1:5]) 25 | CMTS = matrix(vals, nrow = 10, ncol = 5, dimnames = list(LETTERS[1:10], 26 | letters[1:5])) 27 | } else { 28 | new = input$hot_comment$comment 29 | 30 | CMTS = values[["CMTS"]] 31 | CMTS[new$r, new$c] = as.character(new$val) 32 | } 33 | 34 | values[["CMTS"]] = CMTS 35 | CMTS 36 | }) 37 | 38 | observe({ 39 | hot = data() 40 | if (input$exportData != 0) { 41 | if (!is.null(hot)) { 42 | write.csv(hot, "data.csv") 43 | } 44 | } 45 | }) 46 | 47 | observe({ 48 | if (input$exportComments != 0) { 49 | if (!is.null(values[["CMTS"]])) { 50 | write.csv(values[["CMTS"]], "comments.csv") 51 | } 52 | } 53 | }) 54 | 55 | output$hot <- renderRHandsontable({ 56 | MAT = data() 57 | CMTS = comments() 58 | 59 | if (!is.null(MAT) && !is.null(CMTS)) { 60 | hot = rhandsontable(MAT, comments = CMTS) 61 | 62 | hot 63 | } 64 | }) 65 | }) 66 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_comment/ui.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | shinyUI(fluidPage( 4 | titlePanel("Handsontable"), 5 | sidebarLayout( 6 | sidebarPanel( 7 | helpText("Change a cell comment using the right-click menu. ", 8 | "Note that deleting a comment does not currently fire ", 9 | "a callback."), 10 | actionButton("exportData", "Export Data"), 11 | actionButton("exportComments", "Export Comments") 12 | ), 13 | mainPanel( 14 | rHandsontableOutput("hot") 15 | ) 16 | ) 17 | )) 18 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_corr/returns.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/inst/examples/rhandsontable_corr/returns.rds -------------------------------------------------------------------------------- /inst/examples/rhandsontable_corr/rsconnect/shinyapps.io/jrowen/rhandsontable_corr.dcf: -------------------------------------------------------------------------------- 1 | name: rhandsontable_corr 2 | account: jrowen 3 | server: shinyapps.io 4 | bundleId: 205663 5 | url: https://jrowen.shinyapps.io/rhandsontable_corr 6 | when: 1434682762.33578 7 | asMultiple: FALSE 8 | asStatic: FALSE 9 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_corr/server.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(rhandsontable) 3 | library(metricsgraphics) 4 | library(data.table) 5 | library(reshape2) 6 | library(quantmod) 7 | 8 | tkrs = c("MSFT", "CAT", "AXP", "DIS", "MMM") 9 | 10 | # quantmod::getSymbols(tkrs, from = "2012-06-01", auto.assign=TRUE) 11 | # returns = Reduce(function(x, y) merge(x, y), lapply(tkrs, get)) 12 | # returns = returns[, names(returns)[grepl("Close", names(returns))]] 13 | # returns = data.table(Date = time(returns), coredata(returns)) 14 | # returns = melt(returns, id.vars = "Date", variable.name = "Name", 15 | # value.name = "Price")[order(Name, Date)] 16 | # returns[, `:=`(Name = gsub(".Close", "", Name))] 17 | # returns[, `:=`(Return = c(NA, Price[-1] / head(Price, -1) - 1)), by = Name] 18 | # saveRDS(returns, "returns.rds") 19 | returns = readRDS("returns.rds") 20 | setkey(returns, Name) 21 | 22 | shinyServer(function(input, output, session) { 23 | calc = reactive({ 24 | cor(dcast.data.table(returns, Date ~ Name, value.var = "Return")[ 25 | , !"Date", with = FALSE], use = "pairwise.complete.obs") 26 | }) 27 | 28 | output$hot = renderRHandsontable({ 29 | MAT = calc() 30 | diag(MAT) = 1 31 | MAT[upper.tri(MAT)] = MAT[lower.tri(MAT)] 32 | rhandsontable(MAT, readOnly = TRUE, selectCallback = TRUE) %>% 33 | hot_cols(renderer = "function (instance, td, row, col, prop, value, cellProperties) { 34 | Handsontable.renderers.TextRenderer.apply(this, arguments); 35 | if (row == col) { 36 | td.style.background = 'lightgrey'; 37 | } else if (col > row) { 38 | td.style.background = 'grey'; 39 | td.style.color = 'grey'; 40 | } else if (value < -0.5) { 41 | td.style.background = 'pink'; 42 | } else if (value > 0.5) { 43 | td.style.background = 'lightgreen'; 44 | } 45 | }") 46 | }) 47 | 48 | output$plot = renderMetricsgraphics({ 49 | if (!is.null(input$hot_select)) { 50 | x_val = colnames(calc())[input$hot_select$select$c] 51 | y_val = colnames(calc())[input$hot_select$select$r] 52 | 53 | DT = returns[Name %in% c(x_val, y_val)] 54 | DT = dcast.data.table(DT, Date ~ Name, value.var = "Return") 55 | 56 | DT[, list(x = get(x_val), y = get(y_val))] %>% 57 | mjs_plot(x = x, y = y) %>% 58 | mjs_point(color_accessor = "Date") %>% 59 | mjs_labs(x_label = x_val, y_label = y_val) 60 | } 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_corr/ui.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(rhandsontable) 3 | library(metricsgraphics) 4 | 5 | shinyUI(fluidPage( 6 | titlePanel("Stock Correlations"), 7 | helpText("Click a cell in the table to see a plot of the raw data."), 8 | fluidRow( 9 | column(4, 10 | rHandsontableOutput("hot") 11 | ), 12 | column(6, 13 | metricsgraphicsOutput("plot") 14 | ) 15 | ) 16 | )) 17 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_dash/app.R: -------------------------------------------------------------------------------- 1 | library(shinydashboard) 2 | library(shiny) 3 | library(data.table) 4 | library(rhandsontable) 5 | 6 | ui = dashboardPage( 7 | dashboardHeader(title = "rhandsontable Example"), 8 | dashboardSidebar( 9 | sidebarMenu( 10 | menuItem("Table", tabName = "table", icon = icon("dashboard")) 11 | ) 12 | ), 13 | dashboardBody( 14 | tabItems( 15 | tabItem(tabName = "table", 16 | fluidRow(box(rHandsontableOutput("hot", height = 400)), 17 | box(rHandsontableOutput("hot2", width = 200))), 18 | fluidRow(box(rHandsontableOutput("hot3"))) 19 | ) 20 | ) 21 | ) 22 | ) 23 | 24 | server = function(input, output) { 25 | output$hot = renderRHandsontable({ 26 | rhandsontable(do.call(cbind, lapply(1:20, function(i) data.table(rnorm(10000))))) 27 | }) 28 | 29 | output$hot2 = renderRHandsontable({ 30 | rhandsontable(do.call(cbind, lapply(1:3, function(i) data.table(rnorm(5))))) 31 | }) 32 | 33 | output$hot3 = renderRHandsontable({ 34 | rhandsontable(do.call(cbind, lapply(1:3, function(i) data.table(rnorm(5)))), 35 | stretchH = "all") 36 | }) 37 | } 38 | 39 | shinyApp(ui, server) 40 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_datafile/mtcars.csv: -------------------------------------------------------------------------------- 1 | "","mpg","cyl","disp","hp","drat","wt","qsec","vs","am","gear","carb" 2 | "Mazda RX4",21,6,160,110,3.9,2.62,16.46,0,1,4,4 3 | "Mazda RX4 Wag",21,6,160,110,3.9,2.875,17.02,0,1,4,4 4 | "Datsun 710",22.8,4,108,93,3.85,2.32,18.61,1,1,4,1 5 | "Hornet 4 Drive",21.4,6,258,110,3.08,3.215,19.44,1,0,3,1 6 | "Hornet Sportabout",18.7,8,360,175,3.15,3.44,17.02,0,0,3,2 7 | "Valiant",18.1,6,225,105,2.76,3.46,20.22,1,0,3,1 8 | "Duster 360",14.3,8,360,245,3.21,3.57,15.84,0,0,3,4 9 | "Merc 240D",24.4,4,146.7,62,3.69,3.19,20,1,0,4,2 10 | "Merc 230",22.8,4,140.8,95,3.92,3.15,22.9,1,0,4,2 11 | "Merc 280",19.2,6,167.6,123,3.92,3.44,18.3,1,0,4,4 12 | "Merc 280C",17.8,6,167.6,123,3.92,3.44,18.9,1,0,4,4 13 | "Merc 450SE",16.4,8,275.8,180,3.07,4.07,17.4,0,0,3,3 14 | "Merc 450SL",17.3,8,275.8,180,3.07,3.73,17.6,0,0,3,3 15 | "Merc 450SLC",15.2,8,275.8,180,3.07,3.78,18,0,0,3,3 16 | "Cadillac Fleetwood",10.4,8,472,205,2.93,5.25,17.98,0,0,3,4 17 | "Lincoln Continental",10.4,8,460,215,3,5.424,17.82,0,0,3,4 18 | "Chrysler Imperial",14.7,8,440,230,3.23,5.345,17.42,0,0,3,4 19 | "Fiat 128",32.4,4,78.7,66,4.08,2.2,19.47,1,1,4,1 20 | "Honda Civic",30.4,4,75.7,52,4.93,1.615,18.52,1,1,4,2 21 | "Toyota Corolla",33.9,4,71.1,65,4.22,1.835,19.9,1,1,4,1 22 | "Toyota Corona",21.5,4,120.1,97,3.7,2.465,20.01,1,0,3,1 23 | "Dodge Challenger",15.5,8,318,150,2.76,3.52,16.87,0,0,3,2 24 | "AMC Javelin",15.2,8,304,150,3.15,3.435,17.3,0,0,3,2 25 | "Camaro Z28",13.3,8,350,245,3.73,3.84,15.41,0,0,3,4 26 | "Pontiac Firebird",19.2,8,400,175,3.08,3.845,17.05,0,0,3,2 27 | "Fiat X1-9",27.3,4,79,66,4.08,1.935,18.9,1,1,4,1 28 | "Porsche 914-2",26,4,120.3,91,4.43,2.14,16.7,0,1,5,2 29 | "Lotus Europa",30.4,4,95.1,113,3.77,1.513,16.9,1,1,5,2 30 | "Ford Pantera L",15.8,8,351,264,4.22,3.17,14.5,0,1,5,4 31 | "Ferrari Dino",19.7,6,145,175,3.62,2.77,15.5,0,1,5,6 32 | "Maserati Bora",15,8,301,335,3.54,3.57,14.6,0,1,5,8 33 | "Volvo 142E",21.4,4,121,109,4.11,2.78,18.6,1,1,4,2 34 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_datafile/rsconnect/shinyapps.io/jrowen/rhandsontable_datafile.dcf: -------------------------------------------------------------------------------- 1 | name: rhandsontable_datafile 2 | account: jrowen 3 | server: shinyapps.io 4 | bundleId: 204891 5 | url: https://jrowen.shinyapps.io/rhandsontable_datafile 6 | when: 1434599336.49539 7 | asMultiple: FALSE 8 | asStatic: FALSE 9 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_datafile/server.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | shinyServer(function(input, output, session) { 4 | fname = tempfile(fileext = ".csv") 5 | 6 | observe({ 7 | # remove button and isolate to update file automatically 8 | # after each table change 9 | input$saveBtn 10 | hot = isolate(input$hot) 11 | if (!is.null(hot)) { 12 | write.csv(hot_to_r(input$hot), fname) 13 | print(fname) 14 | } 15 | }) 16 | 17 | output$hot = renderRHandsontable({ 18 | if (!is.null(input$hot)) { 19 | DF = hot_to_r(input$hot) 20 | } else { 21 | DF = read.csv("mtcars.csv", stringsAsFactors = FALSE) 22 | } 23 | 24 | rhandsontable(DF) %>% 25 | hot_table(highlightCol = TRUE, highlightRow = TRUE) 26 | }) 27 | }) 28 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_datafile/ui.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | shinyUI(fluidPage( 4 | titlePanel("Edit Data File"), 5 | helpText("Changes to the table will be automatically saved to the source file."), 6 | # uncomment line below to use action button to commit changes 7 | actionButton("saveBtn", "Save"), 8 | rHandsontableOutput("hot") 9 | )) 10 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_frontier/returns.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/inst/examples/rhandsontable_frontier/returns.rds -------------------------------------------------------------------------------- /inst/examples/rhandsontable_frontier/rsconnect/shinyapps.io/jrowen/rhandsontable_frontier.dcf: -------------------------------------------------------------------------------- 1 | name: rhandsontable_frontier 2 | account: jrowen 3 | server: shinyapps.io 4 | bundleId: 205664 5 | url: https://jrowen.shinyapps.io/rhandsontable_frontier 6 | when: 1434683062.32562 7 | asMultiple: FALSE 8 | asStatic: FALSE 9 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_frontier/server.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(rhandsontable) 3 | library(lpSolve) 4 | library(quadprog) 5 | library(data.table) 6 | library(ggplot2) 7 | 8 | tkrs = c("MSFT", "CAT", "AXP", "DIS", "MMM") 9 | 10 | # quantmod::getSymbols(tkrs, from = "2012-06-01", auto.assign=TRUE) 11 | # returns = Reduce(function(x, y) merge(x, y), lapply(tkrs, get)) 12 | # returns = returns[, names(returns)[grepl("Close", names(returns))]] 13 | # returns = data.table(Date = time(returns), coredata(returns)) 14 | # returns = melt(returns, id.vars = "Date", variable.name = "Name", 15 | # value.name = "Price")[order(Name, Date)] 16 | # returns[, `:=`(Name = gsub(".Close", "", Name))] 17 | # returns[, `:=`(Return = c(NA, Price[-1] / head(Price, -1) - 1)), by = Name] 18 | # saveRDS(returns, "returns.rds") 19 | returns = readRDS("returns.rds") 20 | setkey(returns, Name) 21 | 22 | shinyServer(function(input, output, session) { 23 | values = reactiveValues( 24 | hot_corr = cor(dcast.data.table(returns, Date ~ Name, value.var = "Return")[ 25 | , !"Date", with = FALSE], use = "pairwise.complete.obs"), 26 | hot_retvol = returns[, list(Return = mean(Return, na.rm = TRUE), 27 | Vol = sd(Return, na.rm = TRUE)), by = Name]) 28 | 29 | calc = reactive({ 30 | # load initial values 31 | vol = values[["hot_retvol"]]$Vol 32 | ret = values[["hot_retvol"]]$Return 33 | corr = values[["hot_corr"]] 34 | 35 | cov = diag(vol) %*% corr %*% diag(vol) 36 | 37 | # min wt 38 | n = length(ret) 39 | mat = diag(n) 40 | dir = rep(">=", n) 41 | rhs = rep(0, n) 42 | 43 | # max wt 44 | mat = rbind(mat, -diag(n)) 45 | dir = c(dir, rep(">=", n)) 46 | rhs = c(rhs, rep(-1, n)) 47 | 48 | # sum wt 49 | mat = rbind(rep(1, n), mat) 50 | dir = c("=", dir) 51 | rhs = c(1, rhs) 52 | meq = 1 53 | 54 | max_ret = lp(direction = "max", 55 | objective.in = ret, 56 | const.mat = mat, 57 | const.dir = dir, 58 | const.rhs = rhs) 59 | min_rsk = solve.QP(Dmat = cov, 60 | dvec = rep(0, n), 61 | Amat = t(mat), 62 | bvec = rhs, 63 | meq = meq, 64 | factorized = FALSE) 65 | 66 | frntr.mat = rbind(ret, mat) 67 | frntr.meq = meq + 1 68 | frntr = lapply( 69 | head(seq(t(min_rsk$solution) %*% ret, t(max_ret$solution) %*% ret, 70 | length.out = 100), -1), function(x) { 71 | sol = solve.QP(Dmat = cov, 72 | dvec = rep(0, n), 73 | Amat = t(frntr.mat), 74 | bvec = c(x, rhs), 75 | meq = frntr.meq, 76 | factorized = FALSE) 77 | data.frame(Return = x, 78 | Risk = sqrt(t(sol$solution) %*% cov %*% sol$solution)) 79 | }) 80 | frntr = do.call(rbind, frntr) 81 | 82 | list(Covariance = cov, 83 | `Max Return` = max_ret$solution, 84 | `Min Risk` = min_rsk$solution, 85 | Frontier = frntr) 86 | }) 87 | 88 | output$hot_retvol = renderRHandsontable({ 89 | if (!is.null(input$hot_retvol)) { 90 | DF = hot_to_r(input$hot_retvol) 91 | values[["hot_retvol"]] = DF 92 | rhandsontable(DF) 93 | } else if (!is.null(values[["hot_retvol"]])) { 94 | DF = values[["hot_retvol"]] 95 | rhandsontable(DF) 96 | } 97 | }) 98 | 99 | output$hot_corr = renderRHandsontable({ 100 | if (!is.null(input$hot_corr)) { 101 | DF = hot_to_r(input$hot_corr) 102 | DF[upper.tri(DF)] = DF[lower.tri(DF)] 103 | values[["hot_corr"]] = DF 104 | DF[upper.tri(DF)] = NA 105 | rhandsontable(DF) 106 | } else if (!is.null(values[["hot_corr"]])) { 107 | DF = values[["hot_corr"]] 108 | DF[upper.tri(DF)] = NA 109 | rhandsontable(DF) 110 | } 111 | }) 112 | 113 | output$plot = renderPlot({ 114 | if (!is.null(calc())) { 115 | DF = calc()$Frontier 116 | DF$Return = (1 + DF$Return) ^ 252 - 1 117 | DF$Risk = DF$Risk * sqrt(252) 118 | DF$Sharpe = DF$Return / DF$Risk 119 | ggplot(DF) + 120 | geom_line(aes(x = Risk, y = Return)) + 121 | geom_point(data = DF[which.max(DF$Sharpe),], 122 | aes(x = Risk, y = Return), color = "red", size = 4) + 123 | scale_x_continuous(label = scales::percent) + 124 | scale_y_continuous(label = scales::percent) + 125 | theme_bw() 126 | } 127 | }) 128 | }) 129 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_frontier/ui.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(rhandsontable) 3 | library(ggplot2) 4 | 5 | shinyUI(fluidPage( 6 | titlePanel("Efficient Frontier"), 7 | fluidRow( 8 | column(3, 9 | rHandsontableOutput("hot_retvol") 10 | ), 11 | column(3, 12 | rHandsontableOutput("hot_corr") 13 | ) 14 | ), 15 | fluidRow( 16 | column(6, 17 | plotOutput("plot") 18 | ) 19 | ) 20 | )) 21 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_highlight/app.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | library(shiny) 3 | 4 | app <- shinyApp( 5 | ui = fluidPage( 6 | numericInput("myindex", "Highlight", min = 0, max = 9, value = 1), 7 | rHandsontableOutput("hot", width = 350) 8 | ), 9 | server = function(input, output) { 10 | data = reactive({ 11 | if (!is.null(input$hot)) { 12 | DF = hot_to_r(input$hot) 13 | } else { 14 | DF = data.frame(val = 1:10, bool = TRUE, nm = LETTERS[1:10], 15 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 16 | stringsAsFactors = F) 17 | } 18 | DF 19 | }) 20 | 21 | output$hot <- renderRHandsontable({ 22 | DF = data() 23 | myindex = input$myindex - 1 24 | if (!is.null(DF)) { 25 | rhandsontable(DF, myindex = myindex) %>% 26 | hot_cols(renderer = "function(instance, td, row, col, prop, value, cellProperties) { 27 | Handsontable.renderers.TextRenderer.apply(this, arguments); 28 | if (instance.params && instance.params.myindex == row) td.style.background = 'lightblue'; 29 | } 30 | ") 31 | } 32 | }) 33 | } 34 | ) 35 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_output/rsconnect/shinyapps.io/jrowen/rhandsontable_output.dcf: -------------------------------------------------------------------------------- 1 | name: rhandsontable_output 2 | account: jrowen 3 | server: shinyapps.io 4 | appId: 47090 5 | bundleId: 545821 6 | url: https://jrowen.shinyapps.io/rhandsontable_output/ 7 | when: 1472665398.20152 8 | asMultiple: FALSE 9 | asStatic: FALSE 10 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_output/server.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | shinyServer(function(input, output, session) { 4 | # this caching step is no longer necessary 5 | # it was left as an example 6 | values = reactiveValues() 7 | 8 | data = reactive({ 9 | if (!is.null(input$hot)) { 10 | DF = hot_to_r(input$hot) 11 | } else { 12 | if (is.null(values[["DF"]])) 13 | DF = data.frame(val = 1:10, bool = TRUE, nm = LETTERS[1:10], 14 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 15 | stringsAsFactors = F) 16 | else 17 | DF = values[["DF"]] 18 | } 19 | 20 | values[["DF"]] = DF 21 | DF 22 | }) 23 | 24 | output$hot <- renderRHandsontable({ 25 | DF = data() 26 | if (!is.null(DF)) 27 | rhandsontable(DF, useTypes = as.logical(input$useType), stretchH = "all") 28 | }) 29 | }) 30 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_output/ui.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | shinyUI(fluidPage( 4 | titlePanel("Handsontable"), 5 | sidebarLayout( 6 | sidebarPanel( 7 | helpText("Handsontable demo output. Column add/delete does work ", 8 | "for tables with defined column properties, including type."), 9 | radioButtons("useType", "Use Data Types", c("TRUE", "FALSE")) 10 | ), 11 | mainPanel( 12 | rHandsontableOutput("hot", width = 350) 13 | ) 14 | ) 15 | )) 16 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_portfolio/returns.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrowen/rhandsontable/dd296376820ed864e8f938581482878a40f54a0e/inst/examples/rhandsontable_portfolio/returns.rds -------------------------------------------------------------------------------- /inst/examples/rhandsontable_portfolio/rsconnect/shinyapps.io/jrowen/rhandsontable_portfolio.dcf: -------------------------------------------------------------------------------- 1 | name: rhandsontable_portfolio 2 | account: jrowen 3 | server: shinyapps.io 4 | bundleId: 205667 5 | url: https://jrowen.shinyapps.io/rhandsontable_portfolio 6 | when: 1434683220.25623 7 | asMultiple: FALSE 8 | asStatic: FALSE 9 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_portfolio/server.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(rhandsontable) 3 | library(dygraphs) 4 | library(data.table) 5 | library(reshape2) 6 | library(quantmod) 7 | 8 | tkrs = c("MSFT", "CAT", "AXP", "DIS", "MMM") 9 | 10 | # quantmod::getSymbols(tkrs, from = "2012-06-01", auto.assign=TRUE) 11 | # returns = Reduce(function(x, y) merge(x, y), lapply(tkrs, get)) 12 | # returns = returns[, names(returns)[grepl("Close", names(returns))]] 13 | # returns = data.table(Date = time(returns), coredata(returns)) 14 | # returns = melt(returns, id.vars = "Date", variable.name = "Name", 15 | # value.name = "Price")[order(Name, Date)] 16 | # returns[, `:=`(Name = gsub(".Close", "", Name))] 17 | # returns[, `:=`(Return = c(NA, Price[-1] / head(Price, -1) - 1)), by = Name] 18 | # saveRDS(returns, "returns.rds") 19 | returns = readRDS("returns.rds") 20 | setkey(returns, Name) 21 | 22 | port = data.table(Name = tkrs, 23 | Position = ifelse(rnorm(length(tkrs)) > 0, "Long", "Short"), 24 | Weight = runif(length(tkrs))) 25 | port[, `:=`(Weight = Weight / sum(Weight)), by = Position] 26 | port[Position == "Long", `:=`(Weight = Weight * 1.3)] 27 | port[Position == "Short", `:=`(Weight = Weight * 0.3)] 28 | setkey(port, Name) 29 | 30 | shinyServer(function(input, output, session) { 31 | values = reactiveValues(hot = port) 32 | 33 | calc = reactive({ 34 | port = values[["hot"]] 35 | perf = na.omit(returns[port]) 36 | perf = perf[, list(Return = ifelse(Position == "Long", 1, -1) * 37 | Weight * Return), by = Date][order(Date)] 38 | perf[, `:=`(CumulRet = cumprod(1 + Return) - 1)] 39 | 40 | list(Perf = perf) 41 | }) 42 | 43 | output$hot = renderRHandsontable({ 44 | DT = NULL 45 | if (!is.null(input$hot)) { 46 | DT = setDT(hot_to_r(input$hot)) 47 | if (input$reweight) { 48 | DT[Position == "Long", `:=`(Weight = Weight / sum(Weight) * 1.3)] 49 | DT[Position == "Short", `:=`(Weight = Weight / sum(Weight) * 0.3)] 50 | } 51 | values[["hot"]] = DT 52 | } else if (!is.null(values[["hot"]])) { 53 | DT = values[["hot"]] 54 | } 55 | 56 | if (!is.null(DT)) 57 | rhandsontable(DT) %>% 58 | hot_col(col = "Position", type = "dropdown", 59 | source = c("Long", "Short")) %>% 60 | hot_col(col = "Name", readOnly = TRUE) %>% 61 | hot_cols(columnSorting = list(column = which(names(DT) == "Name"), 62 | sortOrder = TRUE)) 63 | }) 64 | 65 | output$plot = renderDygraph({ 66 | if (!is.null(calc())) { 67 | dt_plot = xts(calc()$Perf$CumulRet, calc()$Perf$Date) 68 | dygraph(dt_plot, main = "Cumulative Return") %>% 69 | dySeries("V1", label = "Portfolio") %>% 70 | dyLimit(as.numeric(calc()$Perf$CumulRet[1]), color = "red") 71 | } 72 | }) 73 | }) 74 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_portfolio/ui.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | library(dygraphs) 3 | 4 | shinyUI(fluidPage( 5 | titlePanel("130/30 Portfolio Returns"), 6 | fluidRow( 7 | column(12, 8 | helpText("Change the position type and weights to recalculate the ", 9 | "return stream.")) 10 | ), 11 | fluidRow( 12 | column(4, 13 | rHandsontableOutput("hot"), 14 | checkboxInput("reweight", "Reweight?") 15 | ), 16 | column(6, 17 | dygraphOutput("plot") 18 | ) 19 | ) 20 | )) 21 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_search/life_expectancy.csv: -------------------------------------------------------------------------------- 1 | country,region,population,female,male 2 | Afghanistan,Asia,32526562,61.9,59.3 3 | Albania,Europe,2896679,80.7,75.1 4 | Algeria,Africa,39666519,77.5,73.8 5 | Angola,Africa,25021974,54,50.9 6 | Antigua and Barbuda,Americas,91818,78.6,74.1 7 | Argentina,Americas,43416755,79.9,72.7 8 | Armenia,Asia,3017712,77.7,71.6 9 | Australia,Oceania,23968973,84.8,80.9 10 | Austria,Europe,8544586,83.9,79 11 | Azerbaijan,Asia,9753968,75.8,69.6 12 | Bahamas,Americas,388019,79.1,72.9 13 | Bahrain,Asia,1377237,77.9,76.2 14 | Bangladesh,Asia,160995642,73.1,70.6 15 | Barbados,Americas,284215,77.9,73.1 16 | Belarus,Europe,9495826,78,66.5 17 | Belgium,Europe,11299192,83.5,78.6 18 | Belize,Americas,359287,73.1,67.5 19 | Benin,Africa,10879829,61.1,58.8 20 | Bhutan,Asia,774830,70.1,69.5 21 | Bolivia,Americas,10724705,73.3,68.2 22 | Bosnia and Herzegovina,Europe,3810416,79.7,75 23 | Botswana,Africa,2262485,68.1,63.3 24 | Brazil,Americas,207847528,78.7,71.4 25 | Bulgaria,Europe,7149787,78,71.1 26 | Burkina Faso,Africa,18105570,60.5,59.1 27 | Burundi,Africa,11178921,61.6,57.7 28 | Cabo Verde,Africa,520502,75,71.3 29 | Cambodia,Asia,15577899,70.7,66.6 30 | Cameroon,Africa,23344179,58.6,55.9 31 | Canada,Americas,35939927,84.1,80.2 32 | Central African Republic,Africa,4900274,54.1,50.9 33 | Chad,Africa,14037472,54.5,51.7 34 | Chile,Americas,17948141,83.4,77.4 35 | China,Asia,1376048943,77.6,74.6 36 | Colombia,Americas,48228704,78.4,71.2 37 | Comoros,Africa,788474,65.2,61.9 38 | Congo,Africa,4620330,66.3,63.2 39 | Costa Rica,Americas,4807850,82.2,77.1 40 | Croatia,Europe,4240317,81.2,74.7 41 | Cuba,Americas,11389562,81.4,76.9 42 | Cyprus,Asia,1165300,82.7,78.3 43 | Czech Republic,Europe,10543186,81.7,75.9 44 | Democratic Republic of the Congo,Africa,77266814,61.5,58.3 45 | Denmark,Europe,5669081,82.5,78.6 46 | Djibouti,Africa,887861,65.3,61.8 47 | Dominican Republic,Americas,10528391,77.1,70.9 48 | Ecuador,Americas,16144363,79,73.5 49 | Egypt,Africa,91508084,73.2,68.8 50 | El Salvador,Americas,6126583,77.9,68.8 51 | Equatorial Guinea,Africa,845060,60,56.6 52 | Eritrea,Africa,5227791,67,62.4 53 | Estonia,Europe,1312558,82,72.7 54 | Ethiopia,Africa,99390750,66.8,62.8 55 | Fiji,Oceania,892145,73.1,67 56 | Finland,Europe,5503457,83.8,78.3 57 | France,Europe,64395345,85.4,79.4 58 | Gabon,Africa,1725292,67.2,64.7 59 | Gambia,Africa,1990924,62.5,59.8 60 | Georgia,Asia,3999812,78.3,70.3 61 | Germany,Europe,80688545,83.4,78.7 62 | Ghana,Africa,27409893,63.9,61 63 | Greece,Europe,10954617,83.6,78.3 64 | Grenada,Americas,106825,76.1,71.2 65 | Guatemala,Americas,16342897,75.2,68.5 66 | Guinea,Africa,12608590,59.8,58.2 67 | Guinea-Bissau,Africa,1844325,60.5,57.2 68 | Guyana,Americas,767085,68.5,63.9 69 | Haiti,Americas,10711067,65.5,61.5 70 | Honduras,Americas,8075060,77,72.3 71 | Hungary,Europe,9855023,79.1,72.3 72 | Iceland,Europe,329425,84.1,81.2 73 | India,Asia,1311050527,69.9,66.9 74 | Indonesia,Asia,257563815,71.2,67.1 75 | Iran,Asia,79109272,76.6,74.5 76 | Iraq,Asia,36423395,71.8,66.2 77 | Ireland,Europe,4688465,83.4,79.4 78 | Israel,Asia,8064036,84.3,80.6 79 | Italy,Europe,59797685,84.8,80.5 80 | Jamaica,Americas,2793335,78.6,73.9 81 | Japan,Asia,126573481,86.8,80.5 82 | Jordan,Asia,7594547,75.9,72.5 83 | Kazakhstan,Asia,17625226,74.7,65.7 84 | Kenya,Africa,46050302,65.8,61.1 85 | Kiribati,Oceania,112423,68.8,63.7 86 | Kuwait,Asia,3892115,76,73.7 87 | Kyrgyzstan,Asia,5939962,75.1,67.2 88 | Latvia,Europe,1970503,79.2,69.6 89 | Lebanon,Asia,5850743,76.5,73.5 90 | Lesotho,Africa,2135022,55.4,51.7 91 | Liberia,Africa,4503438,62.9,59.8 92 | Libya,Africa,6278438,75.6,70.1 93 | Lithuania,Europe,2878405,79.1,68.1 94 | Luxembourg,Europe,567110,84,79.8 95 | Madagascar,Africa,24235390,67,63.9 96 | Malawi,Africa,17215232,59.9,56.7 97 | Malaysia,Asia,30331007,77.3,72.7 98 | Maldives,Asia,363657,80.2,76.9 99 | Mali,Africa,17599694,58.3,58.2 100 | Malta,Europe,418670,83.7,79.7 101 | Mauritania,Africa,4067564,64.6,61.6 102 | Mauritius,Africa,1273212,77.8,71.4 103 | Mexico,Americas,127017224,79.5,73.9 104 | Mongolia,Asia,2959134,73.2,64.7 105 | Montenegro,Europe,625781,78.1,74.1 106 | Morocco,Africa,34377511,75.4,73.3 107 | Mozambique,Africa,27977863,59.4,55.7 108 | Myanmar,Asia,53897154,68.5,64.6 109 | Namibia,Africa,2458830,68.3,63.1 110 | Nepal,Asia,28513700,70.8,67.7 111 | Netherlands,Europe,16924929,83.6,80 112 | New Zealand,Oceania,4528526,83.3,80 113 | Nicaragua,Americas,6082032,77.9,71.5 114 | Niger,Africa,19899120,62.8,60.9 115 | Nigeria,Africa,182201962,55.6,53.4 116 | Norway,Europe,5210967,83.7,79.8 117 | Oman,Asia,4490541,79.2,75 118 | Pakistan,Asia,188924874,67.5,65.5 119 | Panama,Americas,3929141,81.1,74.7 120 | Papua New Guinea,Oceania,7619321,65.4,60.6 121 | Paraguay,Americas,6639123,76,72.2 122 | Peru,Americas,31376670,78,73.1 123 | Philippines,Asia,100699395,72,65.3 124 | Poland,Europe,38611794,81.3,73.6 125 | Portugal,Europe,10349803,83.9,78.2 126 | Qatar,Asia,2235355,80,77.4 127 | Romania,Europe,19511324,78.8,71.4 128 | Rwanda,Africa,11609666,71.1,60.9 129 | Saint Lucia,Americas,184999,77.9,72.6 130 | Saint Vincent and the Grenadines,Americas,109462,75.2,71.3 131 | Samoa,Oceania,193228,77.5,70.9 132 | Sao Tome and Principe,Africa,190344,69.4,65.6 133 | Saudi Arabia,Asia,31540372,76,73.2 134 | Senegal,Africa,15129273,68.6,64.6 135 | Serbia,Europe,8850975,78.4,72.9 136 | Seychelles,Africa,96471,78,69.1 137 | Sierra Leone,Africa,6453184,50.8,49.3 138 | Singapore,Asia,5603740,86.1,80 139 | Slovakia,Europe,5426258,80.2,72.9 140 | Slovenia,Europe,2067526,83.7,77.9 141 | Solomon Islands,Oceania,583591,70.8,67.9 142 | Somalia,Africa,10787104,56.6,53.5 143 | South Africa,Africa,54490406,66.2,59.3 144 | South Sudan,Africa,12339812,58.6,56.1 145 | Spain,Europe,46121699,85.5,80.1 146 | Sri Lanka,Asia,20715010,78.3,71.6 147 | Sudan,Africa,40234882,65.9,62.4 148 | Suriname,Americas,542975,74.7,68.6 149 | Swaziland,Africa,1286970,61.1,56.6 150 | Sweden,Europe,9779426,84,80.7 151 | Switzerland,Europe,8298663,85.3,81.3 152 | Syrian Arab Republic,Asia,18502413,69.9,59.9 153 | Tajikistan,Asia,8481855,73.6,66.6 154 | Thailand,Asia,67959359,78,71.9 155 | Timor-Leste,Asia,1184765,70.1,66.6 156 | Togo,Africa,7304578,61.1,58.6 157 | Tonga,Oceania,106170,76.4,70.6 158 | Trinidad and Tobago,Americas,1360088,74.8,67.9 159 | Tunisia,Africa,11253554,77.8,73 160 | Turkey,Asia,78665830,78.9,72.6 161 | Turkmenistan,Asia,5373502,70.5,62.2 162 | Uganda,Africa,39032383,64.3,60.3 163 | Ukraine,Europe,44823765,76.1,66.3 164 | United Arab Emirates,Asia,9156963,78.6,76.4 165 | United Kingdom,Europe,64715810,83,79.4 166 | Uruguay,Americas,3431555,80.4,73.3 167 | Uzbekistan,Asia,29893488,72.7,66.1 168 | Vanuatu,Oceania,264652,74,70.1 169 | Venezuela,Americas,31108083,78.5,70 170 | Yemen,Asia,26832215,67.2,64.3 171 | Zambia,Africa,16211767,64.7,59 172 | Zimbabwe,Africa,15602751,62.3,59 173 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_search/rsconnect/shinyapps.io/ginberg/rhandsontable_search.dcf: -------------------------------------------------------------------------------- 1 | name: rhandsontable_search 2 | title: rhandsontable_search 3 | username: 4 | account: ginberg 5 | server: shinyapps.io 6 | hostUrl: https://api.shinyapps.io/v1 7 | appId: 237393 8 | bundleId: 1162619 9 | url: https://ginberg.shinyapps.io/rhandsontable_search/ 10 | when: 1515119291.23049 11 | asMultiple: FALSE 12 | asStatic: FALSE 13 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_search/server.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | shinyServer(function(input, output, session) { 4 | fname = tempfile(fileext = ".csv") 5 | 6 | observe({ 7 | # remove button and isolate to update file automatically 8 | # after each table change 9 | input$saveBtn 10 | hot = isolate(input$hot) 11 | if (!is.null(hot)) { 12 | write.csv(hot_to_r(input$hot), fname) 13 | print(fname) 14 | } 15 | }) 16 | 17 | output$hot = renderRHandsontable({ 18 | if (!is.null(input$hot)) { 19 | DF = hot_to_r(input$hot) 20 | } else { 21 | DF = read.csv("life_expectancy.csv", stringsAsFactors = FALSE) 22 | } 23 | 24 | rhandsontable(DF, search = TRUE) %>% 25 | hot_table(highlightCol = TRUE, highlightRow = TRUE) 26 | }) 27 | 28 | output$saveText<- renderUI({ 29 | HTML("") 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /inst/examples/rhandsontable_search/ui.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | shinyUI(fluidPage( 4 | titlePanel("Edit Data File"), 5 | helpText("Changes to the table will be automatically saved to the source file."), 6 | 7 | # uncomment line below to use action button to commit changes 8 | fluidRow( 9 | column(width=2, textInput("searchField", "Search")), 10 | column(width=2, uiOutput("saveText"), actionButton("saveBtn", "Save")) 11 | ), 12 | rHandsontableOutput("hot") 13 | )) 14 | -------------------------------------------------------------------------------- /inst/examples/rmarkdown/flexdash_example.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Untitled" 3 | output: 4 | flexdashboard::flex_dashboard: 5 | orientation: rows 6 | social: menu 7 | source_code: embed 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | library(rhandsontable) 12 | ``` 13 | 14 | Column {data-width=400} 15 | ------------------------------------- 16 | 17 | ### Table 1 18 | 19 | ```{r} 20 | MAT = matrix(rnorm(10000 * 100), nrow = 100, dimnames= list(1:100, 1:10000)) 21 | 22 | rhandsontable(MAT, width = "100%", height = "100%") 23 | ``` 24 | 25 | Column {data-width=600} 26 | ------------------------------------- 27 | 28 | ### Table 2 29 | 30 | ```{r} 31 | MAT = matrix(rnorm(10 * 10), nrow = 10, dimnames= list(1:10, 1:10)) 32 | 33 | rhandsontable(MAT) 34 | ``` 35 | 36 | ### Table 3 37 | 38 | ```{r} 39 | MAT = matrix(rnorm(10 * 10), nrow = 10, dimnames= list(1:10, 1:10)) 40 | 41 | rhandsontable(MAT) 42 | ``` 43 | 44 | -------------------------------------------------------------------------------- /inst/examples/sparkline.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | DF = data.frame(val = 1:10, bool = TRUE, big = LETTERS[1:10], 4 | small = factor(letters[1:10]), 5 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 6 | stringsAsFactors = FALSE) 7 | 8 | DF$chart = sapply(1:10, 9 | function(x) jsonlite::toJSON(list(values=rnorm(10), 10 | options = list(type = "bar")))) 11 | rhandsontable(DF, rowHeaders = NULL) %>% 12 | hot_col("chart", renderer = htmlwidgets::JS("renderSparkline")) 13 | 14 | 15 | spk_df <- data.frame( 16 | value = 1:2, 17 | factor = c("A", "B"), 18 | chart = sapply( 19 | list( 20 | list( 21 | values=c(3,3,3,-3,-3,-3), 22 | options=list(type="bar", zeroAxis=FALSE) 23 | ), 24 | list( 25 | values=runif(10, -3, 3), 26 | options=list(type="bar", zeroAxis=FALSE, barColor="purple", negBarColor="yellow") 27 | ) 28 | ), 29 | jsonlite::toJSON 30 | ), 31 | stringsAsFactors = FALSE 32 | ) 33 | 34 | rhandsontable(spk_df, rowHeaders = NULL, width = 550, height = 300) %>% 35 | hot_col("chart", renderer = htmlwidgets::JS("renderSparkline")) 36 | -------------------------------------------------------------------------------- /inst/examples/types.R: -------------------------------------------------------------------------------- 1 | library(rhandsontable) 2 | 3 | DF = data.frame(val = 1:10, 4 | bool = TRUE, 5 | big = LETTERS[1:10], 6 | small = factor(letters[1:10]), 7 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 8 | stringsAsFactors = FALSE) 9 | 10 | rhandsontable(DF) 11 | 12 | DF2 = data.frame(val = c(NA, 2:10), 13 | bool = c(NA, rep(TRUE, 9)), 14 | big = c(NA, LETTERS[1:9]), 15 | small = c(NA, factor(letters[1:9])), 16 | dt = c(NA, seq(from = Sys.Date(), by = "days", length.out = 9)), 17 | dt_ch = c(NA, as.character(seq(from = Sys.Date(), by = "days", length.out = 9))), 18 | stringsAsFactors = FALSE) 19 | 20 | rhandsontable(DF2) 21 | -------------------------------------------------------------------------------- /inst/htmlwidgets/rhandsontable.css: -------------------------------------------------------------------------------- 1 | .handsontable .currentRow { 2 | background-color: #E7E8EF; 3 | } 4 | 5 | .handsontable .currentCol { 6 | background-color: #F9F9FB; 7 | } 8 | 9 | .handsontable { 10 | overflow: auto; 11 | } 12 | 13 | /* fix for sparkline hover */ 14 | .jqstooltip{ 15 | width: auto !important; 16 | height: auto !important; 17 | } 18 | 19 | /* fix for shiny datepicker */ 20 | .datepicker { 21 | z-index: 1000 !important; 22 | } 23 | 24 | .handsontable table thead th { 25 | white-space: pre-line; 26 | /*max-width: /* enter here your max header width */ 27 | } 28 | -------------------------------------------------------------------------------- /inst/htmlwidgets/rhandsontable.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'rhandsontable', 4 | 5 | type: 'output', 6 | 7 | params: null, 8 | 9 | initialize: function(el, width, height) { 10 | 11 | return { 12 | 13 | }; 14 | 15 | }, 16 | 17 | renderValue: function(el, x, instance) { 18 | 19 | // convert json to array 20 | if (x.data.length > 0 && x.data[0].constructor === Array) { 21 | x.data = x.data; 22 | } else { 23 | x.data = toArray(x.data.map(function(d) { 24 | return x.rColnames.map(function(ky) { 25 | return d[ky]; 26 | }); 27 | })); 28 | } 29 | 30 | if (x.isHeatmap === true) { 31 | x.afterLoadData = this.initHeatmap; 32 | x.beforeChangeRender = this.updateHeatmap; 33 | } 34 | 35 | if (x.overflow) { 36 | $("#" + el.id).css('overflow', x.overflow); 37 | } 38 | 39 | if (x.rowHeaderWidth) { 40 | $("#" + el.id).css('col.rowHeader', x.rowHeaderWidth + 'px'); 41 | } 42 | 43 | //this.afterRender(x); 44 | 45 | this.params = x; 46 | 47 | if (instance.hot) { // update existing instance 48 | if (x.debug && x.debug > 0) { 49 | console.log("rhandsontable: update table"); 50 | } 51 | 52 | instance.hot.params = x; 53 | instance.hot.updateSettings(x); 54 | } else { // create new instance 55 | if (x.debug && x.debug > 0) { 56 | console.log("rhandsontable: new table"); 57 | } 58 | 59 | instance.hot = new Handsontable(el, x); 60 | 61 | this.afterChangeCallback(x); 62 | this.afterCellMetaCallback(x); 63 | this.afterRowAndColChange(x); 64 | 65 | if (x.selectCallback) { 66 | this.afterSelectCallback(x); 67 | } 68 | 69 | instance.hot.params = x; 70 | instance.hot.updateSettings(x); 71 | 72 | var searchField = document.getElementById('searchField'); 73 | if (typeof(searchField) != 'undefined' && searchField !== null) { 74 | Handsontable.dom.addEvent(searchField, 'keyup', function (event) { 75 | var search = instance.hot.getPlugin('search'); 76 | var queryResult = search.query(this.value); 77 | instance.hot.render(); 78 | }); 79 | } 80 | } 81 | }, 82 | 83 | resize: function(el, width, height, instance) { 84 | 85 | }, 86 | 87 | afterRender: function(x) { 88 | x.afterRender = function(isForced) { 89 | var plugin = this.getPlugin('autoColumnSize'); 90 | if (plugin.isEnabled() && this.params) { 91 | if (this.params && this.params.debug) { 92 | if (this.params.debug > 0) { 93 | console.log("rhandsontable: resizing column widths"); 94 | } 95 | } 96 | 97 | var wdths = plugin.widths; 98 | for(var i = 0, colCount = this.countCols(); i < colCount ; i++) { 99 | if (this.params.columns && this.params.columns[i].renderer.name != "customRenderer") { 100 | plugin.calculateColumnsWidth(i, 300, true); 101 | } 102 | } 103 | } 104 | }; 105 | }, 106 | 107 | afterChangeCallback: function(x) { 108 | 109 | x.afterChange = function(changes, source) { 110 | if (this.params && this.params.debug) { 111 | if (this.params.debug > 0) { 112 | console.log("afterChange: " + source); 113 | } 114 | if (this.params.debug > 1) { 115 | console.log("afterChange:"); 116 | console.log(changes); 117 | } 118 | } 119 | 120 | if (HTMLWidgets.shinyMode) { 121 | if (changes && (changes[0][2] !== null || changes[0][3] !== null)) { 122 | if (this.sortIndex && this.sortIndex.length !== 0) { 123 | c = [this.sortIndex[changes[0][0]][0], changes[0].slice(1, 1 + 3)]; 124 | } else { 125 | c = changes; 126 | } 127 | 128 | if (this.params && this.params.debug) { 129 | if (this.params.debug > 0) { 130 | console.log("afterChange: Shiny.onInputChange: " + this.rootElement.id); 131 | } 132 | } 133 | Shiny.onInputChange(this.rootElement.id, { 134 | data: this.getData(), 135 | changes: { event: "afterChange", changes: c, source: source }, 136 | params: this.params 137 | }); 138 | } else if (source == "loadData" && this.params) { 139 | 140 | if (this.params && this.params.debug) { 141 | if (this.params.debug > 0) { 142 | console.log("afterChange: Shiny.onInputChange: " + this.rootElement.id); 143 | } 144 | } 145 | // push input change to shiny so input$hot and output$hot are in sync (see #137) 146 | Shiny.onInputChange(this.rootElement.id, { 147 | data: this.getData(), 148 | changes: { event: "afterChange", changes: null }, 149 | params: this.params 150 | }); 151 | } 152 | } 153 | 154 | }; 155 | 156 | x.afterLoadData = function(firstTime) { 157 | if (this.params && this.params.debug) { 158 | if (this.params.debug > 0) { 159 | console.log("afterLoadData: " + firstTime); 160 | } 161 | } 162 | }; 163 | 164 | x.afterChangesObserved = function(firstTime) { 165 | if (this.params && this.params.debug) { 166 | if (this.params.debug > 0) { 167 | console.log("afterChangesObserved"); 168 | } 169 | } 170 | }; 171 | 172 | x.afterInit = function() { 173 | if (this.params && this.params.debug) { 174 | if (this.params.debug > 0) { 175 | console.log("afterInit"); 176 | } 177 | } 178 | }; 179 | }, 180 | 181 | afterCellMetaCallback: function(x) { 182 | 183 | x.afterSetCellMeta = function(r, c, key, val) { 184 | 185 | if (HTMLWidgets.shinyMode && key === "comment") { 186 | if (this.params && this.params.debug) { 187 | if (this.params.debug > 0) { 188 | console.log("afterSetCellMeta: Shiny.onInputChange: " + this.rootElement.id); 189 | } 190 | } 191 | Shiny.onInputChange(this.rootElement.id + "_comment", { 192 | data: this.getData(), 193 | comment: { r: r + 1, c: c + 1, key: key, val: val}, 194 | params: this.params 195 | }); 196 | } 197 | 198 | }; 199 | }, 200 | 201 | afterSelectCallback: function(x) { 202 | 203 | x.afterSelectionEnd = function(r, c, r2, c2) { 204 | 205 | var r_all = []; 206 | var c_all = []; 207 | if (HTMLWidgets.shinyMode) { 208 | if ( r2 < r ) { r2 = [r, r = r2][0]; } 209 | for ( var i=r; i <= r2; i++ ) { 210 | r_all.push( this.toPhysicalRow(i) + 1 ); 211 | } 212 | if ( c2 < c ) { c2 = [c, c = c2][0]; } 213 | for ( var ii=c; ii <= c2; ii++ ) { 214 | c_all.push( this.toPhysicalColumn(ii) + 1 ); 215 | } 216 | 217 | if (this.params && this.params.debug) { 218 | if (this.params.debug > 0) { 219 | console.log("afterSelectionEnd: Shiny.onInputChange: " + this.rootElement.id); 220 | } 221 | } 222 | Shiny.onInputChange(this.rootElement.id + "_select:rhandsontable.customSelectDeserializer", { 223 | data: this.getData(), 224 | select: { r: r + 1, 225 | c: c + 1, 226 | r2: r2 + 1, 227 | c2: c2 + 1, 228 | rAll: r_all, 229 | cAll: c_all }, 230 | params: this.params 231 | }); 232 | } 233 | 234 | }; 235 | }, 236 | 237 | afterRowAndColChange: function(x) { 238 | 239 | x.afterCreateRow = function(ind, ct) { 240 | 241 | if (HTMLWidgets.shinyMode) { 242 | 243 | if (this.params && this.params.columns) { 244 | for(var i = 0, colCount = this.countCols(); i < colCount ; i++) { 245 | this.setDataAtCell(ind, i, this.params.columns[i].default); 246 | } 247 | } 248 | 249 | if (this.params && this.params.debug) { 250 | if (this.params.debug > 0) { 251 | console.log("afterCreateRow: Shiny.onInputChange: " + this.rootElement.id); 252 | } 253 | } 254 | Shiny.onInputChange(this.rootElement.id, { 255 | data: this.getData(), 256 | changes: { event: "afterCreateRow", ind: ind, ct: ct }, 257 | params: this.params 258 | }); 259 | } 260 | }; 261 | 262 | x.afterRemoveRow = function(ind, ct) { 263 | 264 | if (HTMLWidgets.shinyMode) { 265 | if (this.params && this.params.debug) { 266 | if (this.params.debug > 0) { 267 | console.log("afterRemoveRow: Shiny.onInputChange: " + this.rootElement.id); 268 | } 269 | } 270 | Shiny.onInputChange(this.rootElement.id, { 271 | data: this.getData(), 272 | changes: { event: "afterRemoveRow", ind: ind, ct: ct }, 273 | params: this.params 274 | }); 275 | } 276 | }; 277 | 278 | x.afterCreateCol = function(ind, ct) { 279 | 280 | if (HTMLWidgets.shinyMode) { 281 | if (this.params && this.params.debug) { 282 | if (this.params.debug > 0) { 283 | console.log("afterCreateCol: Shiny.onInputChange: " + this.rootElement.id); 284 | } 285 | } 286 | Shiny.onInputChange(this.rootElement.id, { 287 | data: this.getData(), 288 | changes: { event: "afterCreateCol", ind: ind, ct: ct }, 289 | params: this.params 290 | }); 291 | } 292 | }; 293 | 294 | x.afterRemoveCol = function(ind, ct) { 295 | 296 | if (HTMLWidgets.shinyMode) 297 | if (this.params && this.params.debug) { 298 | if (this.params.debug > 0) { 299 | console.log("afterRemoveCol: Shiny.onInputChange: " + this.rootElement.id); 300 | } 301 | } 302 | Shiny.onInputChange(this.rootElement.id, { 303 | data: this.getData(), 304 | changes: { event: "afterRemoveCol", ind: ind, ct: ct }, 305 | params: this.params 306 | }); 307 | }; 308 | 309 | x.afterRowMove = function(ind, ct) { 310 | 311 | if (HTMLWidgets.shinyMode) 312 | if (this.params && this.params.debug) { 313 | if (this.params.debug > 0) { 314 | console.log("afterRowMove: Shiny.onInputChange: " + this.rootElement.id); 315 | } 316 | } 317 | Shiny.onInputChange(this.rootElement.id, { 318 | data: this.getData(), 319 | changes: { event: "afterRowMove", ind: ind, ct: ct }, 320 | params: this.params 321 | }); 322 | }; 323 | 324 | }, 325 | 326 | // see http://handsontable.com/demo/heatmaps.html 327 | initHeatmap: function(firstTime, source) { 328 | this.heatmap = []; 329 | 330 | for(var i = 0, colCount = this.countCols(); i < colCount ; i++) { 331 | this.heatmap[i] = generateHeatmapData.call(this, i); 332 | } 333 | }, 334 | 335 | updateHeatmap: function(change, source) { 336 | this.heatmap[change[0][1]] = generateHeatmapData.call(this, change[0][1]); 337 | } 338 | 339 | }); 340 | 341 | function generateHeatmapData(colId) { 342 | 343 | var values = this.getDataAtCol(colId); 344 | 345 | return { 346 | min: Math.min.apply(null, values), 347 | max: Math.max.apply(null, values) 348 | }; 349 | } 350 | 351 | // https://stackoverflow.com/questions/22477612/converting-array-of-objects-into-array-of-arrays 352 | function toArray(input) { 353 | var result = input.map(function(obj) { 354 | return Object.keys(obj).map(function(key) { 355 | return obj[key]; 356 | }); 357 | }); 358 | return result; 359 | } 360 | 361 | // csv logic adapted from https://github.com/juantascon/jquery-handsontable-csv 362 | function csvString(instance, sep, dec) { 363 | 364 | var headers = instance.getColHeader(); 365 | 366 | var csv = headers.join(sep) + "\n"; 367 | 368 | for (var i = 0; i < instance.countRows(); i++) { 369 | var row = []; 370 | for (var h in headers) { 371 | var col = instance.propToCol(h); 372 | var value = instance.getDataAtRowProp(i, col); 373 | if ( !isNaN(value) ) { 374 | value = value.toString().replace(".", dec); 375 | } 376 | row.push(value); 377 | } 378 | 379 | csv += row.join(sep); 380 | csv += "\n"; 381 | } 382 | 383 | return csv; 384 | } 385 | 386 | function customRenderer(instance, TD, row, col, prop, value, cellProperties) { 387 | if (['date', 'handsontable', 'dropdown'].indexOf(cellProperties.type) > -1) { 388 | type = 'autocomplete'; 389 | } else { 390 | type = cellProperties.type; 391 | } 392 | Handsontable.renderers.getRenderer(type)(instance, TD, row, col, prop, value, cellProperties); 393 | } 394 | 395 | function renderSparkline(instance, td, row, col, prop, value, cellProperties) { 396 | try { 397 | val = JSON.parse(value); 398 | 399 | nm = 'sparklines_r' + row + '_c' + col; 400 | td.innerHTML = ''; 401 | 402 | // adjust for cell padding 403 | if (val.options && val.options.type && 404 | ['bar', 'tristate'].indexOf(val.options.type[0]) > -1) { 405 | val.options.barSpacing = 1; 406 | val.options.barWidth = Math.max(1, Math.round((instance.getColWidth(col) - 8 - (val.values.length - 1)) / val.values.length)); 407 | } else { 408 | if (!val.options) { 409 | val.options = {}; 410 | } 411 | val.options.width = (instance.getColWidth(col) - 8) + "px"; 412 | } 413 | 414 | $('.' + nm).sparkline(val.values, val.options); 415 | } catch(err) { 416 | td.innerHTML = ''; 417 | } 418 | 419 | return td; 420 | } 421 | 422 | // http://docs.handsontable.com/0.16.1/demo-custom-renderers.html 423 | function strip_tags(input, allowed) { 424 | var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, 425 | commentsAndPhpTags = /|<\?(?:php)?[\s\S]*?\?>/gi; 426 | 427 | // making sure the allowed arg is a string containing only tags in lowercase () 428 | allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); 429 | 430 | return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) { 431 | return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : ''; 432 | }); 433 | } 434 | 435 | function safeHtmlRenderer(instance, td, row, col, prop, value, cellProperties) { 436 | var escaped = Handsontable.helper.stringify(value); 437 | if (instance.getSettings().allowedTags) { 438 | tags = instance.getSettings().allowedTags; 439 | } else { 440 | tags = ''; 441 | } 442 | escaped = strip_tags(escaped, tags); //be sure you only allow certain HTML tags to avoid XSS threats (you should also remove unwanted HTML attributes) 443 | td.innerHTML = escaped; 444 | 445 | return td; 446 | } 447 | 448 | 449 | // if the table is in an ineractive session, shiny mode, 450 | // then we register the handler for setting data interactively 451 | if (HTMLWidgets.shinyMode) { 452 | Shiny.addCustomMessageHandler( 453 | "handler_setDataAtCell", 454 | function(message) { 455 | var hot = window.HTMLWidgets.find('#' + message.id).hot; 456 | var count = message.size; 457 | 458 | // setDataAtCell is overloaded so there's different parameters to send one value 459 | if( count == 1 ) { 460 | hot.setDataAtCell(message.row, message.col, message.val); 461 | return; 462 | } 463 | // if sending 2+ values to the table then we use an array of arrays 464 | var datArr = []; 465 | // when the table is sorted we need to send the values to their visual locations 466 | if ( hot.getPlugin('columnSorting').isSorted() ) { 467 | for ( var i=0; i < count; i++ ) { 468 | datArr[datArr.length] = [hot.toVisualRow(message.row[i]), 469 | hot.toVisualColumn(message.col[i]), 470 | message.val[i]]; 471 | } 472 | } else { 473 | // when not sorted we just use the values from R 474 | for ( var i=0; i < count; i++ ) { 475 | datArr[datArr.length] = [message.row[i], message.col[i], message.val[i]]; 476 | } 477 | } 478 | hot.setDataAtCell(datArr); 479 | }); 480 | } 481 | 482 | -------------------------------------------------------------------------------- /inst/htmlwidgets/rhandsontable.yaml: -------------------------------------------------------------------------------- 1 | # (uncomment to add a dependency) 2 | dependencies: 3 | - name: handsontable 4 | version: 6.2.2 5 | src: "htmlwidgets/lib/handsontable" 6 | script: 7 | - handsontable.full.min.js 8 | - all.min.js 9 | stylesheet: handsontable.full.min.css 10 | - name: numbro.languages 11 | version: 2.0.6 12 | src: "htmlwidgets/lib/numbro" 13 | script: languages.min.js 14 | - name: chroma 15 | version: 1.3.3 16 | src: "htmlwidgets/lib/chroma" 17 | script: chroma.min.js 18 | - name: jquery 19 | version: 3.2.1 20 | src: "htmlwidgets/lib/jquery" 21 | script: jquery.min.js 22 | - name: sparkline 23 | version: 2.1.2 24 | src: "htmlwidgets/lib/sparkline" 25 | script: jquery.sparkline.min.js 26 | - name: rhandsontable 27 | version: 0.3.7 28 | src: "htmlwidgets" 29 | stylesheet: rhandsontable.css 30 | -------------------------------------------------------------------------------- /inst/rstudio/addins.dcf: -------------------------------------------------------------------------------- 1 | Name: Edit a Data Frame 2 | Description: Interactively edit a data frame. 3 | Binding: editAddin 4 | Interactive: true 5 | -------------------------------------------------------------------------------- /man/editAddin.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/editAddin.R 3 | \name{editAddin} 4 | \alias{editAddin} 5 | \title{Edit a Data Frame.} 6 | \usage{ 7 | editAddin() 8 | } 9 | \description{ 10 | Interactively edit a \code{data.frame} or \code{data.table}. The resulting 11 | code will be emitted as a call to reload the data from a temp RDS file. 12 | } 13 | \details{ 14 | This addin can be used to interactively edit. The intended way to use this is 15 | as follows: 16 | 17 | 1. Highlight a symbol naming a \code{data.frame} or \code{data.table} in your 18 | R session, e.g. \code{mtcars}. 2. Execute this addin, to interactively edit 19 | it. 20 | 21 | When you're done, the code performing this operation will be emitted at the 22 | cursor position. 23 | 24 | This function borrows heavily from 25 | \href{https://github.com/rstudio/addinexamples/blob/master/R/subsetAddin.R}{rstudio/addinexamples/subsetAddin} 26 | } 27 | -------------------------------------------------------------------------------- /man/hot_cell.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_cell} 4 | \alias{hot_cell} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_cell(hot, row, col, comment = NULL, readOnly = NULL) 8 | } 9 | \arguments{ 10 | \item{hot}{rhandsontable object} 11 | 12 | \item{row}{numeric row index} 13 | 14 | \item{col}{column name or index} 15 | 16 | \item{comment}{character comment to add to cell} 17 | 18 | \item{readOnly}{logical making the cell read-only} 19 | } 20 | \description{ 21 | Configure single cell. See 22 | \href{https://handsontable.com/}{Handsontable.js} for details. 23 | } 24 | \examples{ 25 | library(rhandsontable) 26 | DF = data.frame(val = 1:10, bool = TRUE, big = LETTERS[1:10], 27 | small = letters[1:10], 28 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 29 | stringsAsFactors = FALSE) 30 | 31 | rhandsontable(DF) \%>\% 32 | hot_cell(1, 1, comment = "Test comment") \%>\% 33 | hot_cell(2, 3, readOnly = TRUE) 34 | } 35 | \seealso{ 36 | \code{\link{hot_cols}}, \code{\link{hot_rows}} 37 | } 38 | -------------------------------------------------------------------------------- /man/hot_col.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_col} 4 | \alias{hot_col} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_col( 8 | hot, 9 | col, 10 | type = NULL, 11 | format = NULL, 12 | source = NULL, 13 | strict = NULL, 14 | readOnly = NULL, 15 | validator = NULL, 16 | allowInvalid = NULL, 17 | halign = NULL, 18 | valign = NULL, 19 | renderer = NULL, 20 | copyable = NULL, 21 | dateFormat = NULL, 22 | default = NULL, 23 | language = NULL, 24 | ... 25 | ) 26 | } 27 | \arguments{ 28 | \item{hot}{rhandsontable object} 29 | 30 | \item{col}{vector of column names or indices} 31 | 32 | \item{type}{character specify the data type. Options include: 33 | numeric, date, checkbox, select, dropdown, autocomplete, password, 34 | and handsontable (not implemented yet)} 35 | 36 | \item{format}{characer specifying column format. See Cell Types at 37 | \href{https://handsontable.com/}{Handsontable.js} for the formatting 38 | options for each data type. Numeric columns are formatted using 39 | \href{https://numbrojs.com}{Numbro.js}.} 40 | 41 | \item{source}{a vector of choices for select, dropdown and autocomplete 42 | column types} 43 | 44 | \item{strict}{logical specifying whether values not in the \code{source} 45 | vector will be accepted} 46 | 47 | \item{readOnly}{logical making the column read-only} 48 | 49 | \item{validator}{character defining a Javascript function to be used 50 | to validate user input. See \code{hot_validate_numeric} and 51 | \code{hot_validate_character} for pre-build validators.} 52 | 53 | \item{allowInvalid}{logical specifying whether invalid data will be 54 | accepted. Invalid data cells will be color red.} 55 | 56 | \item{halign}{character defining the horizontal alignment. Possible 57 | values are htLeft, htCenter, htRight and htJustify} 58 | 59 | \item{valign}{character defining the vertical alignment. Possible 60 | values are htTop, htMiddle, htBottom} 61 | 62 | \item{renderer}{character defining a Javascript function to be used 63 | to format column cells. Can be used to implement conditional formatting.} 64 | 65 | \item{copyable}{logical defining whether data in a cell can be copied using 66 | Ctrl + C} 67 | 68 | \item{dateFormat}{character defining the date format. See 69 | \href{https://github.com/moment/moment}{Moment.js} for details.} 70 | 71 | \item{default}{default column value for new rows (NA if not specified; shiny only)} 72 | 73 | \item{language}{locale passed to \href{https://numbrojs.com}{Numbro.js}; 74 | default is 'en-US'.} 75 | 76 | \item{...}{passed to handsontable} 77 | } 78 | \description{ 79 | Configure single column. 80 | } 81 | \examples{ 82 | library(rhandsontable) 83 | DF = data.frame(val = 1:10, bool = TRUE, big = LETTERS[1:10], 84 | small = letters[1:10], 85 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 86 | stringsAsFactors = FALSE) 87 | 88 | rhandsontable(DF, rowHeaders = NULL) \%>\% 89 | hot_col(col = "big", type = "dropdown", source = LETTERS) \%>\% 90 | hot_col(col = "small", type = "autocomplete", source = letters, 91 | strict = FALSE) 92 | } 93 | \seealso{ 94 | \code{\link{hot_cols}}, \code{\link{hot_rows}}, \code{\link{hot_cell}} 95 | } 96 | -------------------------------------------------------------------------------- /man/hot_cols.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_cols} 4 | \alias{hot_cols} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_cols( 8 | hot, 9 | colWidths = NULL, 10 | columnSorting = NULL, 11 | manualColumnMove = NULL, 12 | manualColumnResize = NULL, 13 | fixedColumnsLeft = NULL, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{hot}{rhandsontable object} 19 | 20 | \item{colWidths}{a scalar or numeric vector of column widths} 21 | 22 | \item{columnSorting}{logical enabling row sorting. Sorting only alters the 23 | table presentation and the original dataset row order is maintained. 24 | The sorting will be done when a user click on column name} 25 | 26 | \item{manualColumnMove}{logical enabling column drag-and-drop reordering} 27 | 28 | \item{manualColumnResize}{logical enabline column width resizing} 29 | 30 | \item{fixedColumnsLeft}{a scalar indicating the number of columns to 31 | freeze on the left} 32 | 33 | \item{...}{passed to hot_col} 34 | } 35 | \description{ 36 | Configure multiple columns. 37 | } 38 | \examples{ 39 | library(rhandsontable) 40 | DF = data.frame(val = 1:10, bool = TRUE, big = LETTERS[1:10], 41 | small = letters[1:10], 42 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 43 | stringsAsFactors = FALSE) 44 | 45 | rhandsontable(DF) \%>\% 46 | hot_cols(columnSorting = TRUE) 47 | } 48 | \seealso{ 49 | \code{\link{hot_col}}, \code{\link{hot_rows}}, \code{\link{hot_cell}} 50 | } 51 | -------------------------------------------------------------------------------- /man/hot_context_menu.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_context_menu} 4 | \alias{hot_context_menu} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_context_menu( 8 | hot, 9 | allowRowEdit = TRUE, 10 | allowColEdit = TRUE, 11 | allowReadOnly = FALSE, 12 | allowComments = FALSE, 13 | allowCustomBorders = FALSE, 14 | customOpts = NULL, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{hot}{rhandsontable object} 20 | 21 | \item{allowRowEdit}{logical enabling row editing} 22 | 23 | \item{allowColEdit}{logical enabling column editing. Note that 24 | Handsontable does not support column add/remove when column types 25 | are defined (i.e. useTypes == TRUE in rhandsontable).} 26 | 27 | \item{allowReadOnly}{logical enabling read-only toggle} 28 | 29 | \item{allowComments}{logical enabling comments} 30 | 31 | \item{allowCustomBorders}{logical enabling custom borders} 32 | 33 | \item{customOpts}{list} 34 | 35 | \item{...}{ignored} 36 | } 37 | \description{ 38 | Configure the options for the right-click context menu 39 | } 40 | \examples{ 41 | library(rhandsontable) 42 | DF = data.frame(val = 1:10, bool = TRUE, big = LETTERS[1:10], 43 | small = letters[1:10], 44 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 45 | stringsAsFactors = FALSE) 46 | 47 | rhandsontable(DF) \%>\% 48 | hot_context_menu(allowRowEdit = FALSE, allowColEdit = FALSE) 49 | } 50 | -------------------------------------------------------------------------------- /man/hot_heatmap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_heatmap} 4 | \alias{hot_heatmap} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_heatmap(hot, cols, color_scale = c("#ED6D47", "#17F556"), renderer = NULL) 8 | } 9 | \arguments{ 10 | \item{hot}{rhandsontable object} 11 | 12 | \item{cols}{numeric vector of columns to include in the heatmap. If missing 13 | all columns are used.} 14 | 15 | \item{color_scale}{character vector that includes the lower and upper 16 | colors} 17 | 18 | \item{renderer}{character defining a Javascript function to be used 19 | to determine the cell colors. If missing, 20 | \code{rhandsontable:::renderer_heatmap} is used.} 21 | } 22 | \description{ 23 | Add heatmap to table. 24 | } 25 | \examples{ 26 | MAT = matrix(rnorm(50), nrow = 10, dimnames = list(LETTERS[1:10], 27 | letters[1:5])) 28 | 29 | rhandsontable(MAT) \%>\% 30 | hot_heatmap() 31 | } 32 | -------------------------------------------------------------------------------- /man/hot_row.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_row} 4 | \alias{hot_row} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_row(hot, row, readOnly = NULL) 8 | } 9 | \arguments{ 10 | \item{hot}{rhandsontable object} 11 | 12 | \item{row}{numeric vector of row indexes} 13 | 14 | \item{readOnly}{logical making the row(s) read-only} 15 | } 16 | \description{ 17 | Configure properties of all cells in a given row(s). 18 | Note that hot_row is not to be confused with \code{\link{hot_rows}}. See 19 | \href{https://handsontable.com/}{Handsontable.js} for details. 20 | } 21 | \examples{ 22 | library(rhandsontable) 23 | MAT = matrix(rnorm(50), nrow = 10, dimnames = list(LETTERS[1:10], 24 | letters[1:5])) 25 | 26 | rhandsontable(MAT, width = 300, height = 150) \%>\% 27 | hot_row(c(1,3:5), readOnly = TRUE) 28 | } 29 | \seealso{ 30 | \code{\link{hot_cols}}, \code{\link{hot_cell}}, \code{\link{hot_rows}} 31 | } 32 | -------------------------------------------------------------------------------- /man/hot_rows.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_rows} 4 | \alias{hot_rows} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_rows(hot, rowHeights = NULL, fixedRowsTop = NULL) 8 | } 9 | \arguments{ 10 | \item{hot}{rhandsontable object} 11 | 12 | \item{rowHeights}{a scalar or numeric vector of row heights} 13 | 14 | \item{fixedRowsTop}{a scaler indicating the number of rows to 15 | freeze on the top} 16 | } 17 | \description{ 18 | Configure row settings that pertain to the entire table. 19 | Note that hot_rows is not to be confused with \code{\link{hot_row}}. See 20 | \href{https://handsontable.com/}{Handsontable.js} for details. 21 | } 22 | \examples{ 23 | library(rhandsontable) 24 | MAT = matrix(rnorm(50), nrow = 10, dimnames = list(LETTERS[1:10], 25 | letters[1:5])) 26 | 27 | rhandsontable(MAT, width = 300, height = 150) \%>\% 28 | hot_cols(colWidths = 100, fixedColumnsLeft = 1) \%>\% 29 | hot_rows(rowHeights = 50, fixedRowsTop = 1) 30 | } 31 | \seealso{ 32 | \code{\link{hot_cols}}, \code{\link{hot_cell}} 33 | } 34 | -------------------------------------------------------------------------------- /man/hot_table.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_table} 4 | \alias{hot_table} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_table( 8 | hot, 9 | contextMenu = TRUE, 10 | stretchH = "none", 11 | customBorders = NULL, 12 | highlightRow = NULL, 13 | highlightCol = NULL, 14 | enableComments = FALSE, 15 | overflow = NULL, 16 | rowHeaderWidth = NULL, 17 | ... 18 | ) 19 | } 20 | \arguments{ 21 | \item{hot}{rhandsontable object} 22 | 23 | \item{contextMenu}{logical enabling the right-click menu} 24 | 25 | \item{stretchH}{character describing column stretching. Options are 'all', 'right', 26 | and 'none'} 27 | 28 | \item{customBorders}{json object} 29 | 30 | \item{highlightRow}{logical enabling row highlighting for the selected 31 | cell} 32 | 33 | \item{highlightCol}{logical enabling column highlighting for the 34 | selected cell} 35 | 36 | \item{enableComments}{logical enabling comments in the table} 37 | 38 | \item{overflow}{character setting the css overflow behavior. Options are 39 | auto (default), hidden and visible} 40 | 41 | \item{rowHeaderWidth}{numeric width (in px) for the rowHeader column} 42 | 43 | \item{...}{passed to \href{https://handsontable.com/}{Handsontable.js} constructor} 44 | } 45 | \description{ 46 | Configure table. See 47 | \href{https://handsontable.com/}{Handsontable.js} for details. 48 | } 49 | \examples{ 50 | library(rhandsontable) 51 | DF = data.frame(val = 1:10, bool = TRUE, big = LETTERS[1:10], 52 | small = letters[1:10], 53 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 54 | stringsAsFactors = FALSE) 55 | 56 | rhandsontable(DF) \%>\% 57 | hot_table(highlightCol = TRUE, highlightRow = TRUE) 58 | } 59 | \seealso{ 60 | \code{\link{rhandsontable}} 61 | } 62 | -------------------------------------------------------------------------------- /man/hot_to_r.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_to_r} 4 | \alias{hot_to_r} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_to_r(...) 8 | } 9 | \arguments{ 10 | \item{...}{passed to \code{rhandsontable:::toR}} 11 | } 12 | \description{ 13 | Convert handsontable data to R object. Can be used in a \code{shiny} app 14 | to convert the input json to an R dataset. 15 | } 16 | \seealso{ 17 | \code{\link{rHandsontableOutput}} 18 | } 19 | -------------------------------------------------------------------------------- /man/hot_validate_character.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_validate_character} 4 | \alias{hot_validate_character} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_validate_character(hot, cols, choices, allowInvalid = FALSE) 8 | } 9 | \arguments{ 10 | \item{hot}{rhandsontable object} 11 | 12 | \item{cols}{vector of column names or indices} 13 | 14 | \item{choices}{a vector of acceptable numeric choices. It will be evaluated 15 | after min and max if specified.} 16 | 17 | \item{allowInvalid}{logical specifying whether invalid data will be 18 | accepted. Invalid data cells will be color red.} 19 | } 20 | \description{ 21 | Add numeric validation to a column 22 | } 23 | \examples{ 24 | library(rhandsontable) 25 | DF = data.frame(val = 1:10, bool = TRUE, big = LETTERS[1:10], 26 | small = letters[1:10], 27 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 28 | stringsAsFactors = FALSE) 29 | 30 | rhandsontable(DF) \%>\% 31 | hot_validate_character(col = "big", choices = LETTERS[1:10]) 32 | } 33 | \seealso{ 34 | \code{\link{hot_validate_numeric}} 35 | } 36 | -------------------------------------------------------------------------------- /man/hot_validate_numeric.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{hot_validate_numeric} 4 | \alias{hot_validate_numeric} 5 | \title{Handsontable widget} 6 | \usage{ 7 | hot_validate_numeric( 8 | hot, 9 | cols, 10 | min = NULL, 11 | max = NULL, 12 | choices = NULL, 13 | exclude = NULL, 14 | allowInvalid = FALSE 15 | ) 16 | } 17 | \arguments{ 18 | \item{hot}{rhandsontable object} 19 | 20 | \item{cols}{vector of column names or indices} 21 | 22 | \item{min}{minimum value to accept} 23 | 24 | \item{max}{maximum value to accept} 25 | 26 | \item{choices}{a vector of acceptable numeric choices. It will be evaluated 27 | after min and max if specified.} 28 | 29 | \item{exclude}{a vector of unacceptable numeric values} 30 | 31 | \item{allowInvalid}{logical specifying whether invalid data will be 32 | accepted. Invalid data cells will be color red.} 33 | } 34 | \description{ 35 | Add numeric validation to a column 36 | } 37 | \examples{ 38 | library(rhandsontable) 39 | MAT = matrix(rnorm(50), nrow = 10, dimnames = list(LETTERS[1:10], 40 | letters[1:5])) 41 | 42 | rhandsontable(MAT * 10) \%>\% 43 | hot_validate_numeric(col = 1, min = -50, max = 50, exclude = 40) 44 | 45 | rhandsontable(MAT * 10) \%>\% 46 | hot_validate_numeric(col = 1, choices = c(10, 20, 40)) 47 | } 48 | \seealso{ 49 | \code{\link{hot_validate_character}} 50 | } 51 | -------------------------------------------------------------------------------- /man/rHandsontableOutput.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{rHandsontableOutput} 4 | \alias{rHandsontableOutput} 5 | \title{Handsontable widget} 6 | \usage{ 7 | rHandsontableOutput(outputId, width = "100\%", height = "100\%") 8 | } 9 | \arguments{ 10 | \item{outputId}{output variable to read from} 11 | 12 | \item{width, height}{must be a valid CSS unit in pixels 13 | or a number, which will be coerced to a string and have \code{"px"} appended.} 14 | } 15 | \description{ 16 | Shiny bindings for rhandsontable 17 | } 18 | \seealso{ 19 | \code{\link{renderRHandsontable}} 20 | } 21 | -------------------------------------------------------------------------------- /man/renderRHandsontable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{renderRHandsontable} 4 | \alias{renderRHandsontable} 5 | \title{Handsontable widget} 6 | \usage{ 7 | renderRHandsontable(expr, env = parent.frame(), quoted = FALSE) 8 | } 9 | \arguments{ 10 | \item{expr}{an expression that generates an rhandsontable.} 11 | 12 | \item{env}{the environment in which to evaluate \code{expr}.} 13 | 14 | \item{quoted}{is \code{expr} a quoted expression (with \code{quote()})? This 15 | is useful if you want to save an expression in a variable.} 16 | } 17 | \description{ 18 | Shiny bindings for rhandsontable 19 | } 20 | \seealso{ 21 | \code{\link{rHandsontableOutput}}, \code{\link{hot_to_r}} 22 | } 23 | -------------------------------------------------------------------------------- /man/rhandsontable-exports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable-package.R 3 | \name{rhandsontable-exports} 4 | \alias{rhandsontable-exports} 5 | \alias{\%>\%} 6 | \title{rhandsontable exported operators} 7 | \description{ 8 | The following functions are imported and then re-exported 9 | from the rhandsontable package to enable use of the magrittr 10 | pipe operator with no additional library calls 11 | } 12 | -------------------------------------------------------------------------------- /man/rhandsontable-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable-package.R 3 | \docType{package} 4 | \name{rhandsontable-package} 5 | \alias{rhandsontable-package} 6 | \title{rhandsontable} 7 | \description{ 8 | R interface for creating tables using Handsontable, url{https://handsontable.com/} 9 | } 10 | \details{ 11 | For full documentation on the package, visit \url{https://jrowen.github.io/rhandsontable/} 12 | } 13 | -------------------------------------------------------------------------------- /man/rhandsontable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{rhandsontable} 4 | \alias{rhandsontable} 5 | \title{Handsontable widget} 6 | \usage{ 7 | rhandsontable( 8 | data, 9 | colHeaders, 10 | rowHeaders, 11 | comments = NULL, 12 | useTypes = TRUE, 13 | readOnly = NULL, 14 | selectCallback = FALSE, 15 | width = NULL, 16 | height = NULL, 17 | digits = 4, 18 | debug = NULL, 19 | search = FALSE, 20 | ... 21 | ) 22 | } 23 | \arguments{ 24 | \item{data}{a \code{data.table}, \code{data.frame} or \code{matrix}} 25 | 26 | \item{colHeaders}{a vector of column names. If missing \code{colnames} 27 | will be used. Setting to \code{NULL} will omit.} 28 | 29 | \item{rowHeaders}{a vector of row names. If missing \code{rownames} 30 | will be used. Setting to \code{NULL} will omit.} 31 | 32 | \item{comments}{matrix or data.frame of comments; NA values are ignored} 33 | 34 | \item{useTypes}{logical specifying whether column classes should be mapped to 35 | equivalent Javascript types. Note that 36 | Handsontable does not support column add/remove when column types 37 | are defined (i.e. useTypes == TRUE in rhandsontable).} 38 | 39 | \item{readOnly}{logical specifying whether the table is editable} 40 | 41 | \item{selectCallback}{logical enabling the afterSelect event to return data. 42 | This can be used with shiny to tie updates to a selected table cell.} 43 | 44 | \item{width}{numeric table width} 45 | 46 | \item{height}{numeric table height} 47 | 48 | \item{digits}{numeric passed to \code{jsonlite::toJSON}} 49 | 50 | \item{debug}{numeric Javascript log level} 51 | 52 | \item{search}{logical specifying if the data can be searched (see 53 | \url{https://jrowen.github.io/rhandsontable/#Customizing} 54 | and Shiny example in inst/examples/rhandsontable_search)} 55 | 56 | \item{...}{passed to \code{hot_table} and to the \code{params} property of the widget} 57 | } 58 | \description{ 59 | Create a \href{https://handsontable.com/}{Handsontable.js} widget. 60 | } 61 | \details{ 62 | For full documentation on the package, visit \url{https://jrowen.github.io/rhandsontable/} 63 | } 64 | \examples{ 65 | library(rhandsontable) 66 | DF = data.frame(val = 1:10, bool = TRUE, big = LETTERS[1:10], 67 | small = letters[1:10], 68 | dt = seq(from = Sys.Date(), by = "days", length.out = 10), 69 | stringsAsFactors = FALSE) 70 | 71 | rhandsontable(DF, rowHeaders = NULL) 72 | } 73 | \seealso{ 74 | \code{\link{hot_table}}, \code{\link{hot_cols}}, \code{\link{hot_rows}}, \code{\link{hot_cell}} 75 | } 76 | -------------------------------------------------------------------------------- /man/set_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rhandsontable.R 3 | \name{set_data} 4 | \alias{set_data} 5 | \title{Handsontable widget} 6 | \usage{ 7 | set_data(id, row, col, val, session, zero_indexed = F) 8 | } 9 | \arguments{ 10 | \item{id}{The id of the table to interact with.} 11 | 12 | \item{row}{Integer vector of row indexes.} 13 | 14 | \item{col}{Integer vector the column indexes.} 15 | 16 | \item{val}{Vector of values to set at each row-col pair.} 17 | 18 | \item{session}{The session that is associated with your shiny server function. The table is only interactive when used in shiny so we only use set_data when the table is in shiny.} 19 | 20 | \item{zero_indexed}{Default FALSE. Set to TRUE if you are supplying row and col indexes that are already 0-based.} 21 | } 22 | \description{ 23 | Set data inside a Handsontable instance without recreating the widget. Send the new values as a vector of rows, a vector of columns, and a vector of values. If different length vectors are supplied then the shorter ones are recycled to match the length of the longest. 24 | } 25 | -------------------------------------------------------------------------------- /rhandsontable.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: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageCheckArgs: --no-manual 22 | PackageRoxygenize: rd,collate,namespace 23 | --------------------------------------------------------------------------------