#' Get next scope name
#'
#' @keywords internal
#' @param prev_scopes A vector of previous scope names.
#' @return The new scope name which does not conflict with any previous scope name.
get_next_scope <- function(prev_scopes) {
chars <- c('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z')
get_next <- function(next_char_indices) {
r <- c()
for(char_index in next_char_indices) {
r <- c(chars[char_index], r)
}
increment <- TRUE
for(i in seq_len(length(next_char_indices))) {
next_char_indices[i] <- next_char_indices[i] + 1
val <- next_char_indices[i]
if(val > length(chars)) {
next_char_indices[i] <- 1
} else {
increment <- FALSE
break;
}
}
if(increment) {
next_char_indices <- c(next_char_indices, 1)
}
new_scope <- paste(r, sep = "")
result <- list(ns = new_scope, nci = next_char_indices)
result
}
next_char_indices = c(1)
next_scope_result <- get_next(next_char_indices)
next_scope <- next_scope_result$ns
next_char_indices <- next_scope_result$nci
while(is.element(next_scope, prev_scopes)) {
next_scope_result <- get_next(next_char_indices)
next_scope <- next_scope_result$ns
next_char_indices <- next_scope_result$nci
}
next_scope
}
#' File in a dataset in a VitessceConfig
#' @title VitessceConfigDatasetFile Class
#' @docType class
#' @description
#' Class representing a file in a dataset in a Vitessce view config.
#'
#' @rdname VitessceConfigDatasetFile
VitessceConfigDatasetFile <- R6::R6Class("VitessceConfigDatasetFile",
private = list(
file = NULL
),
public = list(
#' @description
#' Create a new dataset file object.
#' @param url A URL for the file.
#' @param data_type A data type for the file.
#' @param file_type A file type for the file.
#' @param options A list of options to include for the file.
#' @param coordination_values A list of coordination values to include in the file definition.
#' @return A new `VitessceConfigDatasetFile` object.
initialize = function(url = NA, file_type = NA, options = NA, coordination_values = NA, data_type = NA) {
private$file <- obj_list()
private$file[['fileType']] = file_type
if(!is_na(url)) {
private$file[['url']] = url
}
if(!is_na(options)) {
private$file[['options']] = options
}
if(!is_na(coordination_values)) {
private$file[['coordinationValues']] = coordination_values
}
},
#' @description
#' Convert the object to an R list. Helpful when converting the config to JSON.
#' @return A `list` that can be serialized to JSON using `rjson`.
to_list = function() {
private$file
}
)
)
#' Dataset in a VitessceConfig
#' @title VitessceConfigDataset Class
#' @docType class
#' @description
#' Class representing a dataset in a Vitessce view config.
#'
#' @rdname VitessceConfigDataset
VitessceConfigDataset <- R6::R6Class("VitessceConfigDataset",
private = list(
objs = NULL
),
public = list(
#' @field dataset The dataset as a list.
dataset = NULL,
#' @field base_dir The base directory for the config.
base_dir = NULL,
#' @description
#' Create a new dataset object.
#' @param uid A unique identifier string for the dataset.
#' @param name A name for the dataset
#' @param base_dir A directory which local files are configured relative to.
#' @return A new `VitessceConfigDataset` object.
initialize = function(uid, name, base_dir = NA) {
self$dataset <- list(
uid = uid,
name = name,
files = list()
)
private$objs <- list()
self$base_dir <- base_dir
},
#' @description
#' Get the dataset name.
#' @return The name as a string.
get_name = function() {
return(self$dataset[['name']])
},
#' @description
#' Get the dataset UID.
#' @return The uid as a string.
get_uid = function() {
return(self$dataset[['uid']])
},
#' @description
#' Add a file to this dataset.
#' @param url The URL to the file.
#' @param data_type The data type for the file.
#' @param file_type The file type for the file.
#' @param options Optional. An options list for the file.
#' @return Invisible self, to allow chaining.
#' @examples
#' base_url <- "http://localhost:8000/"
#' vc <- VitessceConfig$new(schema_version = "1.0.16", name = "My config")
#' dataset <- vc$add_dataset("My dataset")$add_file(
#' url = paste0(base_url, "cells.json"),
#' data_type = DataType$CELLS,
#' file_type = FileType$CELLS_JSON
#' )
add_file = function(url = NA, file_type = NA, options = NA, coordination_values = NA, data_type = NA) {
new_file <- VitessceConfigDatasetFile$new(url = url, file_type = file_type, options = options, coordination_values = coordination_values)
self$dataset$files <- append(self$dataset$files, new_file)
invisible(self)
},
#' @description
#' Add a data object to this dataset.
#' @param obj The data object to add.
#' @return Invisible self, to allow chaining.
add_object = function(obj) {
obj$convert_and_save(self$dataset$uid, length(private$objs), base_dir = self$base_dir)
private$objs <- append(private$objs, obj)
invisible(self)
},
#' @description
#' Get a list of web server route objects corresponding to any local files which will need to be served.
#' @return A `list` of `VitessceConfigServerStaticRoute`.
get_routes = function() {
routes <- list()
for(obj in private$objs) {
obj_routes <- obj$get_routes()
for(obj_route in obj_routes) {
routes <- append(routes, obj_route)
}
}
return(routes)
},
#' @description
#' Convert the dataset to an R list. Helpful when converting the config to JSON.
#' @param base_url The base URL to prepend to web server file paths.
#' @return A `list` that can be serialized to JSON using `rjson`.
to_list = function(base_url = NA) {
obj_file_defs <- list()
if(length(private$objs) > 0) {
for(obj in private$objs) {
new_obj_file_defs <- obj$get_file_defs(base_url)
for(new_obj_file_def in new_obj_file_defs) {
obj_file_defs <- append(obj_file_defs, list(new_obj_file_def))
}
}
}
for(obj_file in self$dataset$files) {
f_list <- obj_file$to_list()
obj_file_defs <- append(obj_file_defs, list(f_list))
}
retval <- self$dataset
retval$files <- obj_file_defs
return(retval)
}
)
)
CoordinationLevel <- R6::R6Class("CoordinationLevel",
public = list(
value = NULL,
cached_value = NULL,
initialize = function(value) {
self$value <- value
self$cached_value <- NA
},
set_cached = function(processed_level) {
self$cached_value <- processed_level
},
get_cached = function() {
return(self$cached_value)
},
is_cached = function() {
return(!is.na(self$cached_value))
}
)
)
CL <- function(value) {
return(CoordinationLevel$new(value))
}
#' Coordination scope in a VitessceConfig
#' @title VitessceConfigCoordinationScope Class
#' @docType class
#' @description
#' Class representing a coordination scope in a Vitessce view config.
#'
#' @rdname VitessceConfigCoordinationScope
VitessceConfigCoordinationScope <- R6::R6Class("VitessceConfigCoordinationScope",
public = list(
#' @field c_type The coordination type as a string.
c_type = NULL,
#' @field c_scope The coordination scope as a string.
c_scope = NULL,
#' @field c_value The coordination value.
c_value = NULL,
#' @description
#' Create a new coordination scope object.
#' @param c_type A coordination type name.
#' @param c_scope A coordination scope name.
#' @param c_value An initial value for the coordination scope.
#' @return A new `VitessceConfigCoordinationScope` object.
initialize = function(c_type, c_scope, c_value = NA) {
self$c_type <- c_type
self$c_scope <- c_scope
self$c_value <- c_value
},
#' @description
#' Set the coordination value of this coordination scope object.
#' @param c_value The value to set.
#' @return Invisible self, to allow chaining.
set_value = function(c_value) {
if(length(c_value) > 1) {
self$c_value <- c_value
} else {
self$c_value <- jsonlite::unbox(c_value)
}
invisible(self)
},
#' @description
#' Set the coordination value of this coordination scope object, without unboxing.
#' @param c_value The value to set.
#' @return Invisible self, to allow chaining.
set_value_raw = function(c_value) {
self$c_value <- c_value
invisible(self)
}
)
)
VitessceConfigMetaCoordinationScope <- R6::R6Class("VitessceConfigMetaCoordinationScope",
public = list(
#' @field meta_scope The name of the coordination scope for metaCoordinationScopes.
meta_scope = NULL,
#' @field meta_by_scope The name of the coordination scope for metaCoordinationScopesBy.
meta_by_scope = NULL,
initialize = function(meta_scope, meta_by_scope) {
self$meta_scope = VitessceConfigCoordinationScope$new(CoordinationType$META_COORDINATION_SCOPES, meta_scope)
self$meta_by_scope = VitessceConfigCoordinationScope$new(CoordinationType$META_COORDINATION_SCOPES_BY, meta_by_scope)
},
use_coordination = function(c_scopes) {
if(is.na(self$meta_scope4c_value)) {
self$meta_scope$set_value(obj_list())
}
meta_scopes_val <- self$meta_scope$c_value
for(c_scope in c_scopes) {
meta_scopes_val[[c_scope$c_type]] <- c_scope$c_scope
}
self$meta_scope$set_value(meta_scopes_val)
invisible(self)
},
use_coordination_by_dict = function(scopes) {
# TODO
invisible(self)
}
)
)
#' Horizontal view concatenation in a VitessceConfig
#' @title VitessceConfigViewHConcat Class
#' @docType class
#' @description
#' Class representing a horizontal view concatenation in a Vitessce view config.
#'
#' @rdname VitessceConfigViewHConcat
#' @keywords internal
VitessceConfigViewHConcat <- R6::R6Class("VitessceConfigViewHConcat",
public = list(
#' @field views The views to concatenate.
views = NULL,
#' @description
#' Create a new view concat object.
#' @param views A list of views.
#' @return A new `VitessceConfigViewHConcat` object.
initialize = function(views) {
self$views <- views
}
)
)
#' Vertical view concatenation in a VitessceConfig
#' @title VitessceConfigViewVConcat Class
#' @docType class
#' @description
#' Class representing a vertical view concatenation in a Vitessce view config.
#'
#' @rdname VitessceConfigViewVConcat
#' @keywords internal
VitessceConfigViewVConcat <- R6::R6Class("VitessceConfigViewVConcat",
public = list(
#' @field views The views to concatenate.
views = NULL,
#' @description
#' Create a new view concat object.
#' @param views A list of views.
#' @return A new `VitessceConfigViewVConcat` object.
initialize = function(views) {
self$views <- views
}
)
)
#' View in a VitessceConfig
#' @title VitessceConfigView Class
#' @docType class
#' @description
#' Class representing a view in a Vitessce view config.
#'
#' @rdname VitessceConfigView
VitessceConfigView <- R6::R6Class("VitessceConfigView",
private = list(
view = NULL
),
public = list(
#' @description
#' Create a new view object.
#' @param component A component name.
#' @param coordination_scopes A list of the coordination scope mappings for each coordination type.
#' @param x The x-coordinate of the view in the layout.
#' @param y The y-coordinate of the view in the layout.
#' @param w The width of the view in the layout.
#' @param h The height of the view in the layout.
#' @return A new `VitessceConfigView` object.
initialize = function(component, coordination_scopes, x, y, w, h) {
private$view <- list(
component = component,
coordinationScopes = coordination_scopes,
x = 0,
y = 0,
w = 1,
h = 1
)
},
#' @description
#' Link this view to existing coordination scope(s).
#' @param c_scopes A list of `VitessceConfigCoordinationScope` objects to use.
#' @return Invisible self, to allow chaining.
use_coordination = function(c_scopes) {
for(c_scope in c_scopes) {
private$view$coordinationScopes[[c_scope$c_type]] = c_scope$c_scope
}
invisible(self)
},
use_coordination_by_dict = function(scopes) {
# TODO
invisible(self)
},
use_meta_coordination = function(meta_scope) {
# TODO
invisible(self)
},
#' @description
#' Set the dimensions of the view.
#' @param x The x-coordinate of the view in the layout.
#' @param y The y-coordinate of the view in the layout.
#' @param w The width of the view in the layout.
#' @param h The height of the view in the layout.
#' @return Self, to allow chaining.
set_xywh = function(x, y, w, h) {
private$view$x <- x
private$view$y <- y
private$view$w <- w
private$view$h <- h
invisible(self)
},
#' @description
#' Set additional props for this view.
#' @param ... Any named props to set.
#' @return Self, to allow chaining.
set_props = function(...) {
private$view[['props']] <- list(...)
invisible(self)
},
#' @description
#' Convert the object to an R list. Helpful when converting the config to JSON.
#' @return A `list` that can be serialized to JSON using `rjson`.
to_list = function() {
private$view
}
)
)
#' VitessceConfig
#' @title VitessceConfig Class
#' @docType class
#' @description
#' Class representing a Vitessce view config.
#'
#' @rdname VitessceConfig
#' @export
VitessceConfig <- R6::R6Class("VitessceConfig",
public = list(
#' @field config The internal representation of the view config.
config = NULL,
#' @field base_dir The base directory for the config.
base_dir = NULL,
#' @description
#' Create a new config object.
#' @param schema_version The Vitessce config schema version to use.
#' @param name A name for the config.
#' @param description A description for the config.
#' @return A new `VitessceConfig` object.
initialize = function(schema_version, name = NA, description = NA, base_dir = NA) {
self$config <- list(
version = schema_version,
name = ifelse(is_na(name), "", name),
description = ifelse(is_na(description), "", description),
datasets = list(),
coordinationSpace = obj_list(),
layout = list(),
initStrategy = "auto"
)
self$base_dir <- base_dir
},
#' @description
#' Add a dataset to the config.
#' @param name A name for the dataset.
#' @param uid A unique ID for the dataset. Optional. Created automatically if not provided.
#' @return A new `VitessceConfigDataset` object.
#' @examples
#' vc <- VitessceConfig$new(schema_version = "1.0.16", name = "My config")
#' ds <- vc$add_dataset("My dataset")
add_dataset = function(name, uid = NA) {
prev_dataset_uids <- c()
for(d in self$config$datasets) {
prev_dataset_uids <- c(prev_dataset_uids, d$dataset$uid)
}
uid <- ifelse(is_na(uid), get_next_scope(prev_dataset_uids), uid)
new_dataset <- VitessceConfigDataset$new(uid, name, base_dir = self$base_dir)
self$config$datasets <- append(self$config$datasets, new_dataset)
new_scopes <- self$add_coordination(CoordinationType$DATASET)
new_scopes[[1]]$set_value(uid)
new_dataset
},
#' @description
#' Add a view to the config.
#' @param dataset The dataset object to associate with this view.
#' @param component The name of a component to render in this view.
#' @param x The x-coordinate of the view in the layout.
#' @param y The y-coordinate of the view in the layout.
#' @param w The width of the view in the layout.
#' @param h The height of the view in the layout.
#' @param mapping An optional convenience parameter for setting the `CoordinationType$EMBEDDING_TYPE` coordination value if the component is`Component$SCATTERPLOT`.
#' @return A new `VitessceConfigView` object.
#' @examples
#' vc <- VitessceConfig$new(schema_version = "1.0.16", name = "My config")
#' ds <- vc$add_dataset("My dataset")
#' spatial <- vc$add_view(ds, "spatial")
add_view = function(dataset, component, x = NA, y = NA, w = NA, h = NA, mapping = NA) {
dataset_scope_name_matches <- c()
for(scope_name in names(self$config$coordinationSpace[[CoordinationType$DATASET]])) {
dataset_scope <- self$config$coordinationSpace[[CoordinationType$DATASET]][[scope_name]]
if(dataset_scope$c_value == dataset$dataset$uid) {
dataset_scope_name_matches <- c(dataset_scope_name_matches, scope_name)
}
}
dataset_scope_name <- NA
if(length(dataset_scope_name_matches) == 1) {
dataset_scope_name <- dataset_scope_name_matches[1]
}
coordination_scopes <- list()
coordination_scopes[[CoordinationType$DATASET]] <- dataset_scope_name
new_view <- VitessceConfigView$new(component, coordination_scopes, x, y, w, h)
if(!is_na(mapping)) {
et_scopes <- self$add_coordination(CoordinationType$EMBEDDING_TYPE)
et_scope <- et_scopes[[1]]
et_scope$set_value(mapping)
new_view$use_coordination(et_scopes)
}
self$config$layout <- append(self$config$layout, new_view)
new_view
},
#' @description
#' Add a coordination scope to the config, for one or more coordination types.
#' @param c_types The coordination types for which to create new coordination scopes.
#' @return A list of new `VitessceConfigCoordinationScope` objects.
#' @examples
#' vc <- VitessceConfig$new(schema_version = "1.0.16", name = "My config")
#' ds <- vc$add_dataset("My dataset")
#' spatial <- vc$add_view(ds, "spatial")
#' c_scopes <- vc$add_coordination(c("spatialZoom", "spatialTargetX"))
#' spatial$use_coordination(c_scopes)
add_coordination = function(c_types) {
result <- list()
# We want to allow the user to obtain multiple instances of `VitessceConfigCoordinationScope`
# (one coordination scope instance per coordination type in the `c_types` list).
for(c_type in c_types) {
# We need to make sure that the new coordination scope instance has a unique name,
# among all coordination scopes with the same coordination type.
c_obj <- self$config$coordinationSpace[[c_type]]
prev_scopes <- character()
if(!is.null(c_obj)) {
# We retrieve the existing coordination scope names for this coordination type.
prev_scopes <- names(c_obj)
}
# With the `get_next_scope` function, we obtain a unique name which does not conflict
# with any of the existing names in `prev_scopes`.
c_scope <- get_next_scope(prev_scopes)
# We create a new coordination scope instance with the new name.
scope <- VitessceConfigCoordinationScope$new(c_type, c_scope)
# We want to include the new coordination scope instance in the coordination space.
if(!is.element(c_type, names(self$config$coordinationSpace))) {
# A coordination object for this coordination type does not yet exist in the coordination space.
self$config$coordinationSpace[[c_type]] <- list()
}
# We append the new instance to the coordination object in the coordination space.
self$config$coordinationSpace[[c_type]][[c_scope]] <- scope
# We append the new instance to the result, which will be returned to the user.
result <- append(result, scope)
}
result
},
add_meta_coordination = function() {
# TODO
},
add_coordination_by_dict = function(input_val) {
# TODO
},
link_views_by_dict = function(views, input_val, meta = TRUE) {
# TODO
},
#' @description
#' Define the layout of views.
#' @param view_concat A concatenation of views.
#' @return Self, to allow chaining.
#' @examples
#' vc <- VitessceConfig$new(schema_version = "1.0.16", name = "My config")
#' ds <- vc$add_dataset("My dataset")
#' spatial <- vc$add_view(ds, "spatial")
#' scatterplot <- vc$add_view(ds, "scatterplot")
layout = function(view_concat) {
# TODO
layout_aux <- function(obj, x_min, x_max, y_min, y_max) {
w <- x_max - x_min
h <- y_max - y_min
if(methods::is(obj, "VitessceConfigView")) {
obj$set_xywh(x_min, y_min, w, h)
} else if(methods::is(obj, "VitessceConfigViewHConcat")) {
views <- obj$views
num_views <- length(views)
for(i in seq_len(num_views)) {
layout_aux(
views[[i]],
x_min+(w/num_views)*(i-1),
x_min+(w/num_views)*i,
y_min,
y_max
)
}
} else if(methods::is(obj, "VitessceConfigViewVConcat")) {
views <- obj$views
num_views <- length(views)
for(i in seq_len(num_views)) {
layout_aux(
views[[i]],
x_min,
x_max,
y_min+(h/num_views)*(i-1),
y_min+(h/num_views)*i
)
}
}
}
# Recursively set the values (x,y,w,h) for each view.
layout_aux(view_concat, 0, 12, 0, 12)
# TODO: decide how to handle views that were omitted from the `view_concat` parameter
# TODO: decide how to handle .add_view() being called after .layout() has been called
invisible(self)
},
#' @description
#' A convenience function for setting up new coordination scopes across a set of views.
#' @param views An array of view objects to link together.
#' @param c_types The coordination types on which to coordinate the views.
#' @param c_values Initial values corresponding to each coordination type.
#' Should have the same length as the c_types array. Optional.
#' @param raw Should the coordination values be set using
#' VitessceConfigCoordinationScope$set_value() or
#' VitessceConfigCoordinationScope$set_value_raw()? Use
#' when setting lists or similar more complex values.
#' @return Self, to allow chaining.
#' @examples
#' vc <- VitessceConfig$new(schema_version = "1.0.16", name = "My config")
#' ref_dataset <- vc$add_dataset("Reference")
#' qry_dataset <- vc$add_dataset("Query")
#' ref_plot <- vc$add_view(ref_dataset, Component$SCATTERPLOT, mapping = "umap")
#' qry_plot <- vc$add_view(qry_dataset, Component$SCATTERPLOT, mapping = "proj.umap")
#' vc$link_views(
#' c(ref_plot, qry_plot),
#' c(CoordinationType$EMBEDDING_TARGET_X, CoordinationType$EMBEDDING_TARGET_Y),
#' c_values = c(0, 0)
#' )
link_views = function(views, c_types, c_values = NA, raw = FALSE) {
c_scopes <- self$add_coordination(c_types)
for(view in views) {
for(c_scope in c_scopes) {
view$use_coordination(c(c_scope))
}
}
if(!is_na(c_values) && length(c_types) == length(c_values)) {
for(i in seq_len(length(c_scopes))) {
c_scope <- c_scopes[[i]]
if(raw) {
c_scope$set_value_raw(c_values[[i]])
} else {
c_scope$set_value(c_values[[i]])
}
}
}
invisible(self)
},
#' @description
#' Convert the config to an R list. Helpful when converting the config to JSON.
#' @param base_url An base URL to prepend to file paths.
#' @return A `list` that can be serialized to JSON.
#' @examples
#' vc <- VitessceConfig$new(schema_version = "1.0.16", name = "My config")
#' ds <- vc$add_dataset("My dataset")
#' vc_list <- vc$to_list(base_url = "http://localhost:8000")
to_list = function(base_url = NA) {
retval <- self$config
retval_datasets <- list()
for(d in self$config$datasets) {
dataset_list <- d$to_list(base_url = base_url)
retval_datasets <- append(retval_datasets, list(dataset_list))
}
retval$datasets <- retval_datasets
retval_coordination_space <- obj_list()
for(c_type in names(self$config$coordinationSpace)) {
retval_coordination_space[[c_type]] <- obj_list()
c_scopes <- self$config$coordinationSpace[[c_type]]
for(c_scope_name in names(c_scopes)) {
c_scope <- c_scopes[[c_scope_name]]
retval_coordination_space[[c_type]][[c_scope_name]] <- c_scope$c_value
}
}
retval$coordinationSpace <- retval_coordination_space
retval_layout <- list()
for(v in self$config$layout) {
view_list <- v$to_list()
retval_layout <- append(retval_layout, list(view_list))
}
retval$layout <- retval_layout
retval
},
#' @description
#' Get a list of web server route objects corresponding to any local files which will need to be served.
#' @return A `list` of `VitessceConfigServerStaticRoute`.
get_routes = function() {
retval <- list()
for(d in self$config$datasets) {
dataset_routes <- d$get_routes()
for(dr in dataset_routes) {
retval <- append(retval, dr)
}
}
return(retval)
},
#' @description
#' Create an htmlwidget based on this config.
#' @param theme The theme of the widget, either "dark" or "light". Optional. By default, "dark".
#' @param width The width of the widget as a number or CSS string. Optional.
#' @param height The height of the widget as a number or CSS string. Optional.
#' @param port The port for the local web server (which serves local dataset objects to the widget).
#' Optional. By default, uses open port between 8000 and 9000.
#' @param base_url The base URL for the web server. Optional.
#' By default, creates a localhost URL which includes the port.
#' @param serve Should local data be served by running a local web server with R plumber? By default, TRUE.
#' @param element_id An element ID. Optional.
#' @param ... Passes extra keyword arguments to the `vitessce_widget` function.
#' @return The Vitessce htmlwidget.
#' @examples
#' vc <- VitessceConfig$new(schema_version = "1.0.16", name = "My config")
#' dataset <- vc$add_dataset("My dataset")
#' description <- vc$add_view(dataset, Component$DESCRIPTION)
#' vc$layout(description)
#' vc$widget()
widget = function(...) {
return(vitessce_widget(config = self, ...))
},
#' @description
#' Export the data associated with this configuration to a specified destination.
#' @param to Where should the files be exported to? Values currently supported: "files"
#' @param with_config Should the Vitessce configuration be saved in the output directory as a JSON file?
#' @param base_url If `with_config` is TRUE, what `base_url` value should be used for creation of the JSON config?
#' @param ... Extra parameters to pass through to the export function.
#' @return The Vitessce configuration as a list, with the `base_url` filled in.
#' @examples
#' vc <- VitessceConfig$new(schema_version = "1.0.16", name = "My config")
#' dataset <- vc$add_dataset("My dataset")
#' description <- vc$add_view(dataset, Component$DESCRIPTION)
#' vc$layout(description)
#' vc$export(with_config = TRUE, base_url = "http://localhost:3000", out_dir = "./data")
export = function(to = "files", with_config = FALSE, base_url = NA, ...) {
vc_list <- NA
if(to == "files") {
vc_list <- export_to_files(config = self, with_config = with_config, base_url = base_url, ...)
} else {
stop("Unknown export destination.")
}
invisible(vc_list)
}
)
)
#' @name VitessceConfig$from_list
#' @title Create a new Vitessce Config from a list
#' @description
#'
#' A helper function to construct a new `VitessceConfig` object based on an existing config in a list format.
#'
#' @param config A list containing a valid config.
#' @return A `VitessceConfig` object reflecting the list-based configuration values.
VitessceConfig$from_list <- function(config) {
vc <- VitessceConfig$new(config$version, name = config$name, description = config$description)
for(d in config$datasets) {
new_dataset <- vc$add_dataset(d$name, uid = d$uid)
for(f in d$files) {
new_dataset$add_file(
url = f$url,
file_type = ifelse(!is.null(f$fileType), f$fileType, NA),
coordination_values = ifelse(!is.null(f$coordinationValues), f$coordinationValues, NA),
options = ifelse(!is.null(f$options), f$options, NA)
)
}
}
for(c_type in names(config$coordinationSpace)) {
if(c_type != CoordinationType$DATASET) {
c_obj <- config$coordinationSpace[[c_type]]
vc$config$coordinationSpace[[c_type]] <- obj_list()
for(c_scope_name in names(c_obj)) {
c_scope_value <- c_obj[[c_scope_name]]
scope <- VitessceConfigCoordinationScope$new(c_type, c_scope_name)
scope$set_value(c_scope_value)
vc$config$coordinationSpace[[c_type]][[c_scope_name]] <- scope
}
}
}
for(c in config$layout) {
new_view <- VitessceConfigView$new(c$component, c$coordinationScopes, c$x, c$y, c$w, c$h)
vc$config$layout <- append(vc$config$layout, new_view)
}
return(vc)
}
#' @name VitessceConfig$from_object
#' @title Create a new Vitessce Config from a data object
#' @description
#'
#' A helper function to construct a new `VitessceConfig` object based on an object containing single-cell or imaging data.
#'
#' @param obj An object from which to construct a config. Can be a SingleCellExperiment or Seurat object.
#' @param name A name for the view config.
#' @param description A description for the view config.
#' @return A `VitessceConfig` object containing the object as a member of the datasets list, with some automatically-configured views.
VitessceConfig$from_object <- function(obj, schema_version, name = NA, description = NA) {
vc <- VitessceConfig$new(schema_version, name = name, description = description)
obj$auto_view_config(vc)
return(vc)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.