fixed passing JS func from proxy

This commit is contained in:
pvictor 2021-02-11 21:52:55 +01:00
parent 3e85bd477a
commit 9efca10228
6 changed files with 75 additions and 66 deletions

View File

@ -1,5 +1,5 @@
Package: apexcharter Package: apexcharter
Version: 0.1.8.910 Version: 0.1.8.9100
Title: Create Interactive Chart with the JavaScript 'ApexCharts' Library Title: Create Interactive Chart with the JavaScript 'ApexCharts' Library
Description: Provides an 'htmlwidgets' interface to 'apexcharts.js'. Description: Provides an 'htmlwidgets' interface to 'apexcharts.js'.
'Apexcharts' is a modern JavaScript charting library to build interactive charts and visualizations with simple API. 'Apexcharts' is a modern JavaScript charting library to build interactive charts and visualizations with simple API.

View File

@ -86,6 +86,7 @@ importFrom(htmltools,resolveDependencies)
importFrom(htmltools,tagList) importFrom(htmltools,tagList)
importFrom(htmltools,tags) importFrom(htmltools,tags)
importFrom(htmlwidgets,JS) importFrom(htmlwidgets,JS)
importFrom(htmlwidgets,JSEvals)
importFrom(htmlwidgets,createWidget) importFrom(htmlwidgets,createWidget)
importFrom(htmlwidgets,getDependency) importFrom(htmlwidgets,getDependency)
importFrom(htmlwidgets,shinyRenderWidget) importFrom(htmlwidgets,shinyRenderWidget)

View File

@ -1,28 +1,28 @@
#' @title Proxy for \code{apexchart} #' @title Proxy for \code{apexchart}
#' #'
#' @description Allow to update a chart in Shiny application. #' @description Allow to update a chart in Shiny application.
#' #'
#' @param shinyId single-element character vector indicating the output ID of the #' @param shinyId single-element character vector indicating the output ID of the
#' chart to modify (if invoked from a Shiny module, the namespace will be added #' chart to modify (if invoked from a Shiny module, the namespace will be added
#' automatically) #' automatically)
#' @param session the Shiny session object to which the chart belongs; usually the #' @param session the Shiny session object to which the chart belongs; usually the
#' default value will suffice #' default value will suffice
#' #'
#' @export #' @export
#' #'
#' @importFrom shiny getDefaultReactiveDomain #' @importFrom shiny getDefaultReactiveDomain
#' #'
apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain()) { apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain()) {
if (is.null(session)) { if (is.null(session)) {
stop("apexchartProxy must be called from the server function of a Shiny app") stop("apexchartProxy must be called from the server function of a Shiny app")
} }
if (!is.null(session$ns) && nzchar(session$ns(NULL)) && substring(shinyId, 1, nchar(session$ns(""))) != session$ns("")) { if (!is.null(session$ns) && nzchar(session$ns(NULL)) && substring(shinyId, 1, nchar(session$ns(""))) != session$ns("")) {
shinyId <- session$ns(shinyId) shinyId <- session$ns(shinyId)
} }
structure( structure(
list( list(
session = session, session = session,
@ -43,7 +43,7 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' @return A \code{apexchartProxy} \code{htmlwidget} object. #' @return A \code{apexchartProxy} \code{htmlwidget} object.
#' @noRd #' @noRd
.ax_proxy <- function(proxy, name, ...) { .ax_proxy <- function(proxy, name, ...) {
if (!"apexchart_Proxy" %in% class(proxy)) if (!"apexchart_Proxy" %in% class(proxy))
stop("This function must be used with a apexchartProxy object", call. = FALSE) stop("This function must be used with a apexchartProxy object", call. = FALSE)
proxy$session$sendCustomMessage( proxy$session$sendCustomMessage(
type = sprintf("update-apexchart-%s", name), type = sprintf("update-apexchart-%s", name),
@ -52,7 +52,7 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
proxy proxy
} }
.ax_proxy2 <- function(proxy, name, l) { .ax_proxy2 <- function(proxy, name, l) {
if (!"apexchart_Proxy" %in% class(proxy)) if (!"apexchart_Proxy" %in% class(proxy))
stop("This function must be used with a apexchartProxy object", call. = FALSE) stop("This function must be used with a apexchartProxy object", call. = FALSE)
proxy$session$sendCustomMessage( proxy$session$sendCustomMessage(
type = sprintf("update-apexchart-%s", name), type = sprintf("update-apexchart-%s", name),
@ -64,9 +64,9 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' @title Proxy for updating series. #' @title Proxy for updating series.
#' #'
#' @description Allows you to update the series array overriding the existing one. #' @description Allows you to update the series array overriding the existing one.
#' #'
#' @param proxy A \code{apexchartProxy} \code{htmlwidget} object. #' @param proxy A \code{apexchartProxy} \code{htmlwidget} object.
#' @param newSeries The series array to override the existing one. #' @param newSeries The series array to override the existing one.
@ -75,10 +75,10 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' @export #' @export
#' #'
#' @examples #' @examples
#' #'
#' if (interactive()) { #' if (interactive()) {
#' library(shiny) #' library(shiny)
#' #'
#' ui <- fluidPage( #' ui <- fluidPage(
#' fluidRow( #' fluidRow(
#' column( #' column(
@ -88,15 +88,15 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' ) #' )
#' ) #' )
#' ) #' )
#' #'
#' server <- function(input, output, session) { #' server <- function(input, output, session) {
#' #'
#' rv <- reactiveValues() #' rv <- reactiveValues()
#' rv$df <- data.frame( #' rv$df <- data.frame(
#' date = Sys.Date() + 1:20, #' date = Sys.Date() + 1:20,
#' values = sample(10:90, 20, TRUE) #' values = sample(10:90, 20, TRUE)
#' ) #' )
#' #'
#' observe({ #' observe({
#' invalidateLater(1000, session) #' invalidateLater(1000, session)
#' df <- isolate(rv$df) #' df <- isolate(rv$df)
@ -109,17 +109,17 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' ) #' )
#' rv$df <- df #' rv$df <- df
#' }) #' })
#' #'
#' output$chart <- renderApexchart({ #' output$chart <- renderApexchart({
#' # Generate chart once #' # Generate chart once
#' apex(isolate(rv$df), aes(date, values), "spline") %>% #' apex(isolate(rv$df), aes(date, values), "spline") %>%
#' ax_xaxis( #' ax_xaxis(
#' range = 10 * 24 * 60 * 60 * 1000 #' range = 10 * 24 * 60 * 60 * 1000
#' # Fixed range for x-axis : 10 days #' # Fixed range for x-axis : 10 days
#' # days*hours*minutes*seconds*milliseconds #' # days*hours*minutes*seconds*milliseconds
#' ) #' )
#' }) #' })
#' #'
#' observe({ #' observe({
#' # Update chart to add new data #' # Update chart to add new data
#' apexchartProxy("chart") %>% #' apexchartProxy("chart") %>%
@ -128,24 +128,24 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' T #' T
#' ) #' )
#' }) #' })
#' #'
#' } #' }
#' #'
#' shinyApp(ui, server) #' shinyApp(ui, server)
#' } #' }
#' #'
ax_proxy_series <- function(proxy, newSeries, animate = TRUE) { ax_proxy_series <- function(proxy, newSeries, animate = TRUE) {
.ax_proxy2( .ax_proxy2(
proxy = proxy, proxy = proxy,
name = "series", name = "series",
l = list(newSeries = newSeries, animate = animate) l = list(newSeries = newSeries, animate = animate)
) )
} }
#' @title Proxy for updating options #' @title Proxy for updating options
#' #'
#' @description Allows you to update the configuration object. #' @description Allows you to update the configuration object.
#' #'
#' @param proxy A \code{apexchartProxy} \code{htmlwidget} object. #' @param proxy A \code{apexchartProxy} \code{htmlwidget} object.
@ -153,11 +153,13 @@ ax_proxy_series <- function(proxy, newSeries, animate = TRUE) {
#' #'
#' @export #' @export
#' #'
#' @importFrom htmlwidgets JSEvals
#'
#' @examples #' @examples
#' #'
#' if (interactive()) { #' if (interactive()) {
#' library(shiny) #' library(shiny)
#' #'
#' ui <- fluidPage( #' ui <- fluidPage(
#' fluidRow( #' fluidRow(
#' column( #' column(
@ -176,20 +178,20 @@ ax_proxy_series <- function(proxy, newSeries, animate = TRUE) {
#' ) #' )
#' ) #' )
#' server <- function(input, output, session) { #' server <- function(input, output, session) {
#' #'
#' output$chart <- renderApexchart({ #' output$chart <- renderApexchart({
#' apexchart() %>% #' apexchart() %>%
#' ax_chart(type = "bar") %>% #' ax_chart(type = "bar") %>%
#' ax_series(list( #' ax_series(list(
#' name = "Example", #' name = "Example",
#' data = c(23, 43, 76, 31) #' data = c(23, 43, 76, 31)
#' )) %>% #' )) %>%
#' ax_xaxis( #' ax_xaxis(
#' categories = c("Label A", "Label B", #' categories = c("Label A", "Label B",
#' "Label C", "Label D") #' "Label C", "Label D")
#' ) #' )
#' }) #' })
#' #'
#' observe({ #' observe({
#' apexchartProxy("chart") %>% #' apexchartProxy("chart") %>%
#' ax_proxy_options(list( #' ax_proxy_options(list(
@ -201,17 +203,17 @@ ax_proxy_series <- function(proxy, newSeries, animate = TRUE) {
#' ) #' )
#' )) #' ))
#' }) #' })
#' #'
#' } #' }
#' #'
#' shinyApp(ui, server) #' shinyApp(ui, server)
#' } #' }
#' #'
ax_proxy_options <- function(proxy, options) { ax_proxy_options <- function(proxy, options) {
.ax_proxy2( .ax_proxy2(
proxy = proxy, proxy = proxy,
name = "options", name = "options",
l = list(options = options) l = list(options = options, evals = JSEvals(options))
) )
} }
@ -232,8 +234,8 @@ ax_proxy_options <- function(proxy, options) {
#' @example examples/proxy-toggle.R #' @example examples/proxy-toggle.R
ax_proxy_toggle_series <- function(proxy, series_name) { ax_proxy_toggle_series <- function(proxy, series_name) {
.ax_proxy2( .ax_proxy2(
proxy = proxy, proxy = proxy,
name = "toggle-series", name = "toggle-series",
l = list(seriesName = list1(series_name)) l = list(seriesName = list1(series_name))
) )
} }

View File

@ -4,7 +4,7 @@
* https://github.com/dreamRs/apexcharter * https://github.com/dreamRs/apexcharter
* *
*/ */
/*global HTMLWidgets, ApexCharts, Shiny */ /*global HTMLWidgets, ApexCharts, Shiny */
/// Functions /// Functions
@ -19,14 +19,14 @@ var apexcharter = {
} }
return widgetObj; return widgetObj;
}, },
isSingleSerie: function(options) { isSingleSerie: function(options) {
var typeLabels = ["pie", "radialBar", "donut"]; var typeLabels = ["pie", "radialBar", "donut"];
var lab = typeLabels.indexOf(options.w.config.chart.type) > -1; var lab = typeLabels.indexOf(options.w.config.chart.type) > -1;
var single = options.w.config.series.length === 1; var single = options.w.config.series.length === 1;
return lab | single; return lab | single;
}, },
isDatetimeAxis: function(chartContext) { isDatetimeAxis: function(chartContext) {
if ( if (
chartContext.hasOwnProperty("w") && chartContext.hasOwnProperty("w") &&
@ -39,7 +39,7 @@ var apexcharter = {
return false; return false;
} }
}, },
getSelection: function(chartContext, selectedDataPoints, serieIndex) { getSelection: function(chartContext, selectedDataPoints, serieIndex) {
var typeLabels = ["pie", "radialBar", "donut"]; var typeLabels = ["pie", "radialBar", "donut"];
var typeXY = ["scatter", "bubble"]; var typeXY = ["scatter", "bubble"];
@ -79,7 +79,7 @@ var apexcharter = {
} }
return selected; return selected;
}, },
getYaxis: function(axis) { getYaxis: function(axis) {
var yzoom = { min: null, max: null }; var yzoom = { min: null, max: null };
if (typeof axis.yaxis !== "undefined" && axis.yaxis !== null) { if (typeof axis.yaxis !== "undefined" && axis.yaxis !== null) {
@ -98,7 +98,7 @@ var apexcharter = {
} }
return yzoom; return yzoom;
}, },
getXaxis: function(axis) { getXaxis: function(axis) {
var xzoom = { min: null, max: null }; var xzoom = { min: null, max: null };
if (typeof axis.xaxis !== "undefined") { if (typeof axis.xaxis !== "undefined") {
@ -112,7 +112,7 @@ var apexcharter = {
} }
return xzoom; return xzoom;
}, },
exportChart: function(x, chart) { exportChart: function(x, chart) {
if (x.hasOwnProperty("shinyEvents") & HTMLWidgets.shinyMode) { if (x.hasOwnProperty("shinyEvents") & HTMLWidgets.shinyMode) {
if (x.shinyEvents.hasOwnProperty("export")) { if (x.shinyEvents.hasOwnProperty("export")) {
@ -332,10 +332,16 @@ if (HTMLWidgets.shinyMode) {
Shiny.addCustomMessageHandler("update-apexchart-options", function(obj) { Shiny.addCustomMessageHandler("update-apexchart-options", function(obj) {
var chart = apexcharter.getWidget(obj.id); var chart = apexcharter.getWidget(obj.id);
if (typeof chart != "undefined") { if (typeof chart != "undefined") {
chart.updateOptions(obj.data.options); var options = obj.data.options;
var evals = obj.data.evals;
if (!(evals instanceof Array)) evals = [evals];
for (var k = 0; evals && k < evals.length; k++) {
window.HTMLWidgets.evaluateStringMember(options, evals[k]);
}
chart.updateOptions(options);
} }
}); });
// toggle series // toggle series
Shiny.addCustomMessageHandler("update-apexchart-toggle-series", function(obj) { Shiny.addCustomMessageHandler("update-apexchart-toggle-series", function(obj) {
var chart = apexcharter.getWidget(obj.id); var chart = apexcharter.getWidget(obj.id);

View File

@ -18,7 +18,7 @@ Allows you to update the configuration object.
if (interactive()) { if (interactive()) {
library(shiny) library(shiny)
ui <- fluidPage( ui <- fluidPage(
fluidRow( fluidRow(
column( column(
@ -37,20 +37,20 @@ if (interactive()) {
) )
) )
server <- function(input, output, session) { server <- function(input, output, session) {
output$chart <- renderApexchart({ output$chart <- renderApexchart({
apexchart() \%>\% apexchart() \%>\%
ax_chart(type = "bar") \%>\% ax_chart(type = "bar") \%>\%
ax_series(list( ax_series(list(
name = "Example", name = "Example",
data = c(23, 43, 76, 31) data = c(23, 43, 76, 31)
)) \%>\% )) \%>\%
ax_xaxis( ax_xaxis(
categories = c("Label A", "Label B", categories = c("Label A", "Label B",
"Label C", "Label D") "Label C", "Label D")
) )
}) })
observe({ observe({
apexchartProxy("chart") \%>\% apexchartProxy("chart") \%>\%
ax_proxy_options(list( ax_proxy_options(list(
@ -62,9 +62,9 @@ if (interactive()) {
) )
)) ))
}) })
} }
shinyApp(ui, server) shinyApp(ui, server)
} }

View File

@ -20,7 +20,7 @@ Allows you to update the series array overriding the existing one.
if (interactive()) { if (interactive()) {
library(shiny) library(shiny)
ui <- fluidPage( ui <- fluidPage(
fluidRow( fluidRow(
column( column(
@ -30,15 +30,15 @@ if (interactive()) {
) )
) )
) )
server <- function(input, output, session) { server <- function(input, output, session) {
rv <- reactiveValues() rv <- reactiveValues()
rv$df <- data.frame( rv$df <- data.frame(
date = Sys.Date() + 1:20, date = Sys.Date() + 1:20,
values = sample(10:90, 20, TRUE) values = sample(10:90, 20, TRUE)
) )
observe({ observe({
invalidateLater(1000, session) invalidateLater(1000, session)
df <- isolate(rv$df) df <- isolate(rv$df)
@ -51,17 +51,17 @@ if (interactive()) {
) )
rv$df <- df rv$df <- df
}) })
output$chart <- renderApexchart({ output$chart <- renderApexchart({
# Generate chart once # Generate chart once
apex(isolate(rv$df), aes(date, values), "spline") \%>\% apex(isolate(rv$df), aes(date, values), "spline") \%>\%
ax_xaxis( ax_xaxis(
range = 10 * 24 * 60 * 60 * 1000 range = 10 * 24 * 60 * 60 * 1000
# Fixed range for x-axis : 10 days # Fixed range for x-axis : 10 days
# days*hours*minutes*seconds*milliseconds # days*hours*minutes*seconds*milliseconds
) )
}) })
observe({ observe({
# Update chart to add new data # Update chart to add new data
apexchartProxy("chart") \%>\% apexchartProxy("chart") \%>\%
@ -70,9 +70,9 @@ if (interactive()) {
T T
) )
}) })
} }
shinyApp(ui, server) shinyApp(ui, server)
} }