Skip to content

Commit

Permalink
Merge pull request #146 from tdhock/warn-no-key
Browse files Browse the repository at this point in the history
warn for geoms with showSelected=duration var but no key
  • Loading branch information
Toby Dylan Hocking committed May 8, 2016
2 parents 34ff74e + 2c575fc commit 6b1c9e5
Show file tree
Hide file tree
Showing 10 changed files with 316 additions and 38 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: animint
Maintainer: Toby Dylan Hocking <[email protected]>
Author: Toby Dylan Hocking, Susan VanderPlas, Carson Sievert, Kevin Ferris, Tony Tsai
Version: 2016.05.07
Version: 2016.05.08
License: GPL-3
Title: Interactive animations
Description: An interactive animation can be defined using a list of
Expand Down
8 changes: 8 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@ RENDER: multiple animints inside of a single shiny app? This is
probably just a theoretical issue. (why not just make a single
animint?)

2016.05.08 PR#146

GGPLOT: the compiler now stops with an informative error when stats
are used with showSelected. New warning when position is used with
showSelected.

RENDER: aes(href) works when data_is_object (e.g. geom_polygon)

2016.05.07 PR#151

BUGFIX: common chunk data were not computed correctly when some chunks
Expand Down
57 changes: 44 additions & 13 deletions R/animint.R
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ saveLayer <- function(l, d, meta){
## plot.Selectors.

s.aes <- selector.aes(g$aes)
meta$selector.aes[[g$classed]] <- s.aes

## Do not copy group unless it is specified in aes, and do not copy
## showSelected variables which are specified multiple times.
Expand Down Expand Up @@ -486,19 +487,30 @@ saveLayer <- function(l, d, meta){
}
}

## Warn if stat_bin is used with animint aes. geom_bar + stat_bin
## doesn't make sense with clickSelects/showSelected, since two
not.identity <- function(stat.or.position){
x <- stat.or.position$objname
is.character(x) && length(x)==1 && x != "identity"
}
is.show <- grepl("showSelected", names(g$aes))
has.show <- any(is.show)
## Error if non-identity stat is used with showSelected, since
## typically the stats will delete the showSelected column from the
## built data set. For example geom_bar + stat_bin doesn't make
## sense with clickSelects/showSelected, since two
## clickSelects/showSelected values may show up in the same bin.
stat <- l$stat
if(!is.null(stat)){
is.bin <- stat$objname=="bin"
is.animint.aes <- grepl("clickSelects|showSelected", names(g$aes))
if(is.bin & any(is.animint.aes)){
warning(paste0("stat_bin is unpredictable ",
"when used with clickSelects/showSelected.\n",
"Use plyr::ddply() to do the binning ",
"or use make_bar if using geom_bar/geom_histogram."))
}
if(has.show && not.identity(l$stat)){
show.names <- names(g$aes)[is.show]
data.has.show <- show.names %in% names(g.data)
signal <- if(all(data.has.show))warning else stop
print(l)
signal("showSelected only works with stat=identity, problem: ",
g$classed)
}
## Warn if non-identity position is used with animint aes.
if(has.show && not.identity(l$position)){
print(l)
warning("showSelected only works with position=identity, problem: ",
g$classed)
}

##print("before pre-processing")
Expand Down Expand Up @@ -893,7 +905,8 @@ saveLayer <- function(l, d, meta){
}

## group should be the last thing in nest_order, if it is present.
if("group" %in% names(g$aes)){
data.object.geoms <- c("line", "path", "ribbon", "polygon")
if("group" %in% names(g$aes) && g$geom %in% data.object.geoms){
g$nest_order <- c(g$nest_order, "group")
}

Expand Down Expand Up @@ -1405,6 +1418,24 @@ animint2dir <- function(plot.list, out.dir = tempfile(),
as.list(unique(unlist(lapply(values.update, "[[", "update"))))
}

## Now that selectors are all defined, go back through geoms to
## check if there are any warnings to issue.
for(g.name in names(meta$geoms)){
g.info <- meta$geoms[[g.name]]
g.selectors <- meta$selector.aes[[g.name]]
show.vars <- g.info$aes[g.selectors$showSelected$one]
duration.vars <- names(meta$duration)
show.with.duration <- show.vars[show.vars %in% duration.vars]
no.key <- ! "key" %in% names(g.info$aes)
if(length(show.with.duration) && no.key){
warning(
"to ensure that smooth transitions are interpretable, ",
"aes(key) should be specifed for geoms with aes(showSelected=",
show.with.duration[1],
"), problem: ", g.name)
}
}

## For a static data viz with no interactive aes, no need to check
## for trivial showSelected variables with only 1 level.
if(0 < length(meta$selectors)){
Expand Down
2 changes: 1 addition & 1 deletion inst/examples/breakpoints.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ breakpointError <-
geom_line(aes(segments, error, group=bases.per.probe,
clickSelects=bases.per.probe),
data=only.error, lwd=4))
gg2animint(breakpointError)
animint2dir(breakpointError)

63 changes: 42 additions & 21 deletions inst/htmljs/animint.js
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,7 @@ var animint = function (to_select, json_file) {
}
}

var eActions, eAppend;
var eActions, eAppend, linkActions;
var key_fun = null;
var id_fun = function(d){
return d.id;
Expand Down Expand Up @@ -1246,6 +1246,17 @@ var animint = function (to_select, json_file) {
return one_row.id;
};
elements = elements.data(kv, key_fun);
linkActions = function(a_elements){
a_elements
.attr("xlink:href", function(group_info){
var one_group = keyed_data[group_info.value];
var one_row = one_group[0];
return one_row.href;
})
.attr("target", "_blank")
.attr("class", "geom")
;
};
eActions = function (e) {
e.attr("d", function (d) {
var one_group = keyed_data[d.value];
Expand Down Expand Up @@ -1294,7 +1305,14 @@ var animint = function (to_select, json_file) {
});
};
eAppend = "path";
} else if (g_info.geom == "segment") {
}else{
linkActions = function(a_elements){
a_elements.attr("xlink:href", function(d){ return d.href; })
.attr("target", "_blank")
.attr("class", "geom");
};
}
if (g_info.geom == "segment") {
elements = elements.data(data, key_fun);
eActions = function (e) {
e.attr("x1", function (d) {
Expand All @@ -1314,7 +1332,8 @@ var animint = function (to_select, json_file) {
.style("stroke", get_colour);
};
eAppend = "line";
} else if (g_info.geom == "linerange") {
}
if (g_info.geom == "linerange") {
elements = elements.data(data, key_fun);
eActions = function (e) {
e.attr("x1", function (d) {
Expand All @@ -1334,7 +1353,8 @@ var animint = function (to_select, json_file) {
.style("stroke", get_colour);
};
eAppend = "line";
} else if (g_info.geom == "vline") {
}
if (g_info.geom == "vline") {
elements = elements.data(data, key_fun);
eActions = function (e) {
e.attr("x1", toXY("x", "xintercept"))
Expand All @@ -1346,7 +1366,8 @@ var animint = function (to_select, json_file) {
.style("stroke", get_colour);
};
eAppend = "line";
} else if (g_info.geom == "hline") {
}
if (g_info.geom == "hline") {
// pretty much a copy of geom_vline with obvious modifications
elements = elements.data(data, key_fun);
eActions = function (e) {
Expand All @@ -1359,7 +1380,8 @@ var animint = function (to_select, json_file) {
.style("stroke", get_colour);
};
eAppend = "line";
} else if (g_info.geom == "text") {
}
if (g_info.geom == "text") {
elements = elements.data(data, key_fun);
// TODO: how to support vjust? firefox doensn't support
// baseline-shift... use paths?
Expand All @@ -1375,7 +1397,8 @@ var animint = function (to_select, json_file) {
});
};
eAppend = "text";
} else if (g_info.geom == "point") {
}
if (g_info.geom == "point") {
elements = elements.data(data, key_fun);
eActions = function (e) {
e.attr("cx", toXY("x", "x"))
Expand All @@ -1385,7 +1408,8 @@ var animint = function (to_select, json_file) {
.style("stroke", get_colour);
};
eAppend = "circle";
} else if (g_info.geom == "jitter") {
}
if (g_info.geom == "jitter") {
elements = elements.data(data, key_fun);
eActions = function (e) {
e.attr("cx", toXY("x", "x"))
Expand All @@ -1395,7 +1419,8 @@ var animint = function (to_select, json_file) {
.style("stroke", get_colour);
};
eAppend = "circle";
} else if (g_info.geom == "tallrect") {
}
if (g_info.geom == "tallrect") {
elements = elements.data(data, key_fun);
eActions = function (e) {
e.attr("x", toXY("x", "xmin"))
Expand All @@ -1410,7 +1435,8 @@ var animint = function (to_select, json_file) {
.style("stroke", get_colour);
};
eAppend = "rect";
} else if (g_info.geom == "widerect") {
}
if (g_info.geom == "widerect") {
elements = elements.data(data, key_fun);
eActions = function (e) {
e.attr("y", toXY("y", "ymax"))
Expand All @@ -1425,7 +1451,8 @@ var animint = function (to_select, json_file) {
.style("stroke", get_colour);
};
eAppend = "rect";
} else if (g_info.geom == "rect") {
}
if (g_info.geom == "rect") {
elements = elements.data(data, key_fun);
eActions = function (e) {
e.attr("x", toXY("x", "xmin"))
Expand All @@ -1444,7 +1471,8 @@ var animint = function (to_select, json_file) {
}
};
eAppend = "rect";
} else if (g_info.geom == "boxplot") {
}
if (g_info.geom == "boxplot") {

// TODO: currently boxplots are unsupported (we intentionally
// stop with an error in the R code). The reason why is that
Expand Down Expand Up @@ -1524,16 +1552,9 @@ var animint = function (to_select, json_file) {
.style("stroke-width", get_size)
.style("stroke", get_colour);
};
} else {
return "unsupported geom " + g_info.geom;
}
elements.exit().remove();
var enter = elements.enter();
var linkActions = function(a_elements){
a_elements.attr("xlink:href", function(d){ return d.href; })
.attr("target", "_blank")
.attr("class", "geom");
};
if(g_info.aes.hasOwnProperty("href")){
enter = enter.append("svg:a")
.append("svg:"+eAppend);
Expand Down Expand Up @@ -1960,7 +1981,7 @@ var animint = function (to_select, json_file) {
// add a button to view the animation widgets
var show_hide_animation_controls = element.append("button")
.text(show_message)
.attr("id", "show_hide_animation_controls")
.attr("id", viz_id + "_show_hide_animation_controls")
.on("click", function(){
if(this.textContent == show_message){
time_table.style("display", "");
Expand Down Expand Up @@ -2027,7 +2048,7 @@ var animint = function (to_select, json_file) {
var duration_inputs = duration_tds
.append("input")
.attr("id", function(s_name){
return "duration_ms_" + s_name;
return viz_id + "_duration_ms_" + s_name;
})
.attr("type", "text")
.on("change", function(s_name){
Expand Down
Loading

0 comments on commit 6b1c9e5

Please sign in to comment.