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>
<button id="update">Update data once</button>
<label id="constant"><input type="checkbox"> Update every 250ms</label>

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;
}

#update {
  position: fixed;
  right: 190px;
  top: 10px;
}

#constant {
  display: block;
  position: fixed;
  right: 10px;
  top: 10px;
}

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 = 60;
  var SEGMENT_COUNT = 25;
  var EDGE_LIKELIHOOD = 0.09;
  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'
    });
  })
  _.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 COLA_LAYOUT = {
  name: 'cola',
  animate: true, // whether to show the layout as it's running
  refresh: 1, // number of ticks per frame; higher is faster but more jerky
  maxSimulationTime: 1500, // max length in ms to run the layout
  ungrabifyWhileSimulating: false, // so you can't drag nodes during layout
  fit: true, // on every layout reposition of nodes, fit the viewport
  padding: 30, // padding around the simulation
  boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }

  // positioning options
  randomize: false, // use random node positions at beginning of layout
  avoidOverlap: true, // if true, prevents overlap of node bounding...