Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
<link class="jsbin" href="https://getbootstrap.com/2.3.2/assets/css/bootstrap-responsive.css" rel="stylesheet" type="text/css" />
<link class="jsbin" href="https://getbootstrap.com/2.3.2/assets/css/bootstrap.css" rel="stylesheet" type="text/css" />
  
<script class="jsbin" src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
  
<script class="jsbin" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script class="jsbin" src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<script src="https://js-hypercube-demo.herokuapp.com/js-hypercube.min.js"></script>
<script src="https://js-hypercube-demo.herokuapp.com/example.data.js"></script>
  
<meta charset=utf-8 />
  <title>js-hypercube/backbone.js example</title>
<!--[if IE]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
  article, aside, figure, footer, header, hgroup, 
  menu, nav, section { display: block; }
  
  td {height:50px;vertical-align:top;}
</style>
</head>
<body>
  <div class="container">
    <h1>Video Game Revenue Example</h1>
  <div class="row">
    <div class="span12">
      <table class="table table-condensed" id="revenue"></table>
    </div>
    </div>
  </div>
</body>
</html>
 
// convert timestamp to multiple date/time dimensions
ps.Cube.transforms.dateLocal(window.example.data);
var sampleCube = ps.Cube.deserialize(window.example.data, ['rentals', 'sales', 'revenue']);
// an OLAP cube
var Cube = Backbone.Model.extend({
  defaults: {
    slice: 'Total Revenue',
    drillBy: null, // dimension to drill by
    childSlices: null, // child cubes if we've drilled down
    parentSlices: [] // any dimensions we are already slicing by
  },
  initialize: function() {
    // when drilling by a different dimension, update children
    this.bind('change:drillBy', function() {
      this.updateChildCubes();
    });
  },
  updateChildCubes: function() {
    var drillBy = this.get('drillBy');
    
    if (drillBy === null) {
      // remove children
      this.set({childSlices: null});
    } else {
      var cube = this.get('cube');
      var allSlices =  _.toArray(_.clone(this.get('parentSlices')));
      allSlices.push(drillBy);
      var childCubes = _.map(cube.getValues(drillBy).sort(), function(element) {
        var slice = {};
        slice[drillBy] = element;
        return new Cube({
          cube: cube.slice(slice),
          slice: element,
          parentSlices: allSlices
        });
      });
      this.set({childSlices: new CubeList(childCubes)});
    }
  },
  
  drillBy: function(dimension) {
    this.set({drillBy: dimension});
    return this;
  },
  
  // get next dimension available to drill down by
  nextDimension: function() {
    var allDimensions = this.get('cube').getFactNames();
    var allSlices = this.get('parentSlices');
    // discard dimensions in parent slices
    var dimensions = _.difference(allDimensions, allSlices);
    if (dimensions.length === 0) {
      // can't drill down any further
      return false;
    }
    var currentDrill = this.get('drillBy');
    if (currentDrill === null) {
      return dimensions[0];
    } else {
      var pos = _.indexOf(dimensions, currentDrill);
      if (pos == dimensions.length-1) {
        return null;
      } else {
        return dimensions[pos + 1];
      }
    }
  },
    
  drillByNextDimension: function() {
    var nextDimension = this.nextDimension();
    if (nextDimension === false) {
      return;
    }
    this.drillBy(nextDimension);
  }
   
  
});
// used to hold all of the child cubes when we drill down
var CubeList = Backbone.Collection.extend({
  model: Cube
});
// render the total revenue for a cube
var CubeView = Backbone.View.extend({
  tagName: 'tr',
  className: 'bullet',
  
  initialize: function() {
    console.log('initializing cubeview');
    _.bindAll(this, 'render', 'drill');
    this.model.bind('change', this.render);
  },
  
  // drill down on click
  events: {
    'click': 'drill'
  },
  
  drill: function(){
    event.stopImmediatePropagation();
    this.model.drillByNextDimension();
  },
  
  render: function() {
    // get the underlying js-hybercube object
    var cube = this.model.get('cube');
    var revenue = cube.sum().rentals;
    var slice = this.model.get('slice').toString();
        
    // render the revenue and bar chart in a table row
    // my html/css skills are as bad as they were in 1999
    $(this.el).html('<td><button class="btn btn-small btn-primary">' +
                    slice + '</button> <span class="badge badge-success">$' +
                    revenue + '</span></td>' +
                    '<td class="bullet"><div style="width:'+ parseInt(revenue/10, 10) +'px;' +
                    'height:20px; background-color:#CCC;"></div></td>');
    
    // render the children if we've drilled down
    var childCubes = this.model.get('childSlices');
    if (childCubes !== null) {
      $('td.bullet', this.el).append('<h4>Drill By '+this.model.get('drillBy').toString().replace(/_/g,' ') +'</h4>');
      var childView = new CubeListView({collection: childCubes});
      $('td.bullet', this.el).append(childView.render().el);
    }
    return this;
  }
});
// render a collection of cubes
var CubeListView = Backbone.View.extend({
  tagName: 'table',
  
  initialize: function() {
    _.bindAll(this, 'render');
  },
  
  render: function() {
    var table = this.el;
    _(this.collection.models).each(function(item) {
       var cubeview = new CubeView({ model: item});
       $(table).append(cubeview.render().el);
    }, this);
    
    return this;
  }
});
var cube = new Cube({cube: sampleCube});
var salesCube = new CubeView({
  model: cube
});
$('table#revenue').append(salesCube.render().el);
Output 300px

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
cwardenpro
0viewers