3838# ' @export
3939
4040gf_girafe <- function (ggobj , code , ... ) {
41+
4142 if (missing(code )) {
4243 return (ggiraph :: girafe(ggobj = ggobj , ... ))
4344 }
@@ -212,3 +213,201 @@ gf_labeller_interactive <- function(..., .mapping) {
212213
213214 ggiraph :: labeller_interactive(.mapping = .mapping , !!! qdots )
214215}
216+
217+ # ##############################################################################
218+ # #
219+ # # modified version of function in ggiraph, branching based on whether position
220+ # # is specified.
221+
222+ layer_interactive <- function (
223+ layer_func , stat = NULL , position = NULL , ... ,
224+ interactive_geom = NULL , extra_interactive_params = NULL ) {
225+
226+ dots <- list (... )
227+ if (is.null(position )) {
228+ ggiraph_layer_interactive(
229+ layer_func , stat = stat , ... ,
230+ interactive_geom = interactive_geom , extra_interactive_params = extra_interactive_params
231+ )
232+ } else {
233+ ggiraph_layer_interactive(
234+ layer_func , stat = stat , position = position , ... ,
235+ interactive_geom = interactive_geom , extra_interactive_params = extra_interactive_params
236+ )
237+ }
238+ }
239+
240+
241+ # #########################################################################
242+ # # Functions copied from ggiraph because they are not (yet) exported there.
243+
244+ ggiraph_layer_interactive <-
245+ function (layer_func , ... , interactive_geom = NULL , extra_interactive_params = NULL )
246+ {
247+ args <- rlang :: list2(... )
248+ interactive_mapping <- NULL
249+ interactive_params <- NULL
250+ index <- purrr :: detect_index(args , function (x ) {
251+ inherits(x , " uneval" )
252+ })
253+ ipar <- ggiraph_get_default_ipar(extra_interactive_params )
254+ if (index > 0 && ggiraph_has_interactive_attrs(args [[index ]], ipar = ipar )) {
255+ interactive_mapping <- ggiraph_get_interactive_attrs(args [[index ]],
256+ ipar = ipar )
257+ args [[index ]] <- ggiraph_remove_interactive_attrs(args [[index ]],
258+ ipar = ipar )
259+ }
260+ if (ggiraph_has_interactive_attrs(args , ipar = ipar )) {
261+ interactive_params <- ggiraph_get_interactive_attrs(args , ipar = ipar )
262+ args <- ggiraph_remove_interactive_attrs(args , ipar = ipar )
263+ }
264+ result <- do.call(layer_func , args )
265+ layer_ <- NULL
266+ if (is.list(result )) {
267+ index <- purrr :: detect_index(result , function (x ) {
268+ inherits(x , " LayerInstance" )
269+ })
270+ if (index > 0 ) {
271+ layer_ <- result [[index ]]
272+ }
273+ }
274+ else if (inherits(result , " LayerInstance" )) {
275+ layer_ <- result
276+ }
277+ if (! is.null(layer_ )) {
278+ if (is.null(interactive_geom )) {
279+ interactive_geom <- ggiraph_find_interactive_class(layer_ $ geom )
280+ }
281+ layer_ $ geom <- interactive_geom
282+ if (! is.null(interactive_mapping )) {
283+ layer_ $ mapping <- ggiraph_append_aes(layer_ $ mapping , interactive_mapping )
284+ }
285+ if (! is.null(interactive_params )) {
286+ layer_ $ aes_params <- append(layer_ $ aes_params , interactive_params )
287+ }
288+ layer_ $ geom_params <- append(layer_ $ geom_params , list (.ipar = ipar ))
289+ default_aes_names <- names(layer_ $ geom $ default_aes )
290+ missing_names <- setdiff(ipar , default_aes_names )
291+ if (length(missing_names ) > 0 ) {
292+ defaults <- Map(missing_names , f = function (x ) NULL )
293+ layer_ $ geom $ default_aes <- ggiraph_append_aes(layer_ $ geom $ default_aes ,
294+ defaults )
295+ }
296+ if (is.list(result )) {
297+ result [[index ]] <- layer_
298+ }
299+ else {
300+ result <- layer_
301+ }
302+ }
303+ result
304+ }
305+
306+ ggiraph_get_ineteractive_attrs <-
307+ function (x = rlang :: caller_env(), ipar = ggiraph_IPAR_NAMES )
308+ {
309+ if (is.environment(x )) {
310+ rlang :: env_get_list(env = x , ipar , NULL )
311+ }
312+ else {
313+ if (! is.null(attr(x , " interactive" ))) {
314+ x <- attr(x , " interactive" )
315+ }
316+ x [ggiraph_get_interactive_attr_names(x , ipar = ipar )]
317+ }
318+ }
319+
320+ ggiraph_get_default_ipar <-
321+ function (extra_names = NULL )
322+ {
323+ if (is.character(extra_names ) && length(extra_names ) > 0 ) {
324+ extra_names <- Filter(x = extra_names , function (x ) {
325+ ! is.na(x ) && nzchar(trimws(x ))
326+ })
327+ }
328+ unique(c(ggiraph_IPAR_NAMES , extra_names ))
329+ }
330+
331+ ggiraph_get_interactive_attrs <-
332+ function (x = rlang :: caller_env(), ipar = ggiraph_IPAR_NAMES )
333+ {
334+ if (is.environment(x )) {
335+ rlang :: env_get_list(env = x , ipar , NULL )
336+ }
337+ else {
338+ if (! is.null(attr(x , " interactive" ))) {
339+ x <- attr(x , " interactive" )
340+ }
341+ x [ggiraph_get_interactive_attr_names(x , ipar = ipar )]
342+ }
343+ }
344+
345+ ggiraph_get_interactive_attr_names <-
346+ function (x , ipar = ggiraph_IPAR_NAMES )
347+ {
348+ intersect(names(x ), ipar )
349+ }
350+
351+ ggiraph_remove_interactive_attrs <-
352+ function (x , ipar = ggiraph_IPAR_NAMES )
353+ {
354+ for (a in ipar ) {
355+ x [[a ]] <- NULL
356+ }
357+ x
358+ }
359+
360+ ggiraph_find_interactive_class <-
361+ function (gg , baseclass = c(" Geom" , " Guide" ), env = parent.frame())
362+ {
363+ baseclass <- rlang :: arg_match(baseclass )
364+ if (inherits(gg , baseclass )) {
365+ name <- class(gg )[1 ]
366+ }
367+ else if (is.character(gg ) && length(gg ) == 1 ) {
368+ name <- gg
369+ if (name == " histogram" ) {
370+ name <- " bar"
371+ }
372+ }
373+ else {
374+ rlang :: abort(paste0(" `gg` must be either a string or a " , baseclass ,
375+ " * object, not " , obj_desc(gg )), call = NULL )
376+ }
377+ if (! startsWith(name , baseclass )) {
378+ name <- paste0(baseclass , camelize(name , first = TRUE ))
379+ }
380+ baseinteractive <- paste0(baseclass , " Interactive" )
381+ if (! startsWith(name , baseinteractive )) {
382+ name <- sub(baseclass , baseinteractive , name )
383+ }
384+ obj <- find_global(name , env = env )
385+ if (is.null(obj ) || ! inherits(obj , baseclass )) {
386+ rlang :: abort(paste0(" Can't find interactive " , baseclass , " function based on " ,
387+ as_label(gg )), call = NULL )
388+ }
389+ else {
390+ obj
391+ }
392+ }
393+
394+ ggiraph_has_interactive_attrs <-
395+ function (x , ipar = ggiraph_IPAR_NAMES )
396+ {
397+ length(intersect(names(x ), ipar )) > 0
398+ }
399+
400+ ggiraph_append_aes <-
401+ function (mapping , lst )
402+ {
403+ mapping [names(lst )] <- lst
404+ mapping
405+ }
406+
407+ ggiraph_IPAR_NAMES <-
408+ c(
409+ " data_id" , " tooltip" , " onclick" , " hover_css" , " selected_css" ,
410+ " tooltip_fill" , " hover_nearest" )
411+
412+
413+ # ##############################################################################
0 commit comments