File: guide_axis.R

package info (click to toggle)
r-cran-ggvis 0.4.4%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,716 kB
  • sloc: sh: 25; makefile: 2
file content (196 lines) | stat: -rw-r--r-- 7,388 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#' Add a vega axis specification to a ggvis plot
#'
#' Axis specifications allow you to either override the default axes,
#' or additional axes.
#'
#' More information about axes can be found in the "axes and legends" vignettes.
#'
#' @section Compared to ggplot2:
#'
#' In ggplot2, axis (and legend) properties are part of the scales
#' specification. In vega, they are separate, which allows the specification
#' of multiple axes, and more flexible linkage between scales and axes.
#'
#' @param vis A ggvis object.
#' @param type The type of axis. Either x or y.
#' @param scale The name of the scale backing the axis component. Defaults to
#'   the scale type - you will need to specify if you want (e.g.) a scale
#'   for a secondary y-axis.
#' @param orient The orientation of the axis. One of top, bottom, left or right.
#'   The orientation can be used to further specialize the axis type (e.g., a y
#'   axis oriented for the right edge of the chart) - defaults to bottom for
#'   x axes, and left for y axes.
#' @param title A title for the axis. By default, it uses the name of the field
#'   in the first data set used by the scale. Use \code{""} to suppress the
#'   title.
#' @param title_offset The offset (in pixels) from the axis at which to place
#'   the title.
#' @param format The formatting pattern for axis labels. Vega uses D3's format
#'   pattern: \url{https://github.com/mbostock/d3/wiki/Formatting}
#' @param ticks A desired number of ticks. The resulting number may be different
#'   so that values are "nice" (multiples of 2, 5, 10) and lie within the
#'   underlying scale's range.
#' @param values Explicitly set the visible axis tick values.
#' @param subdivide If provided, sets the number of minor ticks between major
#'   ticks (the value 9 results in decimal subdivision).
#' @param tick_padding The padding, in pixels, between ticks and text labels.
#' @param tick_size_major,tick_size_minor,tick_size_end
#'   The size, in pixels, of major, minor and end ticks.
#' @param offset The offset, in pixels, by which to displace the axis from the
#'   edge of the enclosing group or data rectangle.
#' @param layer A string indicating if the axis (and any gridlines) should be
#'   placed above or below the data marks. One of "front" or "back" (default).
#' @param grid A flag indicating if gridlines should be created in addition to
#'   ticks.
#' @param properties Optional mark property definitions for custom axis styling.
#'   Should be an object created by \code{\link{axis_props}}, with properties
#'   for ticks, majorTicks, minorTicks, grid, labels, title, and axis.
#' @seealso Vega axis documentation:
#'   \url{https://github.com/trifacta/vega/wiki/Axes}
#' @export
#' @examples
#' mtcars %>% ggvis(x = ~wt, y = ~mpg, fill = ~cyl) %>%
#'   layer_points() %>%
#'   add_axis("x", title = "Weight", orient = "top")
#'
#' # Suppress axis with hide_axis
#' mtcars %>% ggvis(x = ~wt, y = ~mpg, fill = ~cyl) %>%
#'   layer_points() %>%
#'   hide_axis("x") %>% hide_axis("y")
#'
#' mtcars %>% ggvis(x = ~wt, y = ~mpg) %>% layer_points() %>%
#'   add_axis("x", title = "Weight", ticks = 40,
#'     properties = axis_props(
#'       ticks = list(stroke = "red"),
#'       majorTicks = list(strokeWidth = 2),
#'       grid = list(stroke = "red"),
#'       labels = list(
#'         fill = "steelblue",
#'         angle = 50,
#'         fontSize = 14,
#'         align = "left",
#'         baseline = "middle",
#'         dx = 3
#'       ),
#'       title = list(fontSize = 16),
#'       axis = list(stroke = "#333", strokeWidth = 1.5)
#'     )
#'   )
add_axis <- function(vis, type, scale = NULL, orient = NULL, title = NULL,
                       title_offset = NULL, format = NULL, ticks = NULL,
                       values = NULL, subdivide = NULL, tick_padding = NULL,
                       tick_size_major = NULL, tick_size_minor = tick_size_major,
                       tick_size_end = tick_size_major, offset = NULL,
                       layer = "back", grid = TRUE, properties = NULL) {

  if (is.null(scale)) {
    if (is.null(vis$cur_vis)) {
      scale <- type
    } else {
      scale <- paste0(type, paste0(vis$cur_vis, collapse = "-"))
    }
  }

  axis <- create_axis(type, scale, orient, title, title_offset, format,
                      ticks, values, subdivide, tick_padding,
                      tick_size_major, tick_size_minor, tick_size_end,
                      offset, layer, grid, properties)

  append_ggvis(vis, "axes", axis)
}

#' @rdname add_axis
#' @export
hide_axis <- function(vis, scale) {
  axis <- structure(list(scale = scale, hide = TRUE), class = "ggvis_axis")
  append_ggvis(vis, "axes", axis)
}

#' Defunct function for adding an axis
#'
#' This function has been replaced with \code{\link{add_axis}}.
#' @param ... Other arguments.
#' @export
add_guide_axis <- function(...) {
  stop("add_guide_axis() has been replaced by add_axis().")
}

# Create an axis object.
create_axis <- function(type, scale = type, orient = NULL, title = NULL,
                 title_offset = NULL, format = NULL, ticks = NULL,
                 values = NULL, subdivide = NULL, tick_padding = NULL,
                 tick_size_major = NULL, tick_size_minor = tick_size_major,
                 tick_size_end = tick_size_major, offset = NULL,
                 layer = "back", grid = TRUE, properties = NULL) {

  assert_that(type %in% c("x", "y"))
  assert_that(is.string(scale))

  if (is.null(orient)) orient <- c(x = "bottom", y = "left")[type]
  orient <- match.arg(orient, c("top", "right", "bottom", "left"))

  assert_that(is.null(title) || is.string(title))
#   assert_that(is.number(title_offset))

  layer <- match.arg(layer, c("front", "back"))
  assert_that(is.flag(grid))

  assert_that(is.null(properties) || is.axis_props(properties))

  structure(compact(list(
      type = type, scale = scale, orient = orient, title = title,
      titleOffset = title_offset, format = format, ticks = ticks,
      values = values, subdivide = subdivide, tickPadding = tick_padding,
      tickSizeMajor = tick_size_major, tickSizeMinor = tick_size_minor,
      tickSizeEnd = tick_size_end, offset = offset, layer = layer,
      grid = grid, properties = properties
  )), class = "ggvis_axis")
}


add_missing_axes <- function(vis) {
  axes <- vis$axes
  scales <- vis$scales

  present <- vapply(axes, "[[", "scale", FUN.VALUE = character(1))
  missing <- setdiff(intersect(names(scales), c("x", "y")), present)

  for (scale in missing) {
    vis <- add_axis(vis, scale)
  }
  vis
}

# Some axis settings require examining the scale
apply_axes_defaults <- function(vis) {
  axes <- vis$axes
  scales <- vis$scales

  axes <- lapply(axes, function(axis) {
    scale <- scales[[axis$scale]]

    # If we don't have a title, try to get it from the scale.
    # Use [[-indexing to avoid partial name matching of "titleOffset". (#269)
    if (is.null(axis[["title"]])) {
      axis$title <- scale$label
    }

    axis
  })

  # Replace the original axes with the new ones
  vis$axes <- axes
  vis
}

#' @export
format.ggvis_axis <- function(x, ...) {
  params <- param_string(x, collapse = FALSE)
  param_s <- paste0("  ", format(paste0(names(params), ":")), " ", format(params),
    collapse = "\n")

  paste0("<", class(x)[1], ">\n", param_s)
}

#' @export
print.ggvis_axis <- function(x, ...) cat(format(x, ...), "\n", sep = "")