title | author | framework | highlighter | hitheme | mode |
---|---|---|---|---|---|
Embedding rCharts |
Ramnath Vaidyanathan |
minimal |
prettify |
twitter-bootstrap |
standalone |
by Ramnath Vaidyanathan, Dec 22, 2003
This is a short note to address a question from Sharon Machlis on the best way to embed a visualization created using rCharts, so that one can create a standalone HTML file using knit2html
. If you have not used rCharts, you can try it out using the online playground
@ramnath_vaidya Is this still best practice for knit2html to create rCharts file for use off your local machine? TNX! http://t.co/10RfiH9XgG
— Sharon Machlis (@sharon000) December 22, 2013
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
You will need the latest version of rCharts
(> 0.4) to use the approaches suggested in this note.
library(devtools)
install_github("rCharts", "ramnathv")
Let us first create a simple barplot using NVD3
library(rCharts)
hair_eye_male = subset(as.data.frame(HairEyeColor), Sex == "Male")
n1 <- nPlot(Freq ~ Hair, group = 'Eye',
data = hair_eye_male, type = 'multiBarChart'
)
n1$set(width = 600)
We need to set the chunk options comment = NA
and results = "asis"
so that the resulting html is rendered asis and not marked up (which is the default in knitr). Make sure to set cache = F
for this chunk so that it is always run.
library(knitr)
opts_chunk$set(comment = NA, results = "asis", comment = NA, tidy = F)
The first option is to embed the chart as an inline iframe. It has the advantage of keeping the html standalone, but isolating the chart from the html on the page, thereby avoiding css and js conflicts. However, this feature is not supported by IE and Opera.
n1$show('iframesrc', cdn = TRUE)
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js' type='text/javascript'></script>
<script src='http://d3js.org/d3.v3.min.js' type='text/javascript'></script>
<script src='http://timelyportfolio.github.io/rCharts_nvd3_tests/libraries/widgets/nvd3/js/nv.d3.min-new.js' type='text/javascript'></script>
<script src='http://nvd3.org/lib/fisheye.js' type='text/javascript'></script>
<style>
.rChart {
display: block;
margin-left: auto;
margin-right: auto;
width: 600px;
height: 400px;
}
</style>
</head> <body> <div id='chart13be6cad89a5' class='rChart nvd3'></div>
<script type='text/javascript'>
$(document).ready(function(){
drawchart13be6cad89a5()
});
function drawchart13be6cad89a5(){
var opts = {
"dom": "chart13be6cad89a5",
"width": 600,
"height": 400,
"x": "Hair",
"y": "Freq",
"group": "Eye",
"type": "multiBarChart",
"id": "chart13be6cad89a5"
},
data = [
{
"Hair": "Black",
"Eye": "Brown",
"Sex": "Male",
"Freq": 32
},
{
"Hair": "Brown",
"Eye": "Brown",
"Sex": "Male",
"Freq": 53
},
{
"Hair": "Red",
"Eye": "Brown",
"Sex": "Male",
"Freq": 10
},
{
"Hair": "Blond",
"Eye": "Brown",
"Sex": "Male",
"Freq": 3
},
{
"Hair": "Black",
"Eye": "Blue",
"Sex": "Male",
"Freq": 11
},
{
"Hair": "Brown",
"Eye": "Blue",
"Sex": "Male",
"Freq": 50
},
{
"Hair": "Red",
"Eye": "Blue",
"Sex": "Male",
"Freq": 10
},
{
"Hair": "Blond",
"Eye": "Blue",
"Sex": "Male",
"Freq": 30
},
{
"Hair": "Black",
"Eye": "Hazel",
"Sex": "Male",
"Freq": 10
},
{
"Hair": "Brown",
"Eye": "Hazel",
"Sex": "Male",
"Freq": 25
},
{
"Hair": "Red",
"Eye": "Hazel",
"Sex": "Male",
"Freq": 7
},
{
"Hair": "Blond",
"Eye": "Hazel",
"Sex": "Male",
"Freq": 5
},
{
"Hair": "Black",
"Eye": "Green",
"Sex": "Male",
"Freq": 3
},
{
"Hair": "Brown",
"Eye": "Green",
"Sex": "Male",
"Freq": 15
},
{
"Hair": "Red",
"Eye": "Green",
"Sex": "Male",
"Freq": 7
},
{
"Hair": "Blond",
"Eye": "Green",
"Sex": "Male",
"Freq": 8
}
]
if(!(opts.type==="pieChart" || opts.type==="sparklinePlus")) {
var data = d3.nest()
.key(function(d){
//return opts.group === undefined ? 'main' : d[opts.group]
//instead of main would think a better default is opts.x
return opts.group === undefined ? opts.y : d[opts.group];
})
.entries(data);
}
if (opts.disabled != undefined){
data.map(function(d, i){
d.disabled = opts.disabled[i]
})
}
nv.addGraph(function() {
var chart = nv.models[opts.type]()
.x(function(d) { return d[opts.x] })
.y(function(d) { return d[opts.y] })
.width(opts.width)
.height(opts.height)
d3.select("#" + opts.id)
.append('svg')
.datum(data)
.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
};
</script>
</body> </html> ' scrolling='no' seamless></iframe>
<style>iframe{ width: 100%; height: 400px;}</style>This option embeds the chart inline in the html. It should work in all browsers that the charting library being used supports. However, it is susceptible to css and js conflicts.
n1$show('inline', include_assets = TRUE, cdn = TRUE)
if(!(opts.type==="pieChart" || opts.type==="sparklinePlus")) {
var data = d3.nest()
.key(function(d){
//return opts.group === undefined ? 'main' : d[opts.group]
//instead of main would think a better default is opts.x
return opts.group === undefined ? opts.y : d[opts.group];
})
.entries(data);
}
if (opts.disabled != undefined){
data.map(function(d, i){
d.disabled = opts.disabled[i]
})
}
nv.addGraph(function() {
var chart = nv.models[opts.type]()
.x(function(d) { return d[opts.x] })
.y(function(d) { return d[opts.y] })
.width(opts.width)
.height(opts.height)
d3.select("#" + opts.id)
.append('svg')
.datum(data)
.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
};
</script>
This approach does not seem to work with a Morris chart, are you able to suggest any workarounds for that?