Permalink
Browse files

wdcchart version 0

  • Loading branch information...
1 parent 6e3d65e commit 08b53d45996ed391ef1780eeaccdf7088068235f @gordonwoodhull gordonwoodhull committed Mar 27, 2013
Showing with 158 additions and 60 deletions.
  1. +140 −0 htdocs/dcrchart.js
  2. +1 −0 htdocs/main.html
  3. +15 −58 htdocs/shell_tab.js
  4. +2 −2 rcloud.support/R/wplot.R
View
@@ -0,0 +1,140 @@
+// R to dc.js bridge code. This should probably become a library in js/,
+// just deploying it separately for now to ease development
+//////////////////////////////////////////////////////////////////////////////
+
+var dcrchart = (function() {
+ var chart_group = 0;
+ window.charts = {}; // initialize a global namespace for charts
+
+ function bin_op(disp) {
+ return function(args) {
+ return translate_expr(args[1]) + disp + translate_expr(args[2]);
+ }
+ }
+
+ function una_or_bin_op(disp) {
+ return function(args) {
+ return args.length==2
+ ? '-' + translate_expr(args[1])
+ : bin_op('-')(args);
+ }
+ }
+
+ var translators = {
+ "$": bin_op('.'),
+ "-": una_or_bin_op('-'),
+ "+": una_or_bin_op('+'),
+ "*": bin_op('*'),
+ "/": bin_op('/'),
+ "hash": function(args) { return '{' + _.map(args.slice(1), translate_kv) + '}'; },
+ default : function(args) { return translate_expr(args[0]) + '(' + _.map(args.slice(1), translate_expr) + ')'; }
+ };
+
+ function translate_kv(kv) {
+ if(!$.isArray(kv) || kv[0] != ':' || typeof kv[1] != "string")
+ throw "expected 'key = value' in dc/r hash";
+ return kv[1] + ': ' + translate_expr(kv[2]);
+ }
+
+ function translate_expr(sexp) {
+ if($.isArray(sexp)) {
+ var xlat = translators[sexp[0]] || translators.default;
+ return xlat(sexp);
+ }
+ else return sexp;
+ }
+
+ function make_var(name) {
+ return "var " + name + ' = ';
+ }
+
+ function translate_chart(name, constructor, sexp) {
+ return make_var(name) + 'window.charts["' + name + '"] = dc.' + constructor + '("#' + name + '").' +
+ translate_expr(sexp);
+ }
+
+ function make_chart_div(name) {
+ return $('<div/>',
+ {id: name, style: "float:left"})
+ .append($('<strong/>').append(name))
+ .append('&nbsp;&nbsp;')
+ .append($('<a/>',
+ {class: "reset",
+ href: "javascript:charts."+name+".filterAll(); dc.redrawAll();",
+ style: "display: none;"})
+ .append("reset"))
+ .append($('<div/>').addClass("clearfix"));
+ }
+
+ function chart_handler(prefix, constructor) {
+ return function(result, sexp) {
+ var name = prefix + chart_group + '_' + result.chart_no++;
+ var chart_code = translate_chart(name, constructor, sexp[1]);
+ result.charts.push(chart_code);
+ result.divs.push(make_chart_div(name))
+ return result;
+ }
+ }
+
+ var dimensions = {
+ col: function(sexp) { return "d[" + sexp[1] + "]"; }
+ };
+
+ function translate_dimension(sexp) {
+ if(_.isUndefined(dimensions[sexp[0]]))
+ throw "unknown dc/r dimension " + sexp[0];
+ return dimensions[sexp[0]](sexp);
+ }
+
+ // this could conceivably just be a "var" statement
+ var domains = {
+ uniques: function(sexp) { return "_.pluck(" + sexp[1] + ".group().all(),'key')"; }
+ };
+
+ function translate_domain(sexp) {
+ if(_.isUndefined(domains[sexp[0]]))
+ throw "unknown dc/r domain " + sexp[0];
+ return domains[sexp[0]](sexp);
+ }
+
+ var statements = {
+ dimension: function(result, sexp) {
+ result.decls.push(make_var(sexp[1]) + "ndx.dimension(function(d) { return " +
+ translate_dimension(sexp[2]) + "; })");
+ return result;
+ },
+ domain: function(result, sexp) {
+ result.decls.push(make_var(sexp[1]) + translate_domain(sexp[2]));
+ return result;
+ },
+ pie: chart_handler('pie', 'pieChart'),
+ bar: chart_handler('bar', 'barChart')
+ };
+
+ function translate_statement(result, sexp) {
+ if(_.isUndefined(statements[sexp[0]]))
+ throw "unknown dc/r statement " + sexp[0];
+ return statements[sexp[0]](result, sexp);
+ }
+
+ var result = {
+ translate: function(sexp) {
+ if(sexp[0] != "charts")
+ throw 'expected "charts" at top level';
+ var charts_result = {chart_no: 0, decls: [], charts: [], divs: []};
+ var result = _.reduce(sexp.slice(1),
+ translate_statement,
+ charts_result);
+ var js = "debugger;\n" +
+ "var ndx = crossfilter(rows);\n" +
+ result.decls.join(";\n") + ";\n" +
+ result.charts.join(";\n") + ";\n" +
+ "dc.renderAll();\n";
+ chart_group++;
+ var divwrap = $('<div/>');
+ _.each(result.divs, function(div) { divwrap.append(div); });
+ return { javascript: js, elem: divwrap };
+ }
+ };
+ return result;
+})();
View
@@ -134,6 +134,7 @@ <h4 id="input-text-history-results-title" style="padding-bottom: 0; margin-botto
<script src="editor_tab.js"></script>
<script src="shell_tab.js"></script>
+<script src="dcrchart.js"></script>
<!-- For some bizarre reason, line numbering has garbage characters on --
-- the minified version, so we use the unminified version instead.
View
@@ -95,71 +95,28 @@ var shell = (function() {
var sel = data[2];
Chart.set_selections(group, sel);
}
-
- var dcnum=0;
- function handle_twochart(data) {
- return function(N, rows) {
- setTimeout(function() {
- var oneChart = window["oneChart"+N] = dc.pieChart("#one"+N);
- var twoChart = window["twoChart"+N] = dc.barChart("#two"+N);
-
- var ndx = crossfilter(rows);
- var all = ndx.groupAll();
-
- var oneDimension = ndx.dimension(function(d) {
- return d[0];
- });
- var oneGroup = oneDimension.group().reduceCount();
-
- var twoDimension = ndx.dimension(function(d) {
- return d[1];
- });
- var twoGroup = twoDimension.group().reduceCount();
- // i'm sure there's a better way to do this; why doesn't the default-uniques work?
- var twoDomain = _.map(twoDimension.group().all(), function(kv) { return kv.key; });
-
- oneChart.width(180)
- .height(180)
- .radius(80)
- .dimension(oneDimension)
- .group(oneGroup)
- ;
- twoChart.width(500)
- .height(100)
- .margins({top: 20, right: 50, bottom: 20, left: 40})
- .dimension(twoDimension)
- .group(twoGroup)
- .centerBar(false)
- .gap(0)
- .x(d3.scale.ordinal().domain(twoDomain))
- .xUnits(dc.units.ordinal)
- ;
-
- dc.renderAll();
- }, 100);
- function chartDiv(name) {
- return $('<div/>',
- {id: name+N, style: "float:left"})
- .append($('<strong/>').append(name))
- .append('&nbsp;&nbsp;')
- .append($('<a/>',
- {class: "reset",
- href: "javascript:"+name+"Chart"+N+".filterAll(); dc.redrawAll();",
- style: "display: none;"})
- .append("reset"))
- .append($('<div/>').addClass("clearfix"));
- }
- return $('<div/>').append(chartDiv("one")).append(chartDiv("two"));
- }(++dcnum, data[1]);
+ function handle_dcchart(data) {
+ var chart_data, dcfunc;
+ try {
+ chart_data = dcrchart.translate(data[2]);
+ dcfunc = new Function("rows", chart_data.javascript);
+ }
+ catch(e) {
+ return $('<p/>').append("Exception creating dc code: " + e);
+ }
+ var rows = data[1];
+ setTimeout(function() { dcfunc(rows); }, 10);
+ return chart_data.elem;
}
+
var handlers = {
"scatterplot": handle_scatterplot,
"iframe": handle_iframe,
"facet_osm_plot": handle_facet_osm_plot,
"facet_tour_plot": handle_facet_tour_plot,
- "select": handle_select,
- "twochart": handle_twochart
+ "select": handle_select,
+ "dcchart": handle_dcchart
};
var notebook_model = Notebook.create_model();
View
@@ -60,7 +60,7 @@ wtour <- function(...)
deferred.rcloud.result((list("facet_tour_plot", opts)))
}
-wtwochart <- function(data)
+wdcchart <- function(data, dcexpr)
{
- deferred.rcloud.result((list("twochart", data)))
+ deferred.rcloud.result(list("dcchart", data, substitute(dcexpr)))
}

0 comments on commit 08b53d4

Please sign in to comment.