File: utilities.R

package info (click to toggle)
r-cran-threejs 0.3.3%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 2,884 kB
  • sloc: javascript: 28,121; sh: 17; makefile: 12
file content (132 lines) | stat: -rw-r--r-- 4,325 bytes parent folder | download
1
2
3
4
5
6
7
8
9
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#' Convert an image file or uri to a three.js texture
#'
#' Convert file image representations in R into JSON-formatted arrays
#' suitable for use as three.js textures. This function is automatically
#' invoked for images used in the \code{globejs} function.
#'
#' @param data A character string file name referring to an image file,
#' or referring to an image uri (see the examples).
#'
#' @return JSON-formatted list with image, width, and height fields
#' suitable for use as a three.js
#' texture created with the base64texture function. The image field
#' contains a base64 dataURI encoding of the image.
#'
#' @note
#' Due to browser
#' "same origin policy" security restrictions, loading textures
#' from a file system in three.js may lead to a security exception,
#' see
#' \url{https://github.com/mrdoob/three.js/wiki/How-to-run-things-locally}.
#' References to file locations work in Shiny apps, but not in stand-alone
#' examples. The \code{texture} function facilitates transfer of image
#' texture data from R into three.js textures. Binary image data are
#' encoded and inserted into three.js without using files as dataURIs.
#'
#' @references
#' The threejs project \url{http://threejs.org}.
#' \url{https://github.com/mrdoob/three.js/wiki/How-to-run-things-locally}.
#'
#' @examples
#' \dontrun{
#' # A big image (may take a while to download):
#' img <- paste("http://eoimages.gsfc.nasa.gov/",
#'              "images/imagerecords/73000/73909/",
#'              "world.topo.bathy.200412.3x5400x2700.jpg", sep="")
#' t <- texture(img)
#' }
#'
#' @importFrom base64enc dataURI
#' @export
texture <- function(data)
{
  ext <- gsub(".*\\.", "", data)
  if (grepl("^http", data))
  {
    u <- url(data, open="rb")
    data <- tempfile()
    on.exit(unlink(data))
    writeBin(readBin(u, what="raw", n=10e6), data, useBytes=TRUE)
    close(u)
  }
# Encode the file as a dataURI
  if (nchar(ext) < 1) ext <- "png"
  img <- dataURI(file=data, mime=sprintf("image/%s", ext))
  list(img=img, dataURI=TRUE)
}

# internal non-braindead if-else
ifel <- function(a, b, c)
{
  if (isTRUE(a)) return(b)
  c
}

# parse graph options from a list
# @param g
# @return list
# internal function
gopts <- function(g)
{
  color <- NULL
  lcol <- NULL
  from <- g$from
  to <- g$to
  alpha <- NULL
  if (inherits(g[[1]], "igraph"))
  {
    from <- as_edgelist(g[[1]])
    to   <- from[, 2] - 1
    from <- from[, 1] - 1
    layout <- g[[1]]$layout
    color <- gcol(V(g[[1]])$color)
    alpha <- color$alpha
    color <- color$color
    lcol <- gcol(E(g[[1]])$color)$color
  }
  if ("layout" %in% names(g)) layout <- g$layout
  if ("vertex.color" %in% names(g))
  {
    color <- gcol(g$vertex.color)
    alpha <- color$alpha
    color <- color$color
  }
  if ("edge.color" %in% names(g)) lcol <- gcol(g$edge.color)$color
  ans <- list(layout=layout, from=from, to=to, color=color, lcol=lcol, alpha=alpha, cumulative=g$cumulative)
  if (!is.null(ans$cumulative) && !ans$cumulative) ans$cumulative <- NULL
  ans <- ans[!vapply(ans, is.null, TRUE)]
  if (!("layout" %in% names(ans))) stop("missing layout")
  # re-order y, z, flip y, convert to vector (centering handled by JavaScript)
  ans$layout <- ans$layout[, c(1, 3, 2), drop=FALSE]
  ans$layout[, 3] <- 1 - ans$layout[, 3]
  ans$layout <- signif(as.vector(t(ans$layout)), 8)
  ans
}

#' A basic internal color format parser
#' @param x a character-valued color name
#' @return a list of 3-hex-digit color values and scalar numeric alpha values
#' @importFrom grDevices col2rgb rgb
gcol <- function(x)
{
  if (is.null(x)) return(list(color=NULL, alpha=NULL))
  c <- col2rgb(x, alpha=TRUE)
  a <- as.vector(c[4, ] / 255)   # alpha values
  list(color = apply(c, 2, function(x) rgb(x[1], x[2], x[3], maxColorValue=255)), alpha = a)
}

# internal function used in scatterplot3js
indexline <- function(x) # zero index and make sure each element is an array in JavaScript
{
  a <- as.integer(x) - 1L
  if (length(a) == 1) a <- list(a)
  a
}

# internal function to convert x to a JSON dataURI, where x is either character or raw
# JSON text or a connection or a non-compressed file.
jsuri <- function(x)
{
  if(is.character(x) && file.exists(x)) return(dataURI(file=x, encoding=NULL, mime="application/javascript"))
  dataURI(data=x, encoding=NULL, mime="application/javascript")
}