rapport icon indicating copy to clipboard operation
rapport copied to clipboard

include an rCharts into a pdf repport

Open danreb25 opened this issue 11 years ago • 1 comments

It's OK to generate html repports (cf https://github.com/Rapporter/rapport/issues/104) that include rCharts objects (tested with Highcharts charts).

But what if we would like to include rCharts generated plots into a pdf file? In other words: can we include iframes withraw html (or inline raw html) in the brew code and produce it in the pdf generated repport?

e.g. in the template we write something like

# test Highcharts
<%=
require(rCharts);
a <- hPlot(Pulse ~ Height, data = MASS::survey, type = "bubble", title = "Zoom demo", subtitle = "bubble chart", size = "Age", group = "Exer");
a <-gfa.rcharts.customiser.addaptLibUrlToLocalEnvironment(a,newPathPart =CST_R_CHARTS_LIBRARY );
myChartId<-  "testRapportrCharts";
myFile<-file.path('I:/Myproject','rchartsOut/');
knitr::opts_current$set(list(fig.path = myFile, label = myChartId))
save_stdout(a$show('iframe', cdn  = TRUE, standalone = TRUE));
%> 

it produces something like the following in the *.md generated file

<iframe src='file:///I:/Myproject/rchartsOut/testRapportrCharts.html' 
class='rChart highcharts '
id=iframe_chart170c37b73e76
></iframe>
<style>iframe.rChart{ width: 100%; height: 400px;}</style>

wich isn't converted in pdf (and no erro , no warnings).

Thanks for your comments

danreb25 avatar Mar 24 '14 02:03 danreb25

my solution at this time (code still needs to be cleaned and re-tested) is deduced from the links anottated in the issue https://github.com/ramnathv/rCharts/issues/385:

N.B.: needs to instal

  • casperjs
  • phantomjs

here is my template code

<%
# --------------------------------------------
# function definition
# --------------------------------------------
gfa.rcharts.customiser.addaptLibUrlToLocalEnvironment<-function (
        rChart=NULL
        ,oldPathPart=paste("C:/Program Files/R/R-",paste(R.version$major,R.version$minor,sep='.'),"/library/rCharts/libraries",sep="")
        ,newPathPart=file.path( "..","libraries/rCharts/libraries") 
){
    rChart$LIB$url<-gsub(oldPathPart,newPathPart,rChart$LIB$url,fixed = TRUE);
    return (rChart);
}

save_stdout <- function(x){
    paste(capture.output(x), collapse = '\n')
}

gfa.rcharts.save.wrapper <- function (myRchart=a,  myChartName=NULL , myDestDir=file.path(MY_SLIDIFY_PROJECT_DIR,'rchartsOut') ,withImage=F
                , with_relative_paths=F
                , showMethod=NULL
                ) {

    result<-NULL;

    #on s'assure qu'il n'y ait pas d'extention au nom de fichier                        
    myChartName<-tools::file_path_sans_ext(myChartName)

    # verification/creation du repertoire de destination
    if (!file.exists( myDestDir)){
        dir.create(myDestDir,showWarnings = FALSE);
    }

    destfile<-file.path(myDestDir,paste(myChartName,'.html',sep=''));

    # sauvegarde du fichier
    myRchart$save(  destfile = file.path(destfile));

    #generation d'une image si necessaire
    if (withImage){
        imgFilePath<-gfa.rcharts.save.take_screenshot (src=destfile, imgname = myChartName, delay = 10000, upload = F,isURL=F , dirOut=myDestDir);
        result<-imgFilePath;

    }

    # specific show methods?
    if (!is.null(showMethod)){
        require('knitr');
        switch (showMethod,
                iframe={        
                    knitr::opts_current$set(list(fig.path = myDestDir, label = myChartName));
                    result<-gfa.console.utils.save_stdout(a$show('iframe', cdn  = TRUE, standalone = TRUE));
                },
                inline={        
                    knitr::opts_current$set(list(fig.path = myDestDir, label = myChartName));
                    result<-gfa.console.utils.save_stdout(a$show('inline', include_assets = TRUE, standalone = TRUE)) # OK
                },
                {#default
                    print( paste('gfa.rcharts.save.wrapper function executed with [',showMethod,'] showMethod parameter, hence the show methods is nott executed' , sep =" ")  )
                    result<-NULL;
                }
        );
    }
    return(result);
}

#' Automate screenshot of an rChart, optionally upload it to imgur
#'  addapted from https://github.com/ramnathv/rCharts/blob/b6246d3a4a47c26a8c1023178a83a4e35959bd2c/R/makeExamples.R
#' @param path to R file containing code to create an rChart
#' @param imgname name of the plot to save to
#' @return generated image path
#' Necessite l'installation de phantomjs et de casperjs et de ImageMagick
#' Example : gfa.rcharts.save.take_screenshot(mydestfile, tools::file_path_sans_ext(myChartId));
gfa.rcharts.save.take_screenshot <- function(src, imgname = 'plot1', delay = 10000, upload = F,isURL=F,dirOut=NULL){

    if (tools::file_ext(src) %in% c('r', 'R')){
        rCode = paste(readLines(src, warn = F), collapse = "\n");
        chart = source(src, local = TRUE)$value;
        chart$set(width = 600, height = 325);
        tf <- tempfile(fileext = ".html"); on.exit(unlink(tf));
        chart$save(tf);
    } else {
        if (isURL){
            tf <- src;
        }else {
            tf <- paste('file:///',src,sep='');
        }
    }

    if (is.null(dirOut )){
        wd<-getwd();
    }
    else {
        wd<-dirOut;
    }
    generatedImgFilePath<-file.path(wd , paste(imgname,'.png',sep="") );

    # the original needs to be copied into a location whitout spaces in the path
#   file.copy(from= system.file('utils', 'screenshot.js', package = 'rCharts')
#           , to=file.path( .ROOT,'js','screenshot.js')
#           ,overwrite  = TRUE);
    #script = system.file('utils', 'screenshot.js', package = 'rCharts')
    # at this time I am using a custom script to be sure about the image generation directory
    # until https://github.com/ramnathv/rCharts/issues/387 is taken into account
    script = file.path( .ROOT,'js','screenshot.js');
    cmd1 <- sprintf('casperjs %s %s %s %s %s', script, tf, imgname, delay,wd);
    system(cmd1);

    #cmd2 <- sprintf('convert -flatten %s.png %s.png', imgname, imgname)
    # TODO , je vois pas a quoi ca peut servir??? sauf s'il s'agit de faire une modif format?
    cmd2 <- sprintf('convert -flatten %s.png %s.png', file.path(wd ,imgname ), file.path(wd,imgname  ));
    system(cmd2);
    # system(sprintf("convert %s.png -resize 288x172", file.path(wd ,imgname )))
    if (upload){
        h = knitr:::imgur_upload(paste0(imgname, '.png'));
        return(h[1]);
    } else {
        #return(imgname)
        return(generatedImgFilePath);
    }
}
%>

<!--
============================================
Template generation code
============================================
-->

# test Highcharts
<%=
#https://github.com/ramnathv/rCharts/issues/373
require(rCharts);
a <- hPlot(Pulse ~ Height, data = MASS::survey, type = "bubble", title = "Zoom demo", subtitle = "bubble chart", size = "Age", group = "Exer");
a <-gfa.rcharts.customiser.addaptLibUrlToLocalEnvironment(a,newPathPart =CST_R_CHARTS_LIBRARY );

myChartId<-  "testRapportrCharts";
myFile<-file.path(fRp,'rchartsOut');

if (isForPdf){
    # sauvegarde avec image
    gfa.rcharts.save.wrapper ( myRchart = a,myChartName = myChartId,myDestDir = myFile,withImage = isForPdf);
}else{
    gfa.rcharts.save.wrapper ( myRchart = a,myChartName = myChartId,myDestDir = myFile,withImage = F,showMethod='iframe');
}

%> 

danreb25 avatar Mar 24 '14 23:03 danreb25