acontext("interactivity") library(animint2) ## Example: 2 plots, 2 selectors, but only interacting with 1 plot. data(breakpoints, package = "animint2") only.error <- subset(breakpoints$error,type=="E") only.segments <- subset(only.error, samples==samples[1]) signal.colors <- c(estimate="#0adb0a", latent="#0098ef") breakpointError <- list( signal=ggplot()+ geom_point(aes(position, signal), showSelected="samples", data=breakpoints$signals)+ geom_line(aes(position, signal), colour=signal.colors[["latent"]], data=breakpoints$imprecision)+ geom_segment(aes(first.base, mean, xend=last.base, yend=mean), showSelected=c("segments", "samples"), colour=signal.colors[["estimate"]], data=breakpoints$segments)+ geom_vline(aes(xintercept=base), showSelected=c("segments", "samples"), colour=signal.colors[["estimate"]], linetype="dashed", data=breakpoints$breaks), points=ggplot()+ geom_point(aes(samples, error, id=paste0("samples", samples)), showSelected="segments", clickSelects="samples", data=only.error, stat="identity"), error=ggplot()+ geom_vline(aes(xintercept=segments, id=paste0("segments", segments)), clickSelects="segments", data=only.segments, lwd=17, alpha=1/2)+ geom_line(aes(segments, error, group=samples), clickSelects="samples", data=only.error, lwd=4), first=list(samples=150, segments=4), title="breakpointError (select one model size)") info <- animint2HTML(breakpointError) ##remDr$screenshot(file="~/R/animint/phantom-bug-screenshot.png") dasharrayPattern <- paste0("stroke-dasharray:", "(?.*?)", ";") get.dasharray <- function(node.set){ expect_true(length(node.set) > 0) style.list <- list() for(node.i in seq_along(node.set)){ node <- node.set[[node.i]] a.vec <- xmlAttrs(node) style.list[[node.i]] <- a.vec[["style"]] } style.vec <- do.call(c, style.list) str_match_perl(style.vec, dasharrayPattern) } dashed.xpaths <- c('//g[@class="geom4_vline_signal"]//g[@class="PANEL1"]//line') solid.xpaths <- c('//g[@class="geom2_line_signal"]//g[@class="PANEL1"]//path', '//g[@class="geom3_segment_signal"]//g[@class="PANEL1"]//line', '//g[@class="geom6_vline_error"]//g[@class="PANEL1"]//line', '//g[@class="geom7_line_error"]//g[@class="PANEL1"]//path') test_that("stroke-dasharray: 8,8 for dashed", { for(xpath in dashed.xpaths){ node.set <- getNodeSet(info$html, xpath) dash.mat <- get.dasharray(node.set) expect_match(dash.mat[, "value"], "8(px)?, *8(px)?") } }) test_that("stroke-dasharray default solid (no stroke-dasharray)", { for(xpath in solid.xpaths){ node.set <- getNodeSet(info$html, xpath) dash.mat <- get.dasharray(node.set) expect_true(all(is.na(dash.mat[, 1]))) } }) test_that("default is single selection", { selector.types <- lapply(info$selectors, "[[", "type") expect_match(selector.types$samples, "single") expect_match(selector.types$segments, "single") }) test_that("aes(id) geoms have ids", { nodes <- getNodeSet(info$html, '//*[@id][@class="geom"]') expect_equal(length(nodes), 24) }) test_that("4 elements in second plot", { nodes <- getNodeSet(info$html, '//g[@class="geom5_point_points"]//circle') expect_equal(length(nodes), 4) }) test_that("default is 150 elements", { nodes <- getNodeSet(info$html, '//g[@class="geom1_point_signal"]//circle') expect_equal(length(nodes), 150) }) test_that("default is 4 segments", { nodes <- getNodeSet(info$html, '//g[@class="geom3_segment_signal"]//line') expect_equal(length(nodes), 4) }) test_that("clickSelects 300 makes 300 elements", { html <- clickHTML(id=paste0("samples", 300)) nodes <- getNodeSet(html, '//g[@class="geom1_point_signal"]//circle') expect_equal(length(nodes), 300) }) test_that("clickSelects 1 changes to 1 element", { html <- clickHTML(id=paste0("segments", 1)) nodes <- getNodeSet(html, '//g[@class="geom3_segment_signal"]//line') expect_equal(length(nodes), 1) }) breakpointError$selector.types <- list(segments="multiple", samples="single") breakpointError$title <- "breakpointError (select several model sizes)" info <- animint2HTML(breakpointError) test_that("selector.types are converted to JSON", { selector.types <- lapply(info$selectors, "[[", "type") expect_match(selector.types$samples, "single") expect_match(selector.types$segments, "multiple") }) test_that("default is 150 and 4 elements", { nodes <- getNodeSet(info$html, '//g[@class="geom1_point_signal"]//circle') expect_equal(length(nodes), 150) nodes <- getNodeSet(info$html, '//g[@class="geom5_point_points"]//circle') expect_equal(length(nodes), 4) }) test_that("clickSelects 300 makes 300 elements", { html <- clickHTML(id=paste0("samples", 300)) nodes <- getNodeSet(html, '//g[@class="geom1_point_signal"]//circle') expect_equal(length(nodes), 300) }) test_that("clickSelects 1 adds 1 and 4 ", { html <- clickHTML(id=paste0("segments", 1)) nodes <- getNodeSet(html, '//g[@class="geom3_segment_signal"]//line') expect_equal(length(nodes), 5) nodes <- getNodeSet(html, '//g[@class="geom5_point_points"]//circle') expect_equal(length(nodes), 8) }) test_that("clickSelects 4 removes 4 elements and 4 ", { html <- clickHTML(id=paste0("segments", 4)) nodes <- getNodeSet(html, '//g[@class="geom3_segment_signal"]//line') expect_equal(length(nodes), 1) nodes <- getNodeSet(html, '//g[@class="geom5_point_points"]//circle') expect_equal(length(nodes), 4) }) test_that("clickSelects 1 removes all elements and all ", { html <- clickHTML(id=paste0("segments", 1)) nodes <- getNodeSet(html, '//g[@class="geom3_segment_signal"]//line') expect_equal(length(nodes), 0) nodes <- getNodeSet(html, '//g[@class="geom5_point_points"]//circle') expect_equal(length(nodes), 0) }) ## Tornado multiple selection. data(UStornadoes, package = "animint2") stateOrder <- data.frame(state = unique(UStornadoes$state)[order(unique(UStornadoes$TornadoesSqMile), decreasing=T)], rank = 1:49) # order states by tornadoes per square mile UStornadoes$state <- factor(UStornadoes$state, levels=stateOrder$state, ordered=TRUE) UStornadoes$weight <- 1/UStornadoes$LandArea USpolygons <- map_data("state") USpolygons$state = state.abb[match(USpolygons$region, tolower(state.name))] library(plyr) UStornadoCounts <- ddply(UStornadoes, .(state, year), summarize, count=length(state)) seg.color <- "#55B1F7" tornado.lines <- list( map=ggplot()+ make_text(UStornadoCounts, -100, 50, "year", "Tornadoes in %d")+ geom_polygon(aes( x=long, y=lat, group=group, id=state), clickSelects="state", data=USpolygons, fill="black", colour="grey") + geom_segment(aes( x=startLong, y=startLat, xend=endLong, yend=endLat), showSelected="year", colour=seg.color, data=UStornadoes)+ scale_fill_manual(values=c(end=seg.color))+ theme_animint(width=750, height=500)+ geom_point(aes( endLong, endLat, fill=place), colour=seg.color, showSelected="year", data=data.frame(UStornadoes,place="end")), ts=ggplot()+ geom_text(aes( year, count, label=state), hjust=0, showSelected="state", data=subset(UStornadoCounts, year==max(year)))+ make_tallrect(UStornadoCounts, "year")+ geom_line(aes( year, count, group=state), showSelected="state", data=UStornadoCounts), selector.types=list(state="multiple"), first=list(state=c("CA", "NY"), year=1950)) test_that("1950 and elements", { ## A warning should be issued when there is showSelected=place and ## there is only 1 value for place, but not when there is a legend ## (as in this data viz). expect_no_warning({ info <- animint2HTML(tornado.lines) }) t1950 <- subset(UStornadoes, year==1950) nodes <- getNodeSet(info$html, '//g[@class="geom3_segment_map"]//line') expect_equal(length(nodes), nrow(t1950)) nodes <- getNodeSet(info$html, '//g[@class="geom4_point_map"]//circle') expect_equal(length(nodes), nrow(t1950)) nodes <- getNodeSet(info$html, '//g[@class="geom7_line_ts"]//path') expect_equal(length(nodes), 2) nodes <- getNodeSet(info$html, '//g[@class="geom5_text_ts"]//text') expect_equal(length(nodes), 2) }) test_that("clickSelects CO adds 1 and 1 ", { html <- clickHTML(id="CO") nodes <- getNodeSet(html, '//g[@class="geom7_line_ts"]//path') expect_equal(length(nodes), 3) nodes <- getNodeSet(html, '//g[@class="geom5_text_ts"]//text') expect_equal(length(nodes), 3) }) test_that("clickSelects CA removes 1 and 1 ", { html <- clickHTML(id="CA") nodes <- getNodeSet(html, '//g[@class="geom7_line_ts"]//path') expect_equal(length(nodes), 2) nodes <- getNodeSet(html, '//g[@class="geom5_text_ts"]//text') expect_equal(length(nodes), 2) })