ramnathv / rcharts Goto Github PK
View Code? Open in Web Editor NEWInteractive JS Charts from R
Home Page: http://rcharts.io
License: Other
Interactive JS Charts from R
Home Page: http://rcharts.io
License: Other
Many of the JS charting libraries use functions to handle formatting and other interactions. Now, converting R objects to a payload invokes toJSON
which transforms everything into JSON objects, which are quoted.
I had several ideas on how to handle this.
"function(...){...}"
and removes the quotes using regex manipulation.addFunction
method to the rCharts class, and return an object called jsFunctions
in the payload, which is a list of functions. These functions can be referred to in the main payload, however I would still face the issue of having to unquote those objects.eval
on function objects.Hi,
I try to understand how programmatic approach work starting from trying to mimic polar graph for HighCharts (http://www.highcharts.com/demo/polar-spider)
I can see the huge refactoring work to gather all JS libraries into one framework and see the rPlot function.
Though, with the current state of documentation, I don't see how to start from rPlot.
So I started to investigate directly to HighChart layer and tried:
x=data.frame("S1"=c(9,8,9,1,3),"S2"=c(7,3,7,6,4))
rownames(x)=paste("factor",rownames(x))
a=rCharts:::Highcharts$new()
a$addParams(width = 550)
a$chart(type='line',polar=TRUE)
a$pane(size='80%')
a$title(text='Polarize-It',x=-80)
a$xAxis(categories=rownames(x),tickmarkPlacement='on',lineWidth=0)
a$yAxis(gridLineInterpolation='polygon',lineWidth=0,min=0)
a$data(x,pointPlacement='on')
a$printChart("testPolar")
Error in file(con, "r") : invalid 'description' argument
Can you help: what should be corrected?
Thank you,
Eric
PS: no pressure but I am really working on your sample gallery
When replicating http://www.polychartjs.com/demo?favourite_pet, I realized that no x is a potential scenario for polycharts when doing a pie chart. As far as I can tell x is required by rCharts. I tried to hack around it but could not find a good solution.
code to replicate:
data = list(
name=c('Lisa', 'Samson', 'Fravic', 'Zach', 'Raymond', 'Tim'),
pet=c('cat', 'dog', 'cat', 'cat', 'dog', 'none')
)
p12 <- rPlot(y = "count(name)", color="pet", data = data, type = "bar")
p12$coord(type="polar")
p12$guides(x = list(position = "none", padding = 0), y = list(position = "none"))
p12$show()
in the rCharts object render reads
chartDiv = sprintf("<div id='%s' class='rChart nvd3Plot'></div>", chartId)
now with all the types should it just be rChart, or should there be logic to fill based on javascript library?
I thought it would be cool if the reference class could log all the calls made, thereby making it easy to recreate a plot. @hadley provided a concise answer on SO and here is a proof-of-concept making use of the idea.
The variable foo$calls
contains a list of all the calls made. Since, I don't want the function to log calls when an xPlot
function is called, I will need an extra flag argument, that defaults to TRUE, but can be set to FALSE, to prevent logging of these calls inside the xPlot
function.
This is just a proof-of-concept and I need to make sure it is robust enough before pushing it out.
Foo <- setRefClass('Foo', fields = list(params = 'list', calls = 'list'),
methods = list(
bar1 = function(...){
params$bar1 <<- list(...)
calls <<- c(calls, list(match.call()))
},
bar2 = function(...){
params$bar2 <<- list(...)
calls <<- c(calls, list(match.call()))
}
))
foo = Foo$new()
foo$bar1(x = 1, y = 2)
foo$bar2(x = 1, y = 4)
R version 2.15.3 (2013-03-01)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] whisker_0.3-2 devtools_1.1 downloader_0.2.2 df2json_0.0.2 rjson_0.2.12
[6] clickme_0.1.0 reshape2_1.2.2 xtsExtra_0.0-1 xts_0.9-3 zoo_1.7-9
[11] rCharts_0.1.1 slidify_0.3.3
loaded via a namespace (and not attached):
[1] digest_0.6.3 evaluate_0.4.3 formatR_0.7 grid_2.15.3 httr_0.2
[6] knitr_1.2 lattice_0.20-15 markdown_0.5.4 memoise_0.1 parallel_2.15.3
[11] plyr_1.8 RCurl_1.95-4.1 stringr_0.6.2 tools_2.15.3 yaml_2.1.7
The use case is when I want to pass JS objects in my JSON payload. My current approach is to enclose JS objects between #!
and !#
tags, and use a regular expression to remove the quotes. Here is an example.
x = list(tickFormat = "#! function(d) {
return d3.time.format('%Y-%m-%d')(new Date(d))
} !#"
I have a function toObj
that destringifies contents within special markup tags.
toObj <- function(x){
gsub('\"#!(.*)!#\"', "\\1", x)
}
So essentially, I would do something like toObj(toJSON(x))
. There are three cases.
The first case is what I am doing now, using rjson::toJSON
cat(toObj(rjson::toJSON(x)))
{"tickFormat": function(d) {\n return d3.time.format('%Y-%m-%d')(new Date(d))\n} }
The second case is using RJSONIO::toJSON
, but not invoking the .escapeEscapes
option.
cat(toObj(RJSONIO::toJSON(x)))
{
"tickFormat": function(d) {\n return d3.time.format('%Y-%m-%d')(new Date(d))\n}
}
If I use the .escapeEscapes = F
option in RJSONIO::toJSON
, I get exactly what I want.
{
"tickFormat": function(d) {
return d3.time.format('%Y-%m-%d')(new Date(d))
}
}
So, I think it makes sense to switch to RJSONIO.
I am guessing another Windows issue, but runExample does not work.
tempfile(pattern = '*.R')
[1] "C:\Users\KENT~1.TLE\AppData\Local\Temp\RtmpOswwy0*.R32c1e702e82"
Not sure if this messes other OSes but this changes fixes it.
tempfile( fileext = '.R')
Right now I have examples.R which tests different type of charts. However, I need to do this more systematically with a test suite that tests different aspects. Here is an example for MorrisJS
dat = subset(haireye, Sex == "Female")
## test that labels default to group names when not provided
p2 <- mPlot(Freq ~ Eye, group = "Hair", data = dat, type = "Bar")
p2$show(T)
## test that label argument is respected when explicitly provided
p3 <- mPlot(Freq ~ Eye, group = "Hair", data = dat, type = "Bar",
labels = letters[1:4])
p3$show(T)
Here is the idea
PolyChart$methods(printChart = function(chartId = NULL){
chart_div = sprintf("<div id='%s' class='rChart'></div>", chartId)
writeLines(c(chart_div, .self$html(chartId)))
}
I like the idea of using gists, since they have a simpler structure than a full fledged repo, have multiple viewer sites and are easy to handle.
Here is an example of a gist rendered using http://gistview.github.io/#21fdcdfe86a2b886fa0d
I think it would be good to make chart types consistent across libraries. This can be achieved using a combination of a translation dictionary and guess work based on the dataset.
For example type = "bar"
for NVD3 libraries should be interpreted as discreteBarChart
if there is no grouping variable and as multiBarChart
if there is a grouping variable. Similarly, type = "point"
should become scatterChart
etc.
I am thinking I should make static = T
the default for the show method. The idea is that it is annoying to have to close the shiny server after every call to view the chart.
My earlier rationale to use static = F
was directed at cases where the data is in an external JSON file and has to be read in using AJAX, which will work only with a server. However, currently, data is inline in the HTML, so a server is really not required.
I could control the static
variable based on whether a server is required or not, when I implement the external data file idea referred to in the issues list here.
can we add the ability to pass meta to polycharts? I believe it is fairly easy by changing the layout chart.html from
el.data = polyjs.data(el.data)
to
el.data = polyjs.data(el.data, el.meta)
So far, the following libraries work great.
Rickshaw uses a different div for each component of the plot. This makes things a little trickier in rChart.html
. One idea is to initialize it in the master rCharts class (as say chartDiv), and override it in the child classes. This way, only those libraries, which required a different setup like Rickshaw, will need to redefine it.
This is straightforward to implement, but requires careful work. So, I will table it till I sort out other refactoring issues.
<div id="{{{ params.dom }}}" class='Rickshaw'></div>
<div id="yAxis{{{ params.dom }}}" class='Rickshaw'></div>
The best way to provide examples is to relate them to something users understand. Given the popularity of ggplot2
, it makes complete sense to replicate the plots here on the R Cookbook.
This would also help me tweak the UI for PolyCharts, since it is essentially built on the Grammar of Graphics approach. The idea would be to keep the UI as close as possible to ggplot2, so that users can easily adopt the same in their workflows.
readme.md lists rHighcharts twice. One should be rVega.
I want to use the same strategy I am using with SlidifyLibraries.
slidifyLibraries/libraries
.slidifyLibraries/inst/libraries
.The key step that messes me up is that I tend to fiddle around with config.yml and layouts in slidifyLibraries/inst/libraries
. This renders the copy in the main repo outdated and as a result running the makefile might leave me hanging with an older version of these files.
I need to add a note to clean up slidifyLibraries
by going through the timestamps on the files so that I am using the most recent copy of all files.
The show
method uses system(sprintf("open %s", tf))
to open a browser. I get the error "Couldnt get a file descriptor referring to the console". If I use xdg-open
instead of open
everything works correctly. Am I doing something wrong? Or perhaps is it safer to use xdg-open instead of open?
Thanks for your package!
Oscar
I cannot make a plot with rCharts work in a self-hosted Wordpress installation blog work.
I have included the following before the </head>
<script
src="https://raw.github.com/Polychart/polychart2/develop/polychart2.standalone.js">
</script>
<style>
.rChart {
display: block;
margin-left: auto;
margin-right: auto;
width: 900px;
height: 500px;
}
</style>
and then I only replicated a graph of your example in the body of the post.
As much as I hate pie charts and donut charts because a bar chart can convey the same idea more succinctly, they do have some visual appeal, and provide some piazzaz to an otherwise boring infodeck.
Here is some code showing the construction of a faceted pie chart in PolychartJS
var data = polyjs.data({
data: [
{grade: "Grade 9", percent: 10, completed: 'Yes'},
{grade: "Grade 9", percent: 90, completed: 'No'},
{grade: "Grade 10", percent: 40, completed: 'Yes'},
{grade: "Grade 10", percent: 60, completed: 'No'},
{grade: "Grade 11", percent: 70, completed: 'Yes'},
{grade: "Grade 11", percent: 30, completed: 'No'},
{grade: "Grade 12", percent: 90, completed: 'Yes'},
{grade: "Grade 12", percent: 10, completed: 'No'}
],
meta: {
grade: { type: 'cat' },
percent: { type: 'num' },
completed: { type: 'cat' }
}
});
polyjs.chart({
title: 'Percent of Students Completing Volunteer Requirement',
dom: 'chart',
width: 720,
height: 230,
layer: {
data: data,
type: 'bar',
y: 'percent',
color: 'completed'
},
guides: {
x: {position: 'none', padding: 0},
y: {position: 'none'},
color: {
scale: function(value) {
return value === 'Yes' ? '#62bf9c' : '#DDD';
}
}
},
coord: {
type: 'polar'
},
facet: {
type: 'wrap',
'var': 'grade',
cols: 4,
formatter: function(index) {
return index.grade;
}
}
});
It would be nice to add a gallery to the wiki section, similar to the D3 gallery. Users may then easily publish code examples to RPubs, which could be added to the gallery.
I have put up a prototype, see: https://github.com/reinholdsson/rCharts/wiki/Gallery.
What do you think? Would also be nice if there are a more automatized way of creating the thumbnails, other than using print screen.
@nachocab will be the most helpful in this discussion, but I know he is buried in PHD stuff currently. I'll try to comment based on my own understanding of the spirit of clickme. In terms of create_chart, this almost replaces clickme for this limited functionality in that
{{ create_chart(file.R) }}
could be the entire template.Rmd. This might be still be in the spirit of clickme if you added the ability to pass parameters in create_chart like
{{ create_chart(file.R, {{opts$data}} ) }}
but I think is is a stretch.
Rather I think the more useful function to integrate clickme and rCharts is the method
$printChart()
$html()
as this allows us to include the div+script or the script in a template.Rmd through a {{ functiontorun_rCharts(opts) }} type call. I will work on a minimal example and hope to post in the next 30 minutes.
Here is an example that does not work
p2 <- rPlot(~ time, color = 'sex', data = tips, type = 'bar')
The problem is that when the y variable is missing, the data frame is run through count
to compute the frequency automatically. It does not take into account other aesthetics like color, facet, etc.
I have implemented publishing as a gist using the Github API for basic authorization. One issue though is that my current workflow generates a new token every time I publish. I don't think this is desirable, as it results in many many tokens.
The solution I think is to save a token the first time it is generated, and use it as long as it is available and works. If rCharts can't find it, a new token will be generated.
So the natural question is where to save the token in a way that is safe and persists across sessions.
I need a nice template for examples. The idea would be to take an R file with source code for generating a chart, along with a few themable options and producing a standalone html page that can be published. A sample design is shown below
The page would include the chart, along with the source code used to produce it. In addition, a user can provide a README, which will appear in the sidebar. Other optional elements are a title and subtitle.
Of all the very useful functions in the R PerformanceAnalytics package, I would guess that charts.PerformanceSummary is probably the most used. I spot in the wild almost daily and use it myself often hourly. In my post plot.xts is wonderful, I recreated it using the new xtsExtra package. While I like that result, a d3 or other javascript version would provide a very helpful level of interactivity.
rCharts is still very early in development, but given the author's wonderful slidify package and very conscientious efforts, I do not hesitate to go ahead and put it to use. So far, rCharts provides a R lattice-like interface for NVD3, polychart2, highcharts, morris, and incomplete xcharts. Let's test it out by creating a basic charts.PerformanceSummary with rCharts polycharts.
biggest issue I have is what I think is the inability to do lattice scale relation="free"
I guess the best way around this if it really is a limitation
is to create 2 plots much like the http://www.polychartjs.com/demo?interactive example
however I need to make sure this is even possible in R
I also am having trouble getting the tooltips to properly display the date
imagine this is fairly easy and I am just missing it.
#uncomment these if you have not installed rCharts and you are comfortable using a development package
#require(devtools)
#install_github('rCharts', 'ramnathv')
require(PerformanceAnalytics)
require(rCharts)
data(managers)
managers.cumul <- cumprod(1+managers[,c(1,8,9)])
managers.drawdown <- Drawdowns(managers[,c(1,8,9)])
xtsMelt <- function(xtsData,metric){
df <- data.frame(index(xtsData),coredata(xtsData),stringsAsFactors=FALSE)
df.melt <- melt(df,id.vars=1)
df.melt <- data.frame(df.melt,rep(metric,NROW(df.melt)))
#little unnecessary housekeeping
df.melt <- df.melt[,c(1,2,4,3)]
colnames(df.melt) <- c("date","indexname","metric","value")
df.melt$date <- as.Date(df.melt$date)
return(df.melt)
}
managers.melt <- rbind(xtsMelt(managers.cumul,"CumulGrowth"),xtsMelt(managers.drawdown,"Drawdown"))
managers.melt$metric <- factor(managers.melt$metric,levels=c("Drawdown","CumulGrowth"))
xyplot(value~date|metric,groups=indexname,data=managers.melt,
type="l",
layout=c(1,2),
scales=list(x=list(tck=c(1,0)),y=list(relation="free")),
xlab=NULL, ylab=NULL)
#remove troublesome . using modified method from this Stack Overflow
#http://stackoverflow.com/questions/2851015/convert-data-frame-columns-from-factors-to-characters
i <- sapply(managers.melt, is.factor)
managers.melt[i] <- lapply(managers.melt[i], gsub, pattern="\\.", replacement="")
#get date as text
managers.melt$date <- format(managers.melt$date,"%Y-%m-%d")
p1 <- rPlot(value ~ date, data = managers.melt, color = 'indexname', type = 'point', size=list(const=1), height = 500)
#p1$set( verticalSpacing = 25 )
p1$set( legendPosition = "top" )
p1$facet(type= "wrap",var="metric",cols=1,formatter="function(object) {return object.metric;}")
p1$html()
cat(p1$render())
p1$show()
biggest issue is the lack of facetting which will also require combining two separate charts
to accomplish the simultaneous viewing of CumulGrowth and Drawdown
using two y scales does not work in this instance unfortunately
#uncomment these if you have not installed rCharts and you are comfortable using a development package
#require(devtools)
#install_github('rCharts', 'ramnathv')
require(PerformanceAnalytics)
require(rCharts)
data(managers)
managers.cumul <- cumprod(1+managers[,c(1,8,9)])
managers.drawdown <- Drawdowns(managers[,c(1,8,9)])
xtsMelt <- function(xtsData,metric){
df <- data.frame(index(xtsData),coredata(xtsData),stringsAsFactors=FALSE)
df.melt <- melt(df,id.vars=1)
df.melt <- data.frame(df.melt,rep(metric,NROW(df.melt)))
#little unnecessary housekeeping
df.melt <- df.melt[,c(1,2,4,3)]
colnames(df.melt) <- c("date","indexname","metric","value")
df.melt$date <- as.Date(df.melt$date)
return(df.melt)
}
managers.melt <- rbind(xtsMelt(managers.cumul,"CumulGrowth"),xtsMelt(managers.drawdown,"Drawdown"))
managers.melt$metric <- factor(managers.melt$metric,levels=c("Drawdown","CumulGrowth"))
xyplot(value~date|metric,groups=indexname,data=managers.melt,
type="l",
layout=c(1,2),
scales=list(x=list(tck=c(1,0)),y=list(relation="free")),
xlab=NULL, ylab=NULL)
#remove troublesome . using modified method from this Stack Overflow
#http://stackoverflow.com/questions/2851015/convert-data-frame-columns-from-factors-to-characters
i <- sapply(managers.melt, is.factor)
managers.melt[i] <- lapply(managers.melt[i], gsub, pattern="\\.", replacement="")
n1 <- nvd3Plot(value ~ date,
group = 'indexname',
data = managers.melt[which(managers.melt$metric=="CumulGrowth"),],
type = 'lineChart')
#n1$yAxis(tickFormat='d3.format(\",.2f\")',replace=T)
n1$show()
Another good test would be to replicate the examples provided in the libraries. I started on polycharts.
require(quantmod)
require(reshape2)
require(rCharts)
DJIA <- na.omit(getSymbols("DJIA",src='FRED',auto.assign=FALSE)["2012-12-04::2013-03-10"])
xtsMelt <- function(xtsData,metric,names=NULL){
df <- data.frame(index(xtsData),coredata(xtsData),stringsAsFactors=FALSE)
df.melt <- melt(df,id.vars=1)
df.melt <- data.frame(df.melt,rep(metric,NROW(df.melt)))
#little unnecessary housekeeping
df.melt <- df.melt[,c(1,2,4,3)]
if(is.null(names)) {
colnames(df.melt) <- c("date","indexname","metric","value")
} else {colnames(df.melt) <- names}
df.melt[,1]<- as.Date(df.melt[,1])
return(df.melt)
}
DJIA.melt <- xtsMelt(DJIA,"price",names=c("Date","Index","Metric","Close"))
DJIA.melt[,1] <- format(DJIA.melt[,1],"%m/%d/%Y")
p1 <- rPlot(Close ~ Date, data = DJIA.melt,
type="line",
size=list(const=3))
p1$guides(x=list(numticks=10),y=list(min=12000,max=15000))
p1$set(title = "Dow Jones Daily Closing Value")
p1$show(F)
browsershare <- read.csv("http://gs.statcounter.com/chart.php?statType_hidden=browser®ion_hidden=ww&granularity=monthly&statType=Browser®ion=Worldwide&fromMonthYear=2008-07&toMonthYear=2013-03&csv=1")
browsershare.melt <- melt(browsershare,id.vars=1)
colnames(browsershare.melt)[c(2,3)] <- c("Browser","Share")
p3 <- rPlot(Share ~ Date, color = "Browser",
data=browsershare.melt,
size=list(const=3),
type="line")
p3$set(title="Browser Shares Over Time")
p3$show()
osshare <- read.csv("http://gs.statcounter.com/chart.php?statType_hidden=os®ion_hidden=ww&granularity=monthly&statType=Operating%20System®ion=Worldwide&fromMonthYear=2008-07&toMonthYear=2013-03&csv=1",stringsAsFactors=FALSE)
#if we wanted to sort by last value
#osshare <- osshare[,c(1,order(last(osshare[,-1]),decreasing=TRUE)+1)]
#osshare.melt <- read.csv("http://www.polychartjs.com/s/data/OSStatistics.csv")
osshare.melt <- reshape2::melt(osshare,id.vars=1)
colnames(osshare.melt)[c(2,3)] <- c("OS","Share")
p4 <- rPlot(y="Share",x="Date", color = "OS", #could do Share ~ Date
data=osshare.melt,
size=list(const=3),
opacity=list(const=0.7),
type="area",
height=500)
#demonstrate how we can change axis and legend titles
p4$guides(color=list(numticks=10,title="Oper System"),y=list(title="Market Share"))
p4$set(title="OS Market Shares Over Time")
p4$show()
data(iris)
colnames(iris) <- sapply(colnames(iris), FUN=gsub, pattern="\\.", replacement="")
p5 <- rPlot(SepalWidth ~ SepalLength, data = iris, color = "Species", type="point", height=400)
#again match polychartjs example exactly to show how we can change axis and legend titles
p5$guides(color=list(title="Category"),y=list(title="sepalWidth"),x=list(title="sepalLength"))
p5$set(title="Iris Flowers")
p5$html()
p5$show()
jsondata = data.frame(
c("The Fellowship of the Ring","The Two Towers","The Return of the King","The Hobbit"),
c(871530000, 926047000, 1119929000, 949541000)
)
colnames(jsondata) <- c("movie","gross")
p7 <- rPlot(gross ~ movie, data = jsondata, type = "bar", color=list(const="darkgreen"))
p7$set(title = "Lord of the Rings Box Office Gross")
p7$html()
p7$show()
names = c('Joe', 'Jay', 'Jen', 'Jane', 'John', 'Jone', 'Jake', 'Jule', 'Jack')
height = c(1.62, 1.63, 1.71, 1.66, 1.79, 1.58, 1.55, 1.62, 1.72) #actually error in example, 1.63)
data = data.frame(names,height)
p8 <- rPlot(x="bin(height,0.05)", y="count(names)", data=data, type="bar")
p8$guides(x=list(title="Height in Meters"), y=list(title="Density"))
p8$set(title = "Histogram of Heights")
p8$html()
p8$show()
jsondata = data.frame(rbind(
c('Floyd Mayweather', 85000000, 'Boxing'),
c('Manny Pacquaio', 62000000, 'Boxing'),
c('Tiger Woods', 59400000, 'Golf'),
c('LeBron James', 53000000, 'Basketball'),
c('Roger Federer', 52700000, 'Tennis'),
c('Kopaye Bryant', 52300000, 'Basketball'),
c('Phil Mickelson', 47800000, 'Golf'),
c('David Beckham', 46000000, 'Soccer'),
c('Cristiano Ronaldo', 42500000, 'Soccer'),
c('Peyton Manning', 42400000, 'Football'))
)
colnames(jsondata) <- c("name","pay","sport")
p9 <- rPlot(x = list(var="name", sort="pay"), y = "pay", data = jsondata, color = "sport",type = "bar" )
p9$guides(y = list(title = "Athlete Pay (in $)"), x = list(title = "Name of Athlete", numticks = 10), color = list(title = "Type of Sport"))
p9$coord(type = "cartesian", flip = "true")
p9$set(title= "Top 10 Highest Paid Athletes 2012")
p9$html()
cat(p9$render())
p9$show()
data = data.frame(list(
segment=c(
"FirstTime", "FirstTime", "FirstTime", "Return", "Return", "Return",
"Sale", "Sale", "Sale"
),
source= c(
"Referral", "LinkedIn", "Cold Call","Referral", "LinkedIn", "Cold Call",
"Referral", "LinkedIn", "Cold Call"
),
value= c(10,15,20,5,10,18,3,5,8)
))
p10 <- rPlot(x = list(var = "segment", sort = "sum(value)", desc = "true"),
y = "value",
data = data,
color = "source",
type = "bar",
height = 200,
width = 720)
p10$guides(x = list(renderLine = "false", renderTick = "false", renderLabel = "true", renderGrid = "false"),
y = list(position = "none"))
p10$coord(type = "cartesian", flip = "true")
p10$set(title = "Sales Funnel")
p10$show()
data = list(
names = c('Joe', 'Jay', 'Jessica', 'Mayfield', 'Candice', 'Alice'),
department = c('Sales', 'Sales', 'IT', 'IT', 'HR', 'HR'),
salary = c(100000, 98000, 110000, 50000, 55000, 80000)
)
p11 <- rPlot(salary ~ department, color = 'names', data = data, type = "bar", position = "dodge")
p11$set(title = "Department Salaries")
p11$show()
data = list(
name=c('Lisa', 'Samson', 'Fravic', 'Zach', 'Raymond', 'Tim'),
pet=c('cat', 'dog', 'cat', 'cat', 'dog', 'none')
)
p12 <- rPlot(y = "count(name)", x="pet", color="pet", data = data, type = "bar")
p12$coord(type="polar")
p12$guides(x = list(position = "none", padding = 0), y = list(position = "none"))
p12$show()
p13
data=data.frame(
c( "Grade 9", 10, 'Yes'),
c( "Grade 9", 90, 'No'),
c( "Grade 10", 40, 'Yes'),
c( "Grade 10", 60, 'No'),
c( "Grade 11", 70, 'Yes'),
c( "Grade 11", 30, 'No'),
c( "Grade 12", 90, 'Yes'),
c( "Grade 12", 10, 'No')
)
colnames(data) <- c("grade","percent","completed")
p14 <- rPlot(width = 720, height = 230,
y = "percent", color = "completed", data = data)
p14$guides(x=list(position="none", padding=0),
y=list(position="none"),
color(scale = 'function(value) {return value === 'Yes' ? "#62bf9c" : "#DDD"'))
p14$coord(type="polar")
p14$facet(type="wrap", var=list(grade), cols=4, formatter='function(index){return index.grade}')
p14$set(title = "Percent of Students Completing Volunteer Requirement")
p14$show()
## Use InsectSprays Data since Polychart Example is Fake Data
data(InsectSprays)
#boxplot(count~spray, data=InsectSprays, col="lightgray")
p15 <- rPlot(width=720,
x = "spray",
y = "box(count)",
data = InsectSprays,
type = "box")
p15$guides(x=list(min=0, max=110))
p15
data(iris)
colnames(iris) <- sapply(colnames(iris), FUN=gsub, pattern="\\.", replacement="")
p16 <- rPlot(height = 400,
width = 720,
x = "bin(SepalLength, 1)",
y = "bin(SepalWidth, 0.5)",
color = "mean(PetalWidth)",
data = iris,
type = "tile")
p16$guides(color = list(scale = list(type="gradient", lower = "#EEE", upper = "#a23")))
p16$facet(type="wrap",var="Species" ) #,formatter='function(object) { return object.category }')
p16$set(title = "Iris Flowers")
p16
p17
data(iris)
colnames(iris) <- sapply(colnames(iris), FUN=gsub, pattern="\\.", replacement="")
p18 <- rPlot(width = 720,
height = 300,
x = "SepalLength",
y = "SepalWidth",
color = "Species",
data = iris,
type = "point")
p18$facet(type = "wrap", var = "Species")
p18$set(title = "Iris Flowers")
p18
It would be a good idea to sanitize variable names passed on as a JS object. Especially, the periods. This should be relatively straightforward to do inside getLayer
.
rChart.html css overrides height and width assigned with rPlot when rPlot$show(). Is there a way to use the height and width provided in the rPlot specification? Mainly important when doing facetted polycharts plots.
When I run create_chart or $show(T), I get the following error:
file association for 'C:\Users\KENT~1.TLE\AppData\Local\Temp\Rtmp4EKTH8\file2b7471735b47html' not available or invalid
Warning message:
running command 'open C:\Users\KENT~1.TLE\AppData\Local\Temp\Rtmp4EKTH8\file2b7471735b47html' had status 63
It appears that I am losing a . in my file. I verified that the file exists and is just missing the . between file and extension. I'm not sure if this is a personal problem or possibly an error with Windows 7.
It appears to be with R tempfile.
> tempfile(fileext = "html")
[1] "C:\\Users\\KENT~1.TLE\\AppData\\Local\\Temp\\Rtmp4EKTH8\\file2b747baa1770html"
> tempfile(fileext = ".html")
[1] "C:\\Users\\KENT~1.TLE\\AppData\\Local\\Temp\\Rtmp4EKTH8\\file2b741a4f5d5d.html"
so the fix seems simple unless it affects behavior on other OSes.
This here is a great example of how to do a tutorial explaining the charting functions of a library. I can create a slidify layout that captures this flow and use it to create tutorials for each JS library I include.
For starters, it would be useful to recreate the tutorial for Rickshaw using rCharts, which would also help me implement functionality that is currently dormant.
Another nice example for Sidebar: http://www.chartjs.org/docs/
This is a cool tutorial showing how to use reactive.js a javascript library that supports reactivity (just like shiny) to control d3.js like charts.
It looks really easy to use, and might only require some book-keeping code to use with rCharts. A huge advantage of using reactive.js
over shiny is that the application can be viewed on any server.
It appears to me that http://glimmer.rstudio.com/ramnathv/rChartApp/ seems to be broken at the moment.
As well I can't get the "rCharts: Interactive Charts from R using polychart.js" example working with your server.r and ui.r, but I really don't know what I'm doing. I end up with:
Error in if (!grepl("^[a-z][a-z0-9-_]*$", prefix, ignore.case = TRUE, :
argument is of length zero
traceback()
25: addResourcePath(lib, system.file(lib, package = package))
24: singleton(addResourcePath(lib, system.file(lib, package = package)))
23: withCallingHandlers(expr, message = function(c) invokeRestart("muffleMessage"))
22: suppressMessages(singleton(addResourcePath(lib, system.file(lib,
package = package)))) at showOutput.R#25
21: getAssets(lib, package)
20: tagList(getAssets(lib, package))
19: tag("div", list(...))
Currently, all data is written inline in the HTML file. While this behavior is desirable by default, there are situations where it might be better to save the data as a json/csv
file, and then use d3.json
or one of the many reader functions to read the data in the HTML file.
It would be good to implement this feature across the board for all libraries. I will need to pick a data library that is able to handle multiple data formats, especially json and csv.
I like the Cosmo theme on Bootswatch, but would like to customize the colors. The best way to do this is to use SwatchMaker
make swatch
to create css files for custom Cosmo theme.TODO
I need to put some thought through designing a simple, yet elegant web page for rCharts. This issue here is mainly a stub for me to dump my thoughts on this subject.
Here is a laundry list of potential page types I need.
I get this now when I publish() after the user and pwd request.
Error in post_gist(gist) : could not find function "POST"
I see two issues of hotlinking directly to unversioned assets.
Solution.
This is easy to fix, since I only need to modify the CDN links to assets. Once I make a call on where to host stuff, this should be relatively easy.
Currently, every JS charting library needs three files:
config.yml
layouts/chart.html
layouts/script.html
It should be possible to reduce them to two files: config.yml
and layouts/chart.html
with the full HTML being generated by combining the two using a generic template common to all charting libraries.
The other issue to worry about is specification of CDN vs using assets locally.
As I was trying to to do the PerformanceSummary, I discovered these other spec-level options of polycharts https://github.com/Polychart/polychart2/wiki/Chart-options. Can these be added similar to width and height, so they could work something like
p1 <- rPlot(value ~ date, data = managers.melt, color = 'indexname',
type = 'point', size=list(const=1),
verticalSpacing = list(const=200),
legendPostion = list(const="bottom")
)
and end up in the spec like
var chartParams = {"dom":"chart1b2c2a1d1da3",
"width":700,
"height":400,
"verticalSpacing":15,
"legendPosition":"top",
"layers":[{
Each javascript library seems to like dates as x in a different way. I wanted to document the behavior and then explore how rCharts should handle.
.x(function(d) { return d[opts.x] })
which means we cannot parse here like this
.x(function(d) { return new Date(d)); }
or
.x(function(d) { return d3.time.format("%Y-%m-%d").parse(d); }
. Rather we format the date through a function call like this if we converted the date to milliseconds since 1970-01-01. We could really provide any date format and just adjust the function provided to the xAxis.
edhec.melt$date <- as.double(as.POSIXct(as.Date(edhec.melt$date),origin="1970-01-01")) * 1000
....
chart.xAxis
.tickFormat(function(d) {return d3.time.format("%Y-%m-%d")(new Date(d));})
The convert is easy, but polycharts does not seem to handle the date in the tooltip hover, only in the x axis.
managers.melt$date <- format(managers.melt$date,"%Y-%m-%d")
rCharts implementation is not complete but Rickshaw seems to handle this universally.
edhec.melt$date <- as.double(as.POSIXct(as.Date(edhec.melt$date),origin="1970-01-01"))
managers.melt$date <- format(managers.melt$date,"%Y-%m-%d")
I have not yet explored date handling in xCharts or Highcharts, but will as their support.
The question is
I need to make it clear to users that there are four ways to display an rChart.
p1 <- rPlot(mpg ~ cyl, data = mtcars, type = 'point')
p1 # opens plot using shiny server. sames as p1$show(static = F)
p1$show(static = T) # opens plot as static html
p1$save('myplot.html') # saves the plot as standalone html
p1$printChart('chart1') # prints chart js along with div containing plot
While using printChart
, you will need to explicitly add the js
and css
assets required. If you are using it with Slidify, you just need to include the JS library being used as a widget, and Slidify will automatically add the required assets.
This would allow users the option of loading data from an external file, keeping the HTML uncluttered.
initialize
method to the main rCharts
class, and use callSuper()
in the individual chart classes.*Plot
function.A question that remains is whether or not to allow the users to set width and height of the plot from within the *Plot
function. A case in favor is that most plots should be single line R commands and width and height of a plot are important components.
params <<- list(
dom = basename(tempfile('chart')),
width = getOption('RCHART_WIDTH', 700),
height = getOption('RCHART_HEIGHT', 300)
)
Example of using callSuper
to override initialization inside child classes.
Class1 = setRefClass('Class1', fields = list(params = 'list'), methods = list(
initialize = function(){
params <<- list(x = 1, y = 2)
}
))
Class2 = setRefClass('Class2', fields = list(params = 'list'), contains = 'Class1',
methods = list(
initialize = function(){
callSuper()
params <<- modifyList(params, list(x = 3))
}
))
Here is a use case which motivates this idea. The rCharts_512Paths
visualization by @timelyportfolio relies only on a 512paths
lib folder and a few lines of R code. However, to get it working, I had to do the following:
512paths
to inst
in rCharts.512paths
as a widget to libraries/widgets
in working directory or slidifyLibraries.To encourage use of slidify and rCharts, a user should be able to do all of this by just specifying the path to the lib folder. I think this can be easily done within the R code.
p1 <- rCharts$new()
p1$field( 'lib', '512paths' )
p1$set( data = toJSONArray( data ) )
p1
Now lib
is used in two ways
One way to fix things is to treat lib
as the actual path to the library. If nothing is found, then it can search the system library. A little bit of book-keeping is necessary to connect lib
and lib_url
, but that should be easy.
For it to integrate with slidify, more design changes are required. The key is to communicate with Slidify and add the necessary widgets. Now, this brings me to a bigger question as to how I can facilitate inter-package communication.
Maybe, environments is the solution. Slidify can create a special environment, that other packages can write to. This way, a widget can be automatically added while Slidify is run. This certainly requires more thought. Maybe, a question on SO?
One of the nice things about the charts generated by datawrapper is that they are responsive, which makes them easy to embed on any site. They also come with a nice fullscreen button, which allows a user to view the chart fullscreen.
I need to figure out if there is an easy way to make the charts generated by rCharts responsive.
One important refactoring that remains to be done is consistency in terms of names used. Right now the code base is a mish-mash of camelcase, snakecase, and allcaps. I need to adhere to some kind of a style guide here, before the code base explodes into a nightmare.
This requires me to do the following:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.