block by timelyportfolio 9211644

rCharts issue 77 - dimple example

Full Screen

index.html

<!doctype HTML>
<meta charset = 'utf-8'>
<html>
  <head>
    <link rel='stylesheet' href='//timelyportfolio.github.io/rCharts_dimple/tooltipfix.css'>
    <link rel='stylesheet' href='//timelyportfolio.github.io/rCharts_dimple/js/d3.tip.v0.6.3.js'>
    
    <script src='//d3js.org/d3.v3.min.js' type='text/javascript'></script>
    <script src='//dimplejs.org/dist/dimple.v1.1.5.min.js' type='text/javascript'></script>
    <script src='//timelyportfolio.github.io/rCharts_dimple/js/d3.tip.v0.6.3.js' type='text/javascript'></script>
    
    <style>
    .rChart {
      display: block;
      margin-left: auto; 
      margin-right: auto;
      width: 800px;
      height: 400px;
    }  
    </style>
    
  </head>
  <body >
    
    <div id = 'chart20c07b4c1bc9' class = 'rChart dimple'></div>    
    <script type="text/javascript">
  var opts = {
 "dom": "chart20c07b4c1bc9",
"width":    800,
"height":    400,
"xAxis": {
 "type": "addCategoryAxis",
"showPercent": false 
},
"yAxis": {
 "type": "addCategoryAxis",
"showPercent": false,
"orderRule": [ "Nonacademic", "Fixed Term Academic", "Other Tenure Track", "Research University", "Postdoc" ] 
},
"zAxis": [],
"colorAxis": {
 "type": "addColorAxis",
"colorSeries": "Value",
"palette": [ "white", "pink", "red" ] 
},
"defaultColors": [],
"layers": [],
"legend": [],
"x": [ "Year", "Employer" ],
"y": "Type",
"type": "bar",
"bounds": {
 "x":    140,
"y":     50,
"height":    300,
"width":    500 
},
"tooltip": {
 "html": "'<h4 style=\"color:gray;\">Employer: ' + d.key.split('/')[1].split('_')[0] + '</h4>Year: ' + d.cx + '<br> Count: ' + d.cValue",
"direction": "n",
"offset": [     10,    -10 ] 
},
"id": "chart20c07b4c1bc9" 
},
    data = [{"Employer":"aaa","Type":"Fixed Term Academic","Year":"2010","Value":8},{"Employer":"bbb","Type":"Fixed Term Academic","Year":"2010","Value":7},{"Employer":"ccc","Type":"Fixed Term Academic","Year":"2010","Value":12},{"Employer":"ddd","Type":"Fixed Term Academic","Year":"2010","Value":8},{"Employer":"eee","Type":"Fixed Term Academic","Year":"2010","Value":6},{"Employer":"aaa","Type":"Nonacademic","Year":"2010","Value":11},{"Employer":"bbb","Type":"Nonacademic","Year":"2010","Value":3},{"Employer":"ccc","Type":"Nonacademic","Year":"2010","Value":8},{"Employer":"ddd","Type":"Nonacademic","Year":"2010","Value":9},{"Employer":"eee","Type":"Nonacademic","Year":"2010","Value":7},{"Employer":"aaa","Type":"Other Tenure Track","Year":"2010","Value":14},{"Employer":"bbb","Type":"Other Tenure Track","Year":"2010","Value":12},{"Employer":"ccc","Type":"Other Tenure Track","Year":"2010","Value":8},{"Employer":"ddd","Type":"Other Tenure Track","Year":"2010","Value":13},{"Employer":"eee","Type":"Other Tenure Track","Year":"2010","Value":7},{"Employer":"aaa","Type":"Postdoc","Year":"2010","Value":15},{"Employer":"bbb","Type":"Postdoc","Year":"2010","Value":5},{"Employer":"ccc","Type":"Postdoc","Year":"2010","Value":9},{"Employer":"ddd","Type":"Postdoc","Year":"2010","Value":9},{"Employer":"eee","Type":"Postdoc","Year":"2010","Value":8},{"Employer":"aaa","Type":"Research University","Year":"2010","Value":12},{"Employer":"bbb","Type":"Research University","Year":"2010","Value":8},{"Employer":"ccc","Type":"Research University","Year":"2010","Value":9},{"Employer":"ddd","Type":"Research University","Year":"2010","Value":9},{"Employer":"eee","Type":"Research University","Year":"2010","Value":13},{"Employer":"aaa","Type":"Fixed Term Academic","Year":"2011","Value":17},{"Employer":"bbb","Type":"Fixed Term Academic","Year":"2011","Value":7},{"Employer":"ccc","Type":"Fixed Term Academic","Year":"2011","Value":12},{"Employer":"ddd","Type":"Fixed Term Academic","Year":"2011","Value":9},{"Employer":"eee","Type":"Fixed Term Academic","Year":"2011","Value":12},{"Employer":"aaa","Type":"Nonacademic","Year":"2011","Value":12},{"Employer":"bbb","Type":"Nonacademic","Year":"2011","Value":6},{"Employer":"ccc","Type":"Nonacademic","Year":"2011","Value":11},{"Employer":"ddd","Type":"Nonacademic","Year":"2011","Value":12},{"Employer":"eee","Type":"Nonacademic","Year":"2011","Value":15},{"Employer":"aaa","Type":"Other Tenure Track","Year":"2011","Value":10},{"Employer":"bbb","Type":"Other Tenure Track","Year":"2011","Value":14},{"Employer":"ccc","Type":"Other Tenure Track","Year":"2011","Value":8},{"Employer":"ddd","Type":"Other Tenure Track","Year":"2011","Value":18},{"Employer":"eee","Type":"Other Tenure Track","Year":"2011","Value":12},{"Employer":"aaa","Type":"Postdoc","Year":"2011","Value":6},{"Employer":"bbb","Type":"Postdoc","Year":"2011","Value":13},{"Employer":"ccc","Type":"Postdoc","Year":"2011","Value":10},{"Employer":"ddd","Type":"Postdoc","Year":"2011","Value":14},{"Employer":"eee","Type":"Postdoc","Year":"2011","Value":8},{"Employer":"aaa","Type":"Research University","Year":"2011","Value":12},{"Employer":"bbb","Type":"Research University","Year":"2011","Value":10},{"Employer":"ccc","Type":"Research University","Year":"2011","Value":11},{"Employer":"ddd","Type":"Research University","Year":"2011","Value":12},{"Employer":"eee","Type":"Research University","Year":"2011","Value":9},{"Employer":"aaa","Type":"Fixed Term Academic","Year":"2012","Value":11},{"Employer":"bbb","Type":"Fixed Term Academic","Year":"2012","Value":6},{"Employer":"ccc","Type":"Fixed Term Academic","Year":"2012","Value":15},{"Employer":"ddd","Type":"Fixed Term Academic","Year":"2012","Value":10},{"Employer":"eee","Type":"Fixed Term Academic","Year":"2012","Value":10},{"Employer":"aaa","Type":"Nonacademic","Year":"2012","Value":6},{"Employer":"bbb","Type":"Nonacademic","Year":"2012","Value":12},{"Employer":"ccc","Type":"Nonacademic","Year":"2012","Value":9},{"Employer":"ddd","Type":"Nonacademic","Year":"2012","Value":7},{"Employer":"eee","Type":"Nonacademic","Year":"2012","Value":9},{"Employer":"aaa","Type":"Other Tenure Track","Year":"2012","Value":12},{"Employer":"bbb","Type":"Other Tenure Track","Year":"2012","Value":12},{"Employer":"ccc","Type":"Other Tenure Track","Year":"2012","Value":6},{"Employer":"ddd","Type":"Other Tenure Track","Year":"2012","Value":11},{"Employer":"eee","Type":"Other Tenure Track","Year":"2012","Value":10},{"Employer":"aaa","Type":"Postdoc","Year":"2012","Value":11},{"Employer":"bbb","Type":"Postdoc","Year":"2012","Value":10},{"Employer":"ccc","Type":"Postdoc","Year":"2012","Value":12},{"Employer":"ddd","Type":"Postdoc","Year":"2012","Value":11},{"Employer":"eee","Type":"Postdoc","Year":"2012","Value":13},{"Employer":"aaa","Type":"Research University","Year":"2012","Value":13},{"Employer":"bbb","Type":"Research University","Year":"2012","Value":12},{"Employer":"ccc","Type":"Research University","Year":"2012","Value":9},{"Employer":"ddd","Type":"Research University","Year":"2012","Value":12},{"Employer":"eee","Type":"Research University","Year":"2012","Value":9},{"Employer":"aaa","Type":"Fixed Term Academic","Year":"2013","Value":6},{"Employer":"bbb","Type":"Fixed Term Academic","Year":"2013","Value":11},{"Employer":"ccc","Type":"Fixed Term Academic","Year":"2013","Value":8},{"Employer":"ddd","Type":"Fixed Term Academic","Year":"2013","Value":12},{"Employer":"eee","Type":"Fixed Term Academic","Year":"2013","Value":12},{"Employer":"aaa","Type":"Nonacademic","Year":"2013","Value":8},{"Employer":"bbb","Type":"Nonacademic","Year":"2013","Value":10},{"Employer":"ccc","Type":"Nonacademic","Year":"2013","Value":9},{"Employer":"ddd","Type":"Nonacademic","Year":"2013","Value":10},{"Employer":"eee","Type":"Nonacademic","Year":"2013","Value":6},{"Employer":"aaa","Type":"Other Tenure Track","Year":"2013","Value":11},{"Employer":"bbb","Type":"Other Tenure Track","Year":"2013","Value":15},{"Employer":"ccc","Type":"Other Tenure Track","Year":"2013","Value":9},{"Employer":"ddd","Type":"Other Tenure Track","Year":"2013","Value":7},{"Employer":"eee","Type":"Other Tenure Track","Year":"2013","Value":11},{"Employer":"aaa","Type":"Postdoc","Year":"2013","Value":8},{"Employer":"bbb","Type":"Postdoc","Year":"2013","Value":16},{"Employer":"ccc","Type":"Postdoc","Year":"2013","Value":11},{"Employer":"ddd","Type":"Postdoc","Year":"2013","Value":4},{"Employer":"eee","Type":"Postdoc","Year":"2013","Value":9},{"Employer":"aaa","Type":"Research University","Year":"2013","Value":9},{"Employer":"bbb","Type":"Research University","Year":"2013","Value":6},{"Employer":"ccc","Type":"Research University","Year":"2013","Value":8},{"Employer":"ddd","Type":"Research University","Year":"2013","Value":7},{"Employer":"eee","Type":"Research University","Year":"2013","Value":9}];
  var svg = dimple.newSvg("#" + opts.id, opts.width, opts.height);
  
  tip = d3.tip()
    .html(function(d) {
      return eval(opts.tooltip.html) ;
    })
    .direction(opts.tooltip.direction ? opts.tooltip.direction : "s")
    .offset(opts.tooltip.offset ? opts.tooltip.offset : [10,10])

  /* Invoke the tip in the context of your visualization */
  svg.call(tip)

  //data = dimple.filterData(data, "Owner", ["Aperture", "Black Mesa"])
  var myChart = new dimple.chart(svg, data);
  if (opts.bounds) {
    myChart.setBounds(opts.bounds.x, opts.bounds.y, opts.bounds.width, opts.bounds.height);//myChart.setBounds(80, 30, 480, 330);
  }
  //dimple allows use of custom CSS with noFormats
  if(opts.noFormats) { myChart.noFormats = opts.noFormats; };
  //for markimekko and addAxis also have third parameter measure
  //so need to evaluate if measure provided
  
  //function to build axes
  function buildAxis(position,layer){
    var axis;
    var axisopts = opts[position+"Axis"];
    
    if(axisopts.measure) {
      axis = myChart[axisopts.type](position,layer[position],axisopts.measure);
    } else {
      axis = myChart[axisopts.type](position, layer[position]);
    };
    if(!(axisopts.type === "addPctAxis")) axis.showPercent = axisopts.showPercent;
    if (axisopts.orderRule) axis.addOrderRule(axisopts.orderRule);
    if (axisopts.grouporderRule) axis.addGroupOrderRule(axisopts.grouporderRule);  
    if (axisopts.overrideMin) axis.overrideMin = axisopts.overrideMin;
    if (axisopts.overrideMax) axis.overrideMax = axisopts.overrideMax;
    if (axisopts.overrideMax) axis.overrideMax = axisopts.overrideMax;
    if (axisopts.inputFormat) axis.dateParseFormat = axisopts.inputFormat;
    if (axisopts.outputFormat) axis.tickFormat = axisopts.outputFormat;    
    return axis;
  };
  
  var c = null;
  if(d3.keys(opts.colorAxis).length > 0) {
    c = myChart[opts.colorAxis.type](opts.colorAxis.colorSeries,opts.colorAxis.palette) ;
  }
  
  //allow manipulation of default colors to use with dimple
  if(opts.defaultColors.length) {
    opts.defaultColors = opts.defaultColors[0];
    if (typeof(opts.defaultColors) == "function") {
      //assume this is a d3 scale
      //for now loop through first 20 but need a better way to handle
      defaultColorsArray = [];
      for (var n=0;n<20;n++) {
        defaultColorsArray.push(opts.defaultColors(n));
      };
      opts.defaultColors = defaultColorsArray;
    }
    opts.defaultColors.forEach(function(d,i) {
      opts.defaultColors[i] = new dimple.color(d);
    })
    myChart.defaultColors = opts.defaultColors;
  }  
  
  //do series
  //set up a function since same for each
  //as of now we have x,y,groups,data,type in opts for primary layer
  //and other layers reside in opts.layers
  function buildSeries(layer, hidden){
    var x = buildAxis("x", layer);
    x.hidden = hidden;
    
    var y = buildAxis("y", layer);
    y.hidden = hidden;
    
    //z for bubbles
    var z = null;
    if (!(typeof(layer.zAxis) === 'undefined') && layer.zAxis.type){
      z = buildAxis("z", layer);
    };
    
    //here think I need to evaluate group and if missing do null
    //as the group argument
    //if provided need to use groups from layer
    var s = new dimple.series(myChart, null, x, y, z, c, dimple.plot[layer.type], dimple.aggregateMethod.avg, dimple.plot[layer.type].stacked);
    
    if(layer.hasOwnProperty("groups")) {
      s.categoryFields = (typeof layer.groups === "object") ? layer.groups : [layer.groups]; 
    };
    
    //series offers an aggregate method that we will also need to check if available
    //options available are avg, count, max, min, sum
    if (!(typeof(layer.aggregate) === 'undefined')) {
      s.aggregate = eval(layer.aggregate);
    }
    if (!(typeof(layer.lineWeight) === 'undefined')) {
      s.lineWeight = eval(layer.lineWeight);
    }
    if (!(typeof(layer.barGap) === 'undefined')) {
      s.barGap = eval(layer.barGap);
    }
    
   /* if (!(typeof(layer.eventHandler) === 'undefined')) {
      layer.eventHandler = (layer.eventHandler.length === "undefined") ? layer.eventHandler : [layer.eventHandler];
      layer.eventHandler.forEach(function(evt){
        s.addEventHandler(evt.event, eval(evt.handler))
      })
    }*/
    // Handle the hover event - overriding the default behaviour
    s.addEventHandler("mouseover", onHover);
    // Handle the leave event - overriding the default behaviour
    s.addEventHandler("mouseleave", onLeave);
      
    myChart.series.push(s);
    return s;
  };
  
  buildSeries(opts, false);
  if (opts.layers.length > 0) {
    opts.layers.forEach(function(layer){
      buildSeries(layer, true);
    })
  }
  //unsure if this is best but if legend is provided (not empty) then evaluate
  if(d3.keys(opts.legend).length > 0) {
    var l =myChart.addLegend();
    d3.keys(opts.legend).forEach(function(d){
      l[d] = opts.legend[d];
    });
  }
  //quick way to get this going but need to make this cleaner
  if(opts.storyboard) {
    myChart.setStoryboard(opts.storyboard);
  };
  myChart.draw();
  
  function onHover(e){
    tip.show(e.selectedShape.datum());
  }
  
  function onLeave(e){
    tip.hide(e.selectedShape.datum());
  }
</script>
    
    
      <script>
      d3.selectAll('rect.bar')
      .transition()
      .delay(100)
      .style('stroke',function(d){
      return d.fill
      })
      .attr('width',d3.select('rect.bar').attr('width')/2);
      myChart.axes[1].titleShape.text('Year')
      myChart.axes[2].titleShape.remove()
      
      //add title
      myChart.svg.append('g')
      .append('text')
      .text('An Awesome rCharts + dimple Creation')
      .attr('x',10)
      .attr('y',30)
      .style('font-size','200%')
      </script>
          
  </body>
</html>

code.R

#install_github("rCharts","timelyportfolio",ref="dimple_layer")
require(rCharts)

data.new <- data.frame(id = 1:1000)
data.new$Employer <- c("aaa","bbb","ccc","ddd","eee")[runif(n=1000,min=1,max=6)]
data.new$Type <- c("Nonacademic", "Postdoc", "Fixed Term Academic", "Other Tenure Track", "Research University")[runif(n=1000,min=1,max=6)]
data.new$Year <- c("2010","2011","2012","2013")[runif(n=1000,min=1,max=5)]

data.new <- 
  data.frame(xtabs( ~ Employer + Type + Year, data = data.new))

colnames(data.new)[4] <- "Value"

dmap <- dPlot(
  x = c("Year","Employer"),
  y = "Type",
  data = data.new,
  type = "bar",
  bounds = list(x=140,y=50,height=300,width=500)
)
dmap$yAxis(
  type = "addCategoryAxis",
  orderRule=levels(data.new$Type)[c(2,1,3,5,4)]
)
dmap$colorAxis(
  type = "addColorAxis",
  colorSeries = "Value",
  palette = c("white","pink","red")
)
dmap$setTemplate(
  afterScript = "
  <script>
  d3.selectAll('rect.bar')
  .transition()
  .delay(100)
  .style('stroke',function(d){
  return d.fill
  })
  .attr('width',d3.select('rect.bar').attr('width')/2);
  myChart.axes[1].titleShape.text('Year')
  myChart.axes[2].titleShape.remove()
  
  //add title
  myChart.svg.append('g')
  .append('text')
  .text('An Awesome rCharts + dimple Creation')
  .attr('x',10)
  .attr('y',30)
  .style('font-size','200%')
  </script>
  "
)

#get some tooltips
dmap$templates$script = 
  #"http://timelyportfolio.github.io/rCharts_dimple/chart_tooltip.html"
  "./chart_tooltip.html"
dmap$addAssets("http://timelyportfolio.github.io/rCharts_dimple/js/d3.tip.v0.6.3.js")
#use d3-tip and html
#so allows use of <h3>,<p>,etc tags
#see d3-tip api https://github.com/Caged/d3-tip/blob/master/docs/positioning-tooltips.md
#best way to see what d provides for information is Chrome console
dmap$set(tooltip = list(
  html = "'<strong>Employer: ' + d.key.split('/')[1].split('_')[0] + '</strong></br>Year: ' + d.cx + '<br> Count: ' + d.cValue"
  ,direction = "n"  # defaults to s; options n for top, e right, w left, s bottom
  ,offset = c(10,-10) # this is the default; adds offset to position
))
dmap