├── inst
└── app
│ ├── data
│ └── .gitignore
│ ├── www
│ ├── app_images
│ │ └── .gitignore
│ ├── img_size.js
│ └── taipan.css
│ ├── ui.R
│ └── server.R
├── LICENSE
├── vignettes
├── .gitignore
├── taipan-vignette.R
└── taipan-vignette.Rmd
├── tests
├── testthat.R
└── testthat
│ └── test-taipan.R
├── man
├── figures
│ └── taipan.png
├── taipanQuestions.Rd
└── buildTaipan.Rd
├── NEWS.md
├── docs
├── articles
│ ├── Taipan4editings.png
│ ├── Taipan5plotting.png
│ ├── Taipan1imageInformation.png
│ ├── Taipan2selectionInformation.png
│ ├── Taipan3selectionInformation.png
│ ├── index.html
│ └── taipan-vignette.html
├── reference
│ ├── figures
│ │ └── taipan.png
│ ├── index.html
│ ├── reexports.html
│ ├── sampleQuestions.html
│ ├── tennisQuestions.html
│ ├── tennisQuestionsSmall.html
│ ├── taipan-package.html
│ ├── launchTaipan.html
│ └── buildTaipan.html
├── pkgdown.yml
├── link.svg
├── docsearch.js
├── jquery.sticky-kit.min.js
├── pkgdown.js
├── LICENSE-text.html
├── authors.html
├── pkgdown.css
├── news
│ └── index.html
├── LICENSE.html
├── index.html
└── docsearch.css
├── .Rbuildignore
├── .gitignore
├── NAMESPACE
├── sample_images
├── 2016_HSA_R01_BTomic_AUS_vs_DIstomin_UZB_MS157_clip.0013.png
├── 2016_CT6_R01_CGarcia_FRA_vs_BStrycova_CZE_WS145_clip.0015.png
├── 2016_CT6_R02_ABeck_GER_vs_TBacsinszky_SUI_WS220_clip.0017.png
├── 2016_CT6_R01_EKulichkova_RUS_vs_APetkovic_GER_WS128_clip.0080.png
└── 2016_CT6_R01_JMillman_AUS_vs_DSchwartzman_ARG_MS159_clip.0013.png
├── taipan.Rproj
├── DESCRIPTION
├── LICENSE.md
├── README.md
├── README.Rmd
└── R
├── questions.R
└── build.R
/inst/app/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/inst/app/www/app_images/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2018
2 | COPYRIGHT HOLDER: Stephanie Kobakian
3 |
--------------------------------------------------------------------------------
/vignettes/.gitignore:
--------------------------------------------------------------------------------
1 | taipan-vignette_cache
2 | *.html
3 | *.pdf
--------------------------------------------------------------------------------
/tests/testthat.R:
--------------------------------------------------------------------------------
1 | library(testthat)
2 | library(taipan)
3 |
4 | test_check("taipan")
5 |
--------------------------------------------------------------------------------
/tests/testthat/test-taipan.R:
--------------------------------------------------------------------------------
1 | context("taipan")
2 |
3 | test_that("Taipan unit tests", {
4 | })
5 |
--------------------------------------------------------------------------------
/man/figures/taipan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/man/figures/taipan.png
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | # taipan 0.1.0.9000
2 |
3 | * Added a `NEWS.md` file to track changes to the package.
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/docs/articles/Taipan4editings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/docs/articles/Taipan4editings.png
--------------------------------------------------------------------------------
/docs/articles/Taipan5plotting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/docs/articles/Taipan5plotting.png
--------------------------------------------------------------------------------
/docs/reference/figures/taipan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/docs/reference/figures/taipan.png
--------------------------------------------------------------------------------
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^LICENSE\.md$
4 | ^\.travis\.yml$
5 | ^README\.Rmd$
6 | ^docs$
7 | ^sample_images$
8 |
--------------------------------------------------------------------------------
/docs/pkgdown.yml:
--------------------------------------------------------------------------------
1 | pandoc: 1.19.2.1
2 | pkgdown: 1.1.0
3 | pkgdown_sha: ~
4 | articles:
5 | taipan-vignette: taipan-vignette.html
6 |
7 |
--------------------------------------------------------------------------------
/docs/articles/Taipan1imageInformation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/docs/articles/Taipan1imageInformation.png
--------------------------------------------------------------------------------
/docs/articles/Taipan2selectionInformation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/docs/articles/Taipan2selectionInformation.png
--------------------------------------------------------------------------------
/docs/articles/Taipan3selectionInformation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/docs/articles/Taipan3selectionInformation.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.so
3 | symbols.rds
4 | .Rhistory
5 | .Rproj.user
6 | .travis.yml
7 | revdep
8 | tests/testthat/Rplots.pdf
9 | inst/doc
10 | SolveSpecificData.R
11 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export(buildTaipan)
4 | export(taipanQuestions)
5 | importFrom(downloader,download)
6 | importFrom(shiny,div)
7 | importFrom(shiny,runApp)
8 |
--------------------------------------------------------------------------------
/sample_images/2016_HSA_R01_BTomic_AUS_vs_DIstomin_UZB_MS157_clip.0013.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/sample_images/2016_HSA_R01_BTomic_AUS_vs_DIstomin_UZB_MS157_clip.0013.png
--------------------------------------------------------------------------------
/sample_images/2016_CT6_R01_CGarcia_FRA_vs_BStrycova_CZE_WS145_clip.0015.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/sample_images/2016_CT6_R01_CGarcia_FRA_vs_BStrycova_CZE_WS145_clip.0015.png
--------------------------------------------------------------------------------
/sample_images/2016_CT6_R02_ABeck_GER_vs_TBacsinszky_SUI_WS220_clip.0017.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/sample_images/2016_CT6_R02_ABeck_GER_vs_TBacsinszky_SUI_WS220_clip.0017.png
--------------------------------------------------------------------------------
/sample_images/2016_CT6_R01_EKulichkova_RUS_vs_APetkovic_GER_WS128_clip.0080.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/sample_images/2016_CT6_R01_EKulichkova_RUS_vs_APetkovic_GER_WS128_clip.0080.png
--------------------------------------------------------------------------------
/sample_images/2016_CT6_R01_JMillman_AUS_vs_DSchwartzman_ARG_MS159_clip.0013.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Solve-Geosolutions/taipan/HEAD/sample_images/2016_CT6_R01_JMillman_AUS_vs_DSchwartzman_ARG_MS159_clip.0013.png
--------------------------------------------------------------------------------
/inst/app/www/img_size.js:
--------------------------------------------------------------------------------
1 | Shiny.addCustomMessageHandler('get_dim', function(id) {
2 | var img = document.getElementById("taipan_current_img");
3 | if(img !== null){
4 | Shiny.setInputValue("taipan_img_dim", [img.naturalWidth, img.naturalHeight]);
5 | }
6 | });
7 |
--------------------------------------------------------------------------------
/inst/app/www/taipan.css:
--------------------------------------------------------------------------------
1 | .taipan_image_div {
2 | position:relative;
3 | }
4 | img {
5 | max-width: 100%;
6 | }
7 | #out_img_overlay {
8 | position:absolute;
9 | top:0;
10 | left:0;
11 | z-index: 1;
12 | }
13 |
14 | .nav > li > a {
15 | font-size:19px;
16 | }
17 |
--------------------------------------------------------------------------------
/vignettes/taipan-vignette.R:
--------------------------------------------------------------------------------
1 | ## ----setup, include = FALSE----------------------------------------------
2 | knitr::opts_chunk$set(
3 | collapse = TRUE,
4 | comment = "#>",
5 | fig.align = "centre",
6 | eval = FALSE)
7 | library(taipan)
8 |
9 | ## ---- eval = FALSE-------------------------------------------------------
10 | # # install.packages("devtools")
11 | # devtools::install_github("srkobakian/taipan")
12 |
13 |
--------------------------------------------------------------------------------
/taipan.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: No
4 | SaveWorkspace: No
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
15 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageUseDevtools: Yes
20 | PackageInstallArgs: --no-multiarch --with-keep.source
21 | PackageRoxygenize: rd,collate,namespace,vignette
22 |
--------------------------------------------------------------------------------
/docs/link.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: taipan
2 | Version: 0.1.0.9000
3 | Title: Taipan For R
4 | Authors@R: c(person("Stephanie", "Kobakian", email = "stephanie.kobakian@gmail.com", role = c("aut", "cre")),
5 | person("Mitchell", "O'Hara-Wild", email = "mail@mitchelloharawild.com", role = c("aut")))
6 | Description: Taipan is a tool for annotating images in preparation for analysis.
7 | It allows users to annotate images in an interactive environment.
8 | Users supply images, questions and the possible answers.
9 | When Images are displayed, survey takers can select the appropriate responses.
10 | The answers are stored in a tidy format for analysis.
11 | Depends:
12 | R (>= 3.2.0)
13 | Imports:
14 | shiny,
15 | downloader
16 | Suggests:
17 | testthat,
18 | knitr,
19 | rmarkdown,
20 | tidyverse
21 | URL: https://github.com/srkob1/taipan
22 | BugReports: https://github.com/srkob1/taipan/issues
23 | License: MIT + file LICENSE
24 | Encoding: UTF-8
25 | LazyData: true
26 | ByteCompile: true
27 | RoxygenNote: 6.0.1.9000
28 | VignetteBuilder: knitr
29 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2018 Stephanie Kobakian
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Taipan
4 | =========================================================
5 |
6 | [](https://travis-ci.org/srkob1/taipan)
7 |
8 | Taipan is a Tool for Annotating Images in Preparation for ANalysis.
9 |
10 | The Taipan package creates simple shiny surveys. The web applications can be used locally or deployed and allow people to save survey results as tidy data that is ready to use for analysis.
11 |
12 | The app was initially created to streamline the process of manually tagging images to create a training set. It allows users to provide information regarding entire images, and smaller regions within. It is a survey style tool, with questions being posed for each image and area identified.
13 |
14 | Installation
15 | ------------
16 |
17 | You can install the development version from Github using:
18 |
19 | ``` r
20 | # install.packages("devtools")
21 | devtools::install_github("srkobakian/taipan")
22 | ```
23 |
24 | Usage: coming soon...
25 | ---------------------
26 |
--------------------------------------------------------------------------------
/vignettes/taipan-vignette.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Taipan Vignette"
3 | author: "Stephanie Kobakian"
4 | date: "`r Sys.Date()`"
5 | output: rmarkdown::html_vignette
6 | vignette: >
7 | %\VignetteIndexEntry{Taipan Vignette}
8 | %\VignetteEncoding{UTF-8}
9 | %\VignetteEngine{knitr::rmarkdown}
10 | editor_options:
11 | chunk_output_type: console
12 | ---
13 |
14 | ```{r setup, include = FALSE}
15 | knitr::opts_chunk$set(
16 | collapse = TRUE,
17 | comment = "#>",
18 | fig.align = "centre",
19 | eval = FALSE)
20 | library(taipan)
21 | ```
22 |
23 | The Taipan package creates simple shiny surveys. The web applications can be used locally or deployed and allow people to save survey results as tidy data that is ready to use for analysis.
24 |
25 | The app was initially created to streamline the process of manually tagging images to create a training set.
26 | It allows users to provide information regarding entire images, and smaller regions within. It is a survey style tool, with questions being posed for each image and area identified.
27 |
28 |
29 | ## Installation
30 |
31 | You can install the development version from Github using:
32 |
33 | ```{r, eval = FALSE}
34 | # install.packages("devtools")
35 | devtools::install_github("srkobakian/taipan")
36 | ```
37 |
38 | ## Usage: coming soon...
39 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 |
6 |
7 | ```{r, echo = FALSE}
8 | knitr::opts_chunk$set(
9 | collapse = TRUE,
10 | comment = "#>",
11 | fig.path = "README-"
12 | )
13 | ```
14 |
15 | # Taipan
16 |
17 | [](https://travis-ci.org/srkob1/taipan)
18 |
19 | Taipan is a Tool for Annotating Images in Preparation for ANalysis.
20 |
21 | The Taipan package creates simple shiny surveys. The web applications can be used locally or deployed and allow people to save survey results as tidy data that is ready to use for analysis.
22 |
23 | The app was initially created to streamline the process of manually tagging images to create a training set.
24 | It allows users to provide information regarding entire images, and smaller regions within. It is a survey style tool, with questions being posed for each image and area identified.
25 |
26 |
27 | ## Installation
28 |
29 | You can install the development version from Github using:
30 |
31 | ```{r, eval = FALSE}
32 | # install.packages("devtools")
33 | devtools::install_github("srkobakian/taipan")
34 | ```
35 |
36 | ## Usage: coming soon...
37 |
--------------------------------------------------------------------------------
/inst/app/ui.R:
--------------------------------------------------------------------------------
1 | library(shiny)
2 | library(shinydashboard)
3 |
4 | shinyUI(
5 | dashboardPage(
6 | dashboardHeader(
7 | title = "taipan",
8 | tags$li(class = "dropdown", actionLink("SpecHelp",span(icon("question-circle")," Program specific help"))),
9 | tags$li(class = "dropdown", downloadLink("btn_export", span(icon("download"), " Export Responses"))),
10 | tags$li(class = "dropdown", a(href="https://github.com/srkob1/taipan", target="_blank", span(icon("github"), " GitHub")))
11 | ),
12 | dashboardSidebar(
13 | disable = TRUE
14 | ),
15 | dashboardBody(
16 | includeScript("www/img_size.js"),
17 | includeCSS("www/taipan.css"),
18 | column(6,
19 | box(
20 | title = textOutput("out_img_info"),
21 | div(class = "taipan_image_div",
22 | imageOutput("out_img_overlay",
23 | click = clickOpts(id = "img_click"),
24 | dblclick = dblclickOpts(id = "img_dblclick"),
25 | brush = brushOpts(id = "img_brush"),
26 | inline=TRUE),
27 | imageOutput("out_img",
28 | inline = TRUE)
29 | ),
30 | width = 12,
31 | status = "primary",
32 | collapsible = TRUE
33 | ),
34 | uiOutput("ui_instructions")),
35 |
36 | column(6,
37 | uiOutput("ui_questions"),
38 | actionLink(
39 | "btn_prev",
40 | box(
41 | "Previous",
42 | width = 3,
43 | background = "green"
44 | )
45 | ),
46 | uiOutput("ui_deleteSelection"),
47 | uiOutput("ui_saveSelection"),
48 | actionLink(
49 | "btn_next",
50 | box(
51 | "Next",
52 | width = 3,
53 | background = "green",
54 | offset = 1
55 | )
56 | )
57 | )
58 | )
59 | )
60 | )
61 |
--------------------------------------------------------------------------------
/docs/docsearch.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 |
3 | // register a handler to move the focus to the search bar
4 | // upon pressing shift + "/" (i.e. "?")
5 | $(document).on('keydown', function(e) {
6 | if (e.shiftKey && e.keyCode == 191) {
7 | e.preventDefault();
8 | $("#search-input").focus();
9 | }
10 | });
11 |
12 | $(document).ready(function() {
13 | // do keyword highlighting
14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */
15 | var mark = function() {
16 |
17 | var referrer = document.URL ;
18 | var paramKey = "q" ;
19 |
20 | if (referrer.indexOf("?") !== -1) {
21 | var qs = referrer.substr(referrer.indexOf('?') + 1);
22 | var qs_noanchor = qs.split('#')[0];
23 | var qsa = qs_noanchor.split('&');
24 | var keyword = "";
25 |
26 | for (var i = 0; i < qsa.length; i++) {
27 | var currentParam = qsa[i].split('=');
28 |
29 | if (currentParam.length !== 2) {
30 | continue;
31 | }
32 |
33 | if (currentParam[0] == paramKey) {
34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20"));
35 | }
36 | }
37 |
38 | if (keyword !== "") {
39 | $(".contents").unmark({
40 | done: function() {
41 | $(".contents").mark(keyword);
42 | }
43 | });
44 | }
45 | }
46 | };
47 |
48 | mark();
49 | });
50 | });
51 |
52 | /* Search term highlighting ------------------------------*/
53 |
54 | function matchedWords(hit) {
55 | var words = [];
56 |
57 | var hierarchy = hit._highlightResult.hierarchy;
58 | // loop to fetch from lvl0, lvl1, etc.
59 | for (var idx in hierarchy) {
60 | words = words.concat(hierarchy[idx].matchedWords);
61 | }
62 |
63 | var content = hit._highlightResult.content;
64 | if (content) {
65 | words = words.concat(content.matchedWords);
66 | }
67 |
68 | // return unique words
69 | var words_uniq = [...new Set(words)];
70 | return words_uniq;
71 | }
72 |
73 | function updateHitURL(hit) {
74 |
75 | var words = matchedWords(hit);
76 | var url = "";
77 |
78 | if (hit.anchor) {
79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor;
80 | } else {
81 | url = hit.url + '?q=' + escape(words.join(" "));
82 | }
83 |
84 | return url;
85 | }
86 |
--------------------------------------------------------------------------------
/docs/jquery.sticky-kit.min.js:
--------------------------------------------------------------------------------
1 | /* Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | */
2 | /*
3 | Source: https://github.com/leafo/sticky-kit
4 | License: MIT
5 | */
6 | (function(){var b,f;b=this.jQuery||window.jQuery;f=b(window);b.fn.stick_in_parent=function(d){var A,w,J,n,B,K,p,q,k,E,t;null==d&&(d={});t=d.sticky_class;B=d.inner_scrolling;E=d.recalc_every;k=d.parent;q=d.offset_top;p=d.spacer;w=d.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=b(document);null==w&&(w=!0);J=function(a,d,n,C,F,u,r,G){var v,H,m,D,I,c,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k));
7 | if(!g.length)throw"failed to find stick parent";v=m=!1;(h=null!=p?p&&a.closest(p):b("
"))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q,
8 | u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),eb&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}),
10 | a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize",
11 | y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n max_length) {
32 | max_length = length;
33 | pos = i;
34 | }
35 | }
36 |
37 | // Add class to parent , and enclosing if in dropdown
38 | if (pos >= 0) {
39 | var menu_anchor = $(links[pos]);
40 | menu_anchor.parent().addClass("active");
41 | menu_anchor.closest("li.dropdown").addClass("active");
42 | }
43 | });
44 |
45 | function paths(pathname) {
46 | var pieces = pathname.split("/");
47 | pieces.shift(); // always starts with /
48 |
49 | var end = pieces[pieces.length - 1];
50 | if (end === "index.html" || end === "")
51 | pieces.pop();
52 | return(pieces);
53 | }
54 |
55 | function prefix_length(needle, haystack) {
56 | if (needle.length > haystack.length)
57 | return(0);
58 |
59 | // Special case for length-0 haystack, since for loop won't run
60 | if (haystack.length === 0) {
61 | return(needle.length === 0 ? 1 : 0);
62 | }
63 |
64 | for (var i = 0; i < haystack.length; i++) {
65 | if (needle[i] != haystack[i])
66 | return(i);
67 | }
68 |
69 | return(haystack.length);
70 | }
71 |
72 | /* Clipboard --------------------------*/
73 |
74 | function changeTooltipMessage(element, msg) {
75 | var tooltipOriginalTitle=element.getAttribute('data-original-title');
76 | element.setAttribute('data-original-title', msg);
77 | $(element).tooltip('show');
78 | element.setAttribute('data-original-title', tooltipOriginalTitle);
79 | }
80 |
81 | if(Clipboard.isSupported()) {
82 | $(document).ready(function() {
83 | var copyButton = " ";
84 |
85 | $(".examples, div.sourceCode").addClass("hasCopyButton");
86 |
87 | // Insert copy buttons:
88 | $(copyButton).prependTo(".hasCopyButton");
89 |
90 | // Initialize tooltips:
91 | $('.btn-copy-ex').tooltip({container: 'body'});
92 |
93 | // Initialize clipboard:
94 | var clipboardBtnCopies = new Clipboard('[data-clipboard-copy]', {
95 | text: function(trigger) {
96 | return trigger.parentNode.textContent;
97 | }
98 | });
99 |
100 | clipboardBtnCopies.on('success', function(e) {
101 | changeTooltipMessage(e.trigger, 'Copied!');
102 | e.clearSelection();
103 | });
104 |
105 | clipboardBtnCopies.on('error', function() {
106 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy');
107 | });
108 | });
109 | }
110 | })(window.jQuery || window.$)
111 |
--------------------------------------------------------------------------------
/docs/LICENSE-text.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | License • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
64 |
65 |
66 |
92 |
93 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
114 |
115 |
YEAR: 2018
116 | COPYRIGHT HOLDER: Stephanie Kobakian
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/docs/articles/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Articles • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
64 |
65 |
66 |
92 |
93 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
114 |
115 |
116 |
All vignettes
117 |
118 |
119 |
122 |
123 |
124 |
125 |
126 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/docs/authors.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Authors • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
64 |
65 |
66 |
92 |
93 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
114 |
115 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/docs/pkgdown.css:
--------------------------------------------------------------------------------
1 | /* Sticky footer */
2 |
3 | /**
4 | * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/
5 | * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css
6 | *
7 | * .Site -> body > .container
8 | * .Site-content -> body > .container .row
9 | * .footer -> footer
10 | *
11 | * Key idea seems to be to ensure that .container and __all its parents__
12 | * have height set to 100%
13 | *
14 | */
15 |
16 | html, body {
17 | height: 100%;
18 | }
19 |
20 | body > .container {
21 | display: flex;
22 | height: 100%;
23 | flex-direction: column;
24 |
25 | padding-top: 60px;
26 | }
27 |
28 | body > .container .row {
29 | flex: 1 0 auto;
30 | }
31 |
32 | footer {
33 | margin-top: 45px;
34 | padding: 35px 0 36px;
35 | border-top: 1px solid #e5e5e5;
36 | color: #666;
37 | display: flex;
38 | flex-shrink: 0;
39 | }
40 | footer p {
41 | margin-bottom: 0;
42 | }
43 | footer div {
44 | flex: 1;
45 | }
46 | footer .pkgdown {
47 | text-align: right;
48 | }
49 | footer p {
50 | margin-bottom: 0;
51 | }
52 |
53 | img.icon {
54 | float: right;
55 | }
56 |
57 | img {
58 | max-width: 100%;
59 | }
60 |
61 | /* Typographic tweaking ---------------------------------*/
62 |
63 | .contents h1.page-header {
64 | margin-top: calc(-60px + 1em);
65 | }
66 |
67 | /* Section anchors ---------------------------------*/
68 |
69 | a.anchor {
70 | margin-left: -30px;
71 | display:inline-block;
72 | width: 30px;
73 | height: 30px;
74 | visibility: hidden;
75 |
76 | background-image: url(./link.svg);
77 | background-repeat: no-repeat;
78 | background-size: 20px 20px;
79 | background-position: center center;
80 | }
81 |
82 | .hasAnchor:hover a.anchor {
83 | visibility: visible;
84 | }
85 |
86 | @media (max-width: 767px) {
87 | .hasAnchor:hover a.anchor {
88 | visibility: hidden;
89 | }
90 | }
91 |
92 |
93 | /* Fixes for fixed navbar --------------------------*/
94 |
95 | .contents h1, .contents h2, .contents h3, .contents h4 {
96 | padding-top: 60px;
97 | margin-top: -40px;
98 | }
99 |
100 | /* Static header placement on mobile devices */
101 | @media (max-width: 767px) {
102 | .navbar-fixed-top {
103 | position: absolute;
104 | }
105 | .navbar {
106 | padding: 0;
107 | }
108 | }
109 |
110 |
111 | /* Sidebar --------------------------*/
112 |
113 | #sidebar {
114 | margin-top: 30px;
115 | }
116 | #sidebar h2 {
117 | font-size: 1.5em;
118 | margin-top: 1em;
119 | }
120 |
121 | #sidebar h2:first-child {
122 | margin-top: 0;
123 | }
124 |
125 | #sidebar .list-unstyled li {
126 | margin-bottom: 0.5em;
127 | }
128 |
129 | .orcid {
130 | height: 16px;
131 | vertical-align: middle;
132 | }
133 |
134 | /* Reference index & topics ----------------------------------------------- */
135 |
136 | .ref-index th {font-weight: normal;}
137 |
138 | .ref-index td {vertical-align: top;}
139 | .ref-index .alias {width: 40%;}
140 | .ref-index .title {width: 60%;}
141 |
142 | .ref-index .alias {width: 40%;}
143 | .ref-index .title {width: 60%;}
144 |
145 | .ref-arguments th {text-align: right; padding-right: 10px;}
146 | .ref-arguments th, .ref-arguments td {vertical-align: top;}
147 | .ref-arguments .name {width: 20%;}
148 | .ref-arguments .desc {width: 80%;}
149 |
150 | /* Nice scrolling for wide elements --------------------------------------- */
151 |
152 | table {
153 | display: block;
154 | overflow: auto;
155 | }
156 |
157 | /* Syntax highlighting ---------------------------------------------------- */
158 |
159 | pre {
160 | word-wrap: normal;
161 | word-break: normal;
162 | border: 1px solid #eee;
163 | }
164 |
165 | pre, code {
166 | background-color: #f8f8f8;
167 | color: #333;
168 | }
169 |
170 | pre code {
171 | overflow: auto;
172 | word-wrap: normal;
173 | white-space: pre;
174 | }
175 |
176 | pre .img {
177 | margin: 5px 0;
178 | }
179 |
180 | pre .img img {
181 | background-color: #fff;
182 | display: block;
183 | height: auto;
184 | }
185 |
186 | code a, pre a {
187 | color: #375f84;
188 | }
189 |
190 | a.sourceLine:hover {
191 | text-decoration: none;
192 | }
193 |
194 | .fl {color: #1514b5;}
195 | .fu {color: #000000;} /* function */
196 | .ch,.st {color: #036a07;} /* string */
197 | .kw {color: #264D66;} /* keyword */
198 | .co {color: #888888;} /* comment */
199 |
200 | .message { color: black; font-weight: bolder;}
201 | .error { color: orange; font-weight: bolder;}
202 | .warning { color: #6A0366; font-weight: bolder;}
203 |
204 | /* Clipboard --------------------------*/
205 |
206 | .hasCopyButton {
207 | position: relative;
208 | }
209 |
210 | .btn-copy-ex {
211 | position: absolute;
212 | right: 0;
213 | top: 0;
214 | visibility: hidden;
215 | }
216 |
217 | .hasCopyButton:hover button.btn-copy-ex {
218 | visibility: visible;
219 | }
220 |
221 | /* mark.js ----------------------------*/
222 |
223 | mark {
224 | background-color: rgba(255, 255, 51, 0.5);
225 | border-bottom: 2px solid rgba(255, 153, 51, 0.3);
226 | padding: 1px;
227 | }
228 |
229 | /* vertical spacing after htmlwidgets */
230 | .html-widget {
231 | margin-bottom: 10px;
232 | }
233 |
--------------------------------------------------------------------------------
/docs/news/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Changelog • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
64 |
65 |
66 |
92 |
93 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
115 |
116 |
117 |
119 |
120 | Added a NEWS.md file to track changes to the package.
121 |
122 |
123 |
124 |
125 |
133 |
134 |
135 |
136 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/docs/reference/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Function reference • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
64 |
65 |
66 |
92 |
93 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | All functions
127 |
128 |
129 |
130 |
131 |
132 |
133 | buildTaipan()
134 |
135 | buildTaipan
136 |
137 |
138 |
139 |
140 |
141 |
147 |
148 |
149 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------
/R/build.R:
--------------------------------------------------------------------------------
1 | #' buildTaipan
2 | #'
3 | #' @param questions a taipan Questions list of scene and selection questions
4 | #' @param images a vector of image locations, can be local or URLs
5 | #' @param appdir location to export the completed app
6 | #' @param launch launch the app from the new directory after build is completed
7 | #' @param overwrite replace the contents of the supplied location with the completed app
8 | #' @param additionalHelp allow for contextual help on the survey as a modal dialog.
9 | #'
10 | #' @examples
11 | #' \dontrun{
12 | #' library(shiny)
13 | #' library(taipan)
14 | #'
15 | #' questions <- taipanQuestions(
16 | #' scene = div(radioButtons("graphic", label = ("2D Graphic"),
17 | #' choices = list("Live image", "2D Graphic")),
18 | #' radioButtons("bg", label = ("Background"),
19 | #' choices = list("Crowd",
20 | #' "Court", "Logo wall", "Not applicable")),
21 | #' radioButtons("person", label = ("Detectable Person"),
22 | #' choices = list("Yes", "No")),
23 | #' radioButtons("shotangle", label = ("Shot angle"),
24 | #' choices = list("Level with players",
25 | #' "Birds eye",
26 | #' "Upward angle")),
27 | #' radioButtons("situation", label = ("Situation"),
28 | #' choices = list("Court in play",
29 | #' "Court player close-up",
30 | #' "Court close-up not player",
31 | #' "Crowd",
32 | #' "Off court close up of player",
33 | #' "Transition"))),
34 | #' selection = div(radioButtons("detect", label = ("Detect Face"),
35 | #' choices = list("Player" ,
36 | #' "Other staff on court", "Fan", "None")),
37 | #' radioButtons("obscured", label = ("Face obscured"),
38 | #' choices = list("Yes", "No")),
39 | #' radioButtons("lighting", label = ("Lighting"),
40 | #' choices = list("Direct sunlight", "Shaded", "Partially shaded")),
41 | #' radioButtons("headangle", label = ("Head angle"),
42 | #' choices = list("Front on", "Back of head",
43 | #' "Profile", "Other")),
44 | #' radioButtons("glasses", label = ("Glasses"),
45 | #' choices = list("Yes", "No")),
46 | #' radioButtons("visorhat", label = ("Visor/hat"),
47 | #' choices = list("Yes", "No")))
48 | #' )
49 | #'
50 | #' additionalHelp <- paste(h4("Program Specific Help"), br(),
51 | #' p("This is some specific text, about something specific to your application"), br(),
52 | #' br(),
53 | #' "For more information on how to use this tool, contact either information-at-information.com or
54 | #' John.Smith-at-information.com")
55 | #'
56 | #'
57 | #' buildTaipan(
58 | #' questions = questions,
59 | #' "https://raw.githubusercontent.com/srkob1/taipan/master/sample_images/2016_CT6_R01_CGarcia_FRA_vs_BStrycova_CZE_WS145_clip.0015.png",
60 | #' file.path(tempdir(), "taipan")
61 | #' )
62 | #'
63 | #' }
64 | #'
65 | #' @importFrom shiny runApp
66 | #' @importFrom downloader download
67 | #'
68 | #' @export
69 |
70 | buildTaipan <- function(questions, images, appdir, launch = TRUE, overwrite = FALSE, additionalHelp = NULL){
71 | # images <- tools::file_path_as_absolute(images)
72 | if(!inherits(questions, "taipanQuestions")){
73 | stop("Questions must be created using the taipanQuestions() function.")
74 | }
75 |
76 | if(overwrite){
77 | message(paste0("Are you sure you want to overwrite '", appdir, "'? All files in this folder will be deleted!\nYes: Delete ALL of these files!\nNo: Keep it the way it is!"))
78 | auth <- readline()
79 | if(toupper(auth)!="YES"){
80 | message("Aborted building of taipan app.")
81 | return(invisible(NULL))
82 | }
83 | unlink(appdir, recursive = TRUE)
84 | }
85 | if(dir.exists(appdir)){
86 | if(length(list.files(appdir))>0){
87 | stop(sprintf('Output appdir "%s" already exists, please provide a different location to save app',
88 | appdir))
89 | }
90 | }
91 | else{
92 | dir.create(appdir)
93 | }
94 | appdir <- tools::file_path_as_absolute(appdir)
95 |
96 | if (is.null(additionalHelp)) {
97 | additionalHelp="There is no help specific for this project"
98 | }
99 |
100 |
101 |
102 | # WRITE APPDIR
103 | app_files <- list.files(file.path(system.file(package="taipan"), "app"))
104 | file.copy(file.path(system.file(package="taipan"), "app", app_files), appdir, recursive = TRUE)
105 |
106 | # SAVE QUESTIONS
107 | saveRDS(questions, file = file.path(appdir, "data", "questions.rds"))
108 |
109 | # SAVE HELP
110 | saveRDS(additionalHelp, file = file.path(appdir, "data", "additionalHelp.rds"))
111 |
112 | # CONSTRUCT IMAGE DIR
113 | if(dir.exists(images)){
114 | images <- list.files(images, full.names = TRUE)
115 | }
116 | img_success <- file.copy(images, file.path(appdir, "www", "app_images", basename(images)))
117 | if(any(!img_success)){
118 | download(images[!img_success], file.path(appdir, "www", "app_images", basename(images)), mode = "wb")
119 | }
120 |
121 | # LAUNCH APP
122 | if(launch){
123 | runApp(appdir)
124 | }
125 | }
126 |
127 |
--------------------------------------------------------------------------------
/docs/LICENSE.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | MIT License • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
64 |
65 |
66 |
92 |
93 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
114 |
115 |
116 |
117 |
Copyright (c) 2018 Stephanie Kobakian
118 |
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
119 |
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
120 |
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/docs/reference/reexports.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Objects exported from other packages — reexports • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
39 |
40 |
41 |
42 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
75 |
76 |
77 |
103 |
104 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
127 |
128 |
129 |
130 |
These objects are imported from other packages. Follow the links
131 | below to see their documentation.
132 |
133 | dplyr %>%
134 |
135 | readr read_csv , write_csv
136 |
137 | tidyr spread
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
151 |
152 |
153 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/docs/reference/sampleQuestions.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Nested list of a sample of Questions — sampleQuestions • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
68 |
69 |
70 |
96 |
97 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
120 |
121 |
122 |
123 |
A nested list containing two sets of questions and the information needed
124 | to create shiny objects for each question.
125 |
126 |
127 |
128 |
sampleQuestions
129 |
130 |
131 |
132 |
133 | scene: located in the top level list, contains a list of questions
134 | to be asked about the entire image.
135 | selection: located in the top level list, contains a list of
136 | questions regarding selected areas within an image.
137 | qType: A character string of the function name of the shiny question
138 | object to be produced.
139 | label: The question that will be displayed in the shiny app.
140 | choices: A character vector of options to be chosen.
141 | selected: An optional argument, when a particular answer should be a
142 | default selection.
143 |
144 |
145 |
146 |
147 |
155 |
156 |
157 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
--------------------------------------------------------------------------------
/docs/articles/taipan-vignette.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Taipan Vignette • taipan
9 |
10 |
11 |
12 |
13 |
14 |
15 |
19 |
20 |
21 |
22 |
80 |
81 |
91 |
92 |
93 |
94 |
The Taipan package creates simple shiny surveys. The web applications can be used locally or deployed and allow people to save survey results as tidy data that is ready to use for analysis.
95 |
The app was initially created to streamline the process of manually tagging images to create a training set. It allows users to provide information regarding entire images, and smaller regions within. It is a survey style tool, with questions being posed for each image and area identified.
96 |
97 |
98 | Installation
99 |
You can install the development version from Github using:
100 |
# install.packages("devtools")
101 | devtools:: install_github ("srkobakian/taipan" )
102 |
103 |
104 |
105 | Usage: coming soon…
106 |
107 |
108 |
109 |
119 |
120 |
121 |
122 |
123 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/docs/reference/tennisQuestions.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Nested list of all questions used to manually annotate Australian Open images — tennisQuestions • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
68 |
69 |
70 |
96 |
97 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
120 |
121 |
122 |
123 |
A nested list structure containing questions regarding the images
124 | provided by Tennis Australia of the Australian Open 2016:
125 |
126 |
127 |
128 |
tennisQuestions
129 |
130 |
131 |
132 |
133 | scene: A list of questions regarding the background, angle of the
134 | shot and the situation occuring.
135 | selection: A list of questions regarding the face captured. Whether
136 | it is completely visible, the angle of the face, how the face is lit, and
137 | the accessories being worn.
138 | qType: A character string of the function name of the shiny question
139 | object to be produced.
140 | label: The question that will be displayed in the shiny app.
141 | choices: A character vector of options to be chosen.
142 | selected: An option argument, when a particular answer should be a
143 | default selection.
144 |
145 |
146 |
147 |
148 |
156 |
157 |
158 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
--------------------------------------------------------------------------------
/docs/reference/tennisQuestionsSmall.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Nested list of some questions used to manually annotate Australian Open images — tennisQuestionsSmall • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
68 |
69 |
70 |
96 |
97 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
120 |
121 |
122 |
123 |
A nested list structure containing questions regarding the images
124 | provided by Tennis Australia of the Australian Open 2016:
125 |
126 |
127 |
128 |
tennisQuestionsSmall
129 |
130 |
131 |
132 |
133 | scene: A list of questions regarding the background, angle of the
134 | shot and the situation occuring.
135 | selection: A list of questions regarding the face captured. Whether
136 | it is completely visible, the angle of the face, how the face is lit, and
137 | the accessories being worn.
138 | qType: A character string of the function name of the shiny question
139 | object to be produced.
140 | label: The question that will be displayed in the shiny app.
141 | choices: A character vector of options to be chosen.
142 | selected: An option argument, when a particular answer should be a
143 | default selection.
144 |
145 |
146 |
147 |
148 |
156 |
157 |
158 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
--------------------------------------------------------------------------------
/docs/reference/taipan-package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | taipan: Taipan For R — taipan-package • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
71 |
72 |
73 |
99 |
100 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
123 |
124 |
125 |
126 |
Taipan is a tool for annotating images in preparation for analysis.
127 | It allows users to annotate images in an interactive environment.
128 | Users supply images, questions and the possible answers.
129 | When Images are displayed, survey takers can select the appropriate responses.
130 | The answers are stored in a tidy format for analysis.
131 |
132 |
133 |
134 |
135 |
See also
136 |
137 |
141 |
142 |
143 |
144 |
162 |
163 |
164 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Taipan For R • taipan
9 |
10 |
11 |
12 |
13 |
18 |
19 |
23 |
24 |
25 |
26 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
94 |
95 |
Taipan is a Tool for Annotating Images in Preparation for ANalysis.
96 |
The Taipan package creates simple shiny surveys. The web applications can be used locally or deployed and allow people to save survey results as tidy data that is ready to use for analysis.
97 |
The app was initially created to streamline the process of manually tagging images to create a training set. It allows users to provide information regarding entire images, and smaller regions within. It is a survey style tool, with questions being posed for each image and area identified.
98 |
99 |
100 | Installation
101 |
You can install the development version from Github using:
102 |
# install.packages("devtools")
103 | devtools:: install_github ("srkobakian/taipan" )
104 |
105 |
106 |
107 | Usage: coming soon…
108 |
109 |
110 |
111 |
112 |
144 |
145 |
146 |
147 |
148 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
--------------------------------------------------------------------------------
/docs/reference/launchTaipan.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Launch Taipan — launchTaipan • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
67 |
68 |
69 |
95 |
96 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
119 |
120 |
121 |
122 |
This launches the app
123 |
124 |
125 |
126 |
launchTaipan (questions = sampleQuestions , loadCache = FALSE ,
127 | images = list.files ("images" ))
128 |
129 |
Arguments
130 |
131 |
132 |
133 | questions
134 | A taipan structured list object containing the questions to be asked in the app, see the global environment object sampleQuestions.
135 |
136 |
137 | loadCache
138 | If a cache.Rda object is found in the working directory and loadCache = TRUE, data from previous use of the app will be made avaiable. if there is no object the app will proceed from the beinnning of the image set. The default for this is FALSE.
139 |
140 |
141 | images
142 | The list of images located within the image folder.
143 |
144 |
145 |
146 |
147 |
Examples
148 |
149 |
# NOT RUN {
150 | library (taipan )
151 | tennisQuestionsSmall <- list (scene = list (
152 |
153 | bg = list (qType = "radio" ,
154 | label = "What is the background?" ,
155 | choices = c ("Crowd" , "Court" , "Logo wall" , "Not applicable" )),
156 | shotangle = list (qType = "radio" ,
157 | label = "What angle was the image taken from?" ,
158 | choices = c ("Level with players" ,"Birds eye" , "Upward angle" )),
159 | situation = list (qType = "radio" ,
160 | label = "What is the siutation occurring?" ,
161 | choices = c ("Court in play" , "Court player close-up" ,"Court close-up not player" ,
162 | "Crowd" , "Off court close up of player" ,"Transition" ))),
163 |
164 | selection = list (detect = list (qType = "radio" ,
165 | label = "Who is the person selected?" ,
166 | choices = c ("Player" ,"Other staff on court" , "Fan" )),
167 | glasses = list (qType = "radio" ,
168 | label = "Is the person wearing glasses?" ,
169 | choices = c ("No" , "Yes" )),
170 | visorhat = list (qType = "radio" ,
171 | label = "Is the person wearing a visor or hat?" ,
172 | choices = c ("No" , "Yes" ))))
173 |
174 |
175 | launchTaipan (tennisQuestionsSmall )
176 | # }
177 |
178 |
179 |
188 |
189 |
190 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
--------------------------------------------------------------------------------
/docs/docsearch.css:
--------------------------------------------------------------------------------
1 | /* Docsearch -------------------------------------------------------------- */
2 | /*
3 | Source: https://github.com/algolia/docsearch/
4 | License: MIT
5 | */
6 |
7 | .algolia-autocomplete {
8 | display: block;
9 | -webkit-box-flex: 1;
10 | -ms-flex: 1;
11 | flex: 1
12 | }
13 |
14 | .algolia-autocomplete .ds-dropdown-menu {
15 | width: 100%;
16 | min-width: none;
17 | max-width: none;
18 | padding: .75rem 0;
19 | background-color: #fff;
20 | background-clip: padding-box;
21 | border: 1px solid rgba(0, 0, 0, .1);
22 | box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175);
23 | }
24 |
25 | @media (min-width:768px) {
26 | .algolia-autocomplete .ds-dropdown-menu {
27 | width: 175%
28 | }
29 | }
30 |
31 | .algolia-autocomplete .ds-dropdown-menu::before {
32 | display: none
33 | }
34 |
35 | .algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] {
36 | padding: 0;
37 | background-color: rgb(255,255,255);
38 | border: 0;
39 | max-height: 80vh;
40 | }
41 |
42 | .algolia-autocomplete .ds-dropdown-menu .ds-suggestions {
43 | margin-top: 0
44 | }
45 |
46 | .algolia-autocomplete .algolia-docsearch-suggestion {
47 | padding: 0;
48 | overflow: visible
49 | }
50 |
51 | .algolia-autocomplete .algolia-docsearch-suggestion--category-header {
52 | padding: .125rem 1rem;
53 | margin-top: 0;
54 | font-size: 1.3em;
55 | font-weight: 500;
56 | color: #00008B;
57 | border-bottom: 0
58 | }
59 |
60 | .algolia-autocomplete .algolia-docsearch-suggestion--wrapper {
61 | float: none;
62 | padding-top: 0
63 | }
64 |
65 | .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column {
66 | float: none;
67 | width: auto;
68 | padding: 0;
69 | text-align: left
70 | }
71 |
72 | .algolia-autocomplete .algolia-docsearch-suggestion--content {
73 | float: none;
74 | width: auto;
75 | padding: 0
76 | }
77 |
78 | .algolia-autocomplete .algolia-docsearch-suggestion--content::before {
79 | display: none
80 | }
81 |
82 | .algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header {
83 | padding-top: .75rem;
84 | margin-top: .75rem;
85 | border-top: 1px solid rgba(0, 0, 0, .1)
86 | }
87 |
88 | .algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column {
89 | display: block;
90 | padding: .1rem 1rem;
91 | margin-bottom: 0.1;
92 | font-size: 1.0em;
93 | font-weight: 400
94 | /* display: none */
95 | }
96 |
97 | .algolia-autocomplete .algolia-docsearch-suggestion--title {
98 | display: block;
99 | padding: .25rem 1rem;
100 | margin-bottom: 0;
101 | font-size: 0.9em;
102 | font-weight: 400
103 | }
104 |
105 | .algolia-autocomplete .algolia-docsearch-suggestion--text {
106 | padding: 0 1rem .5rem;
107 | margin-top: -.25rem;
108 | font-size: 0.8em;
109 | font-weight: 400;
110 | line-height: 1.25
111 | }
112 |
113 | .algolia-autocomplete .algolia-docsearch-footer {
114 | width: 110px;
115 | height: 20px;
116 | z-index: 3;
117 | margin-top: 10.66667px;
118 | float: right;
119 | font-size: 0;
120 | line-height: 0;
121 | }
122 |
123 | .algolia-autocomplete .algolia-docsearch-footer--logo {
124 | background-image: url("data:image/svg+xml;utf8, ");
125 | background-repeat: no-repeat;
126 | background-position: 50%;
127 | background-size: 100%;
128 | overflow: hidden;
129 | text-indent: -9000px;
130 | width: 100%;
131 | height: 100%;
132 | display: block;
133 | transform: translate(-8px);
134 | }
135 |
136 | .algolia-autocomplete .algolia-docsearch-suggestion--highlight {
137 | color: #FF8C00;
138 | background: rgba(232, 189, 54, 0.1)
139 | }
140 |
141 |
142 | .algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight {
143 | box-shadow: inset 0 -2px 0 0 rgba(105, 105, 105, .5)
144 | }
145 |
146 | .algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content {
147 | background-color: rgba(192, 192, 192, .15)
148 | }
149 |
--------------------------------------------------------------------------------
/inst/app/server.R:
--------------------------------------------------------------------------------
1 | library(shiny)
2 | library(ggplot2)
3 | library(purrr)
4 |
5 | getInputID <- function(input){
6 | if(!inherits(input, "shiny.tag")){
7 | return()
8 | }
9 | c(
10 | if(!is.null(input$attribs$id)){list(list(id=input$attribs$id, type = input$name))}else{NULL},
11 | do.call("c", map(input$children, getInputID))
12 | )
13 | }
14 |
15 | shinyServer(
16 | function(input, output, session) {
17 | questions <- readRDS("data/questions.rds")
18 | additionalHelp <- readRDS("data/additionalHelp.rds")
19 |
20 | image_list <- list.files("www/app_images", full.names = TRUE)
21 |
22 | v <- reactiveValues(
23 | imageNum = 1,
24 | current_sel = NULL,
25 | editing = F,
26 | responses = list()
27 | )
28 |
29 | current_img <- reactive({
30 | image_list[v$imageNum]
31 | })
32 | current_sel <- reactive({
33 | v$current_sel
34 | })
35 | current_area <- reactive({
36 | if(!is.null(input$img_brush)){
37 | input$img_brush[c("xmin", "xmax", "ymin", "ymax")]
38 | }
39 | else if(!is.null(current_sel())){
40 | sel_val <- v$responses[[basename(current_img())]][["selection"]][[current_sel()]]
41 | list(
42 | xmin = sel_val$pos$xmin,
43 | xmax = sel_val$pos$xmax,
44 | ymin = sel_val$pos$ymin,
45 | ymax = sel_val$pos$ymax
46 | )
47 | }
48 | else{
49 | NULL
50 | }
51 | })
52 |
53 | output$out_img_overlay <- renderImage({
54 | session$sendCustomMessage("get_dim","taipan_current_img")
55 | if(is.null(input$taipan_img_dim)){
56 | out_width <- 100
57 | out_height <- 100
58 | xlim <- NULL
59 | ylim <- NULL
60 | }
61 | else{
62 | out_width <- input$taipan_img_dim[1]
63 | out_height <- input$taipan_img_dim[2]
64 | xlim <- c(0, out_width)
65 | ylim <- c(-out_height, 0)
66 | }
67 | selection_data <- do.call("rbind",
68 | c(list(data.frame(xmin=numeric(), xmax=numeric(), ymin=numeric(), ymax=numeric())),
69 | map(v$responses[[basename(current_img())]][["selection"]],
70 | function(x) as.data.frame(x$pos))
71 | )
72 | )
73 | selection_data <- transform(selection_data, current = seq_len(NROW(selection_data)) %in% current_sel())
74 | p <- ggplot(selection_data, aes(xmin=xmin, xmax=xmax, ymin=-ymax, ymax=-ymin, colour = current)) +
75 | scale_x_continuous(limits = xlim, expand=c(0,0)) +
76 | scale_y_continuous(limits = ylim, expand=c(0,0)) +
77 | geom_rect(fill="transparent") +
78 | theme_void()+
79 | theme(
80 | panel.background = element_rect(fill = "transparent") # bg of the panel
81 | , plot.background = element_rect(fill = "transparent", colour = NA) # bg of the plot
82 | , legend.background = element_rect(fill = "transparent") # get rid of legend bg
83 | , legend.box.background = element_rect(fill = "transparent") # get rid of legend panel bg
84 | ) +
85 | guides(colour = "none")
86 | ggsave(overlay_img <- tempfile(), p, png, width = out_width,
87 | height = out_height, limitsize = FALSE, bg = "transparent")
88 | list(src = overlay_img)
89 | })
90 |
91 | output$out_img <- renderImage({
92 | list(src = current_img(), id = "taipan_current_img")
93 | }, deleteFile = FALSE)
94 |
95 | output$out_img_info <- renderText({
96 | sprintf("Image: %s (%i/%i)",
97 | basename(current_img()),
98 | v$imageNum,
99 | length(image_list))
100 | })
101 |
102 | sceneInputs <- getInputID(questions$scene)
103 | selectionInputs <- getInputID(questions$selection)
104 |
105 | scene_vals <- reactive({
106 | vals <- map(sceneInputs, function(id){input[[id$id]]})
107 | names(vals) <- map_chr(sceneInputs, "id")
108 | vals
109 | })
110 |
111 | selection_vals <- reactive({
112 | vals <- map(selectionInputs, function(id){input[[id$id]]})
113 | names(vals) <- map_chr(selectionInputs, "id")
114 | vals
115 | })
116 |
117 | output$ui_instructions <- renderUI({
118 | box(
119 | title = "Instructions",
120 | h4("Welcome to your survey."), br(),
121 | p("The", strong("Scene"),
122 | "section asks questions regarding the whole image, and will be saved when you continue to the next image.", "To answer questions about the current image,
123 | respond to the questions below."), br(),
124 | br(),
125 | "Next step is to select an area. Hold down on the image to create a cornerof the selected area,
126 | drag the crosshairs vertically and horizontally to create a rectangle around your area of interest.", br(),
127 | p("The", strong("Selection"), "questions now appear.
128 | These questions relate only to the location you have currently selected."), br(),
129 | p("Save these answers by clicking the", strong("Save Selection"), "button,
130 | when you have completed the answers for this area."), br(),
131 | "Repeat for all areas of interest.", br(),
132 | "It is possible to view or edit the answers provided by double clicking within the area.",
133 | status = "warning",
134 | solidHeader = TRUE,
135 | collapsible = TRUE,
136 | collapsed = TRUE,
137 | width = 12
138 | )
139 | })
140 |
141 | output$ui_questions <- renderUI({
142 | if(!is.null(current_sel())){
143 | box(
144 | title = "Selection",
145 | questions$selection,
146 | width = 12,
147 | status = "primary",
148 | collapsible = TRUE
149 | )
150 | }
151 | else{
152 | box(
153 | title = "Scene",
154 | questions$scene,
155 | width = 12,
156 | status = "primary",
157 | collapsible = TRUE
158 | )
159 | }
160 | })
161 |
162 | output$ui_saveSelection <- renderUI({
163 | if(!is.null(current_sel())){
164 | actionLink(
165 | "btn_saveSelection",
166 | box(
167 | "Save Selection",
168 | width = 3,
169 | background = "blue", offset=1
170 | )
171 | )
172 | } else {
173 | column(3)
174 | }
175 | })
176 |
177 |
178 | observeEvent(v$editing, {
179 | output$ui_deleteSelection <- renderUI({
180 | if(!is.null(current_sel()) & v$editing){
181 | actionLink(
182 | "btn_deleteSelection",
183 | box(
184 | "Delete Selection",
185 | width = 3,
186 | background = "red", offset=1
187 | )
188 | )
189 | } else {
190 | column(3)
191 | }
192 | })})
193 |
194 | observeEvent(input$img_brush, {
195 | if(is.null(input$img_brush)){
196 | v$current_sel <- NULL
197 | }
198 | else{
199 | v$current_sel <- length(v$responses[[basename(current_img())]][["selection"]]) + 1
200 | }
201 | })
202 |
203 | # Additional test for removing brush
204 | observeEvent(input$img_click, {
205 | if(is.null(input$img_brush)){
206 | v$current_sel <- NULL
207 | }
208 | })
209 |
210 | observeEvent(input$img_dblclick, {
211 | xpos <- input$img_dblclick$x
212 | ypos <- input$img_dblclick$y
213 | match <- map_lgl(v$responses[[basename(current_img())]][["selection"]],
214 | function(sel){
215 | (xpos >= sel$pos$xmin) &&
216 | (xpos <= sel$pos$xmax) &&
217 | (ypos >= sel$pos$ymin) &&
218 | (ypos <= sel$pos$ymax)
219 | }
220 | )
221 | sel_match <- which(match)
222 | if(length(sel_match) == 1){
223 | v$current_sel <- sel_match
224 | v$editing <- T
225 |
226 | # Update selection inputs
227 | map(selectionInputs,
228 | function(io){
229 | val <- v$responses[[basename(current_img())]][["selection"]][[sel_match]][["inputs"]][[io$id]]
230 | session$sendInputMessage(
231 | io$id,
232 | list(
233 | value = val,
234 | selected = val
235 | )
236 | )
237 | }
238 | )
239 | }
240 | else{
241 | showNotification(h3("Could not find matching selection, please select a unique area of a square."),
242 | type = "error")
243 | }
244 | })
245 |
246 | # Update the scene values when images change
247 | observeEvent(current_img(), {
248 | map(sceneInputs,
249 | function(io){
250 | # Update scene inputs
251 | val <- v$responses[[basename(current_img())]][["scene"]][[io$id]]
252 | if(!is.null(val)){
253 | session$sendInputMessage(
254 | io$id,
255 | list(
256 | value = val,
257 | selected = val
258 | )
259 | )
260 | }
261 | else{
262 | # Trigger re-build of UI
263 | v$current_sel <- 1
264 | v$current_sel <- NULL
265 | }
266 | }
267 | )
268 | })
269 |
270 | observeEvent(scene_vals(), {
271 | v$responses[[basename(current_img())]][["scene"]] <- scene_vals()
272 | })
273 |
274 | observeEvent(input$btn_prev, {
275 | v$responses[[basename(current_img())]][["scene"]] <- scene_vals()
276 | session$resetBrush("img_brush")
277 | v$current_sel <- NULL
278 | v$imageNum <- pmax(1, v$imageNum - 1)
279 | })
280 |
281 | observeEvent(input$btn_next, {
282 | v$responses[[basename(current_img())]][["scene"]] <- scene_vals()
283 | session$resetBrush("img_brush")
284 | v$current_sel <- NULL
285 | v$imageNum <- pmin(length(image_list), v$imageNum + 1)
286 | v$editing <- F
287 | out <<- suppressWarnings( # hide coercion warnings
288 | v$responses %>%
289 | imap_dfr(
290 | function(img, image_name){
291 | scene_vals <- img$scene %>%
292 | map(paste0, collapse = ", ")
293 | selection_vals <- img$selection %>%
294 | map_dfr(function(sel_val){
295 | c(sel_val$pos,
296 | sel_val$inputs %>%
297 | map(paste0, collapse = ", ")
298 | ) %>%
299 | as.data.frame
300 | })
301 | as.data.frame(c(image_name = image_name, scene_vals, selection_vals))
302 | }
303 | )
304 | )
305 | })
306 |
307 | observeEvent(input$btn_saveSelection, {
308 | v$responses[[basename(current_img())]][["selection"]][[current_sel()]] <-
309 | list(pos = current_area(),
310 | inputs = selection_vals()
311 | )
312 | session$resetBrush("img_brush")
313 | v$current_sel <- NULL
314 | v$editing <- F
315 | })
316 |
317 | observeEvent(input$btn_deleteSelection, {
318 | v$responses[[basename(current_img())]][["selection"]][[current_sel()]] <- NULL
319 | v$current_sel <- NULL
320 | v$editing <- F
321 | })
322 |
323 | output$btn_export <- downloadHandler(
324 | filename = function() {
325 | paste('taipan-export-', Sys.Date(), '.csv', sep='')
326 | },
327 | content = function(con){
328 | v$responses[[basename(current_img())]][["scene"]] <- scene_vals()
329 | out <- suppressWarnings( # hide coercion warnings
330 | v$responses %>%
331 | imap_dfr(
332 | function(img, image_name){
333 | scene_vals <- img$scene %>%
334 | map(paste0, collapse = ", ")
335 | selection_vals <- img$selection %>%
336 | map_dfr(function(sel_val){
337 | c(sel_val$pos,
338 | sel_val$inputs %>%
339 | map(paste0, collapse = ", ")
340 | ) %>%
341 | as.data.frame
342 | })
343 | as.data.frame(c(image_name = image_name, scene_vals, selection_vals))
344 | }
345 | )
346 | )
347 | write.csv(out, con, row.names = FALSE)
348 | }
349 | )
350 |
351 | observeEvent(input$SpecHelp, {
352 | showModal(modalDialog(additionalHelp,icon=icon("question-circle")))
353 | })
354 | }
355 | )
356 |
--------------------------------------------------------------------------------
/docs/reference/buildTaipan.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | buildTaipan — buildTaipan • taipan
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
67 |
68 |
69 |
95 |
96 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
119 |
120 |
121 |
122 |
buildTaipan
123 |
124 |
125 |
126 |
buildTaipan (questions , images , appdir , launch = TRUE , overwrite = FALSE )
127 |
128 |
Arguments
129 |
130 |
131 |
132 | questions
133 | a taipan Questions list of scene and selection questions
134 |
135 |
136 | images
137 | a vector of image locations, can be local or URLs
138 |
139 |
140 | appdir
141 | location to export the completed app
142 |
143 |
144 | launch
145 | launch the app from the new directory after build is completed
146 |
147 |
148 | overwrite
149 | replace the contents of the supplied location with the completed app
150 |
151 |
152 |
153 |
154 |
Examples
155 |
# NOT RUN {
156 | library (shiny )
157 | library (taipan )
158 |
159 | questions <- taipanQuestions (
160 | scene = div (radioButtons ("graphic" , label = ("2D Graphic" ),
161 | choices = list ("Live image" , "2D Graphic" )),
162 | radioButtons ("bg" , label = ("Background" ),
163 | choices = list ("Crowd" ,
164 | "Court" , "Logo wall" , "Not applicable" )),
165 | radioButtons ("person" , label = ("Detectable Person" ),
166 | choices = list ("Yes" , "No" )),
167 | radioButtons ("shotangle" , label = ("Shot angle" ),
168 | choices = list ("Level with players" ,
169 | "Birds eye" ,
170 | "Upward angle" )),
171 | radioButtons ("situation" , label = ("Situation" ),
172 | choices = list ("Court in play" ,
173 | "Court player close-up" ,
174 | "Court close-up not player" ,
175 | "Crowd" ,
176 | "Off court close up of player" ,
177 | "Transition" ))),
178 | selection = div (radioButtons ("detect" , label = ("Detect Face" ),
179 | choices = list ("Player" ,
180 | "Other staff on court" , "Fan" , "None" )),
181 | radioButtons ("obscured" , label = ("Face obscured" ),
182 | choices = list ("Yes" , "No" )),
183 | radioButtons ("lighting" , label = ("Lighting" ),
184 | choices = list ("Direct sunlight" , "Shaded" , "Partially shaded" )),
185 | radioButtons ("headangle" , label = ("Head angle" ),
186 | choices = list ("Front on" , "Back of head" ,
187 | "Profile" , "Other" )),
188 | radioButtons ("glasses" , label = ("Glasses" ),
189 | choices = list ("Yes" , "No" )),
190 | radioButtons ("visorhat" , label = ("Visor/hat" ),
191 | choices = list ("Yes" , "No" )))
192 | )
193 |
194 | buildTaipan (
195 | questions = questions ,
196 | "https://raw.githubusercontent.com/srkob1/taipan/master/sample_images/2016_CT6_R01_CGarcia_FRA_vs_BStrycova_CZE_WS145_clip.0015.png" ,
197 | file.path (tempdir (), "taipan" )
198 | )
199 |
200 | # }
201 |
202 |
203 |
212 |
213 |
214 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
--------------------------------------------------------------------------------