toovio-playground

by peteorpeter

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/2.7.15/cytoscape.min.js"></script>
<script src="https://rawgit.com/tgdwyer/WebCola/master/WebCola/cola.min.js"></script>
<script src="https://rawgit.com/cytoscape/cytoscape.js-cola/master/cytoscape-cola.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<div id="cy"></div>
<ul id="detail" style="display: none"></ul>

CSS

#cy {
  width: 100vw;
  height: 100vh;
  background: white;
}

html * {
  box-sizing: border-box;
}

#detail {
  position: fixed;
  bottom: 10px;
  left: 20px;
  background: rgba(0, 0, 0, .7);
  color: white;
  font-family: sans-serif;
  padding: 10px;
  border-radius: 10px;
}

#detail li {
  display: block;
}

#detail em {
  display: inline-block;
  padding: 5px;
  font-weight: lighter;
  width: 100px;
  text-align: right;
}

#detail strong {
  padding: 5px;
}

JavaScript

function roll(fraction) {
  return Math.random() < fraction;
}

function rando(min, max) {
  return min + (Math.random() * (max - min));
}

// Generate some data
function generateElements() {
  var elements = {
    nodes: [],
    edges: []
  }
  var MODEL_COUNT = 40;
  var SEGMENT_COUNT = 20;
  var EDGE_LIKELIHOOD = 0.1;
  var models = [];
  var segments = [];

  _.times(MODEL_COUNT, function(i) {
    models.push({
      data: {
        id: 'm' + i,
        title: 'Model ' + i,
        lift: rando(4, 8),
        accept_rate: rando(1, 12),
        volume: rando(500, 3000)
      },
      classes: 'model'
    });
  })
  
  // Sort by... acc rate?
  models = _.sortBy(models, function(model){
  	return model.data.accept_rate;
  });
  
  _.times(SEGMENT_COUNT, function(i) {
    segments.push({
      data: {
        id: 's' + i,
        title: 'Data ' + i,
      },
      classes: 'segment'
    });
  })
 
  elements.nodes = models.concat(segments);

  _.each(segments, function(source) {
    _.each(models, function(target) {
      if (roll(EDGE_LIKELIHOOD) && source.data.id !== target.data.id) {
        elements.edges.push({
          data: {
            source: source.data.id,
            target: target.data.id,
            id: source.data.id + target.data.id,
            boost: rando(1, 10)
          }
        });
      }
    })
  });

  console.log('generateElements', elements);
  return elements;
}

var LAYOUT = {
  name: 'concentric',

  fit: true, // whether to fit the viewport to the graph
  padding: 30, // the padding on fit
  startAngle: 1 / 2 * Math.PI, // where nodes start in radians
  sweep: undefined, // how many radians should be between the first and last node (defaults to full circle)
  clockwise: false, // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)
  equidistant: false, // whether levels have an equal radial distance betwen them, may cause bounding box overflow
  minNodeSpacing: 10, // min spacing between...