Caleydo Web Tutorial - AngularJS integration

A simple demo on how to integrate Caleydo Web's matrix vis into an AngularJS app. author(s): Fritz Lekschas

by flek

HTML

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="//rawgit.com/Caleydo/caleydo_web/02056f5408fc33402f9de79aa75ddfd097188195/bundle.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.14/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/stampit/2.1.0/stampit.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.5.1/lodash.min.js"></script>
<script src="//rawgit.com/flekschas/d52c5be411bfe2e66e65/raw/0abaf084965178bca5a50de52e6dd9394cf8e183/data.js"></script>
<script src="//rawgit.com/flekschas/d52c5be411bfe2e66e65/raw/b1465a53e53deaa401ac3eb3a6b2393b5e96f4d4/stamps.js"></script>
<div id="app" ng-app="matrixApp" ng-controller="matrixAppCtrl as app">
  <table id="table" ng-mouseleave="app.leaveTableBody()">
    <thead>
      <tr>
        <th
          ng-if="app.matrix.columnIds || app.matrix.rowIds"
          ng-mouseenter="app.leaveTableBody()"></th>
        <th
          ng-class="{ 'soft-highlight': app.hoveringColumn === $index, 'selected': app.columnSelected($index) }"
          ng-click="app.selectColumn($index)"
          ng-mouseenter="app.enterColumn($index)"
          ng-repeat="id in app.matrix.columnIds track by $index" class="ids">{{ app.matrix.columnHeader($index) }}</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="row in app.matrix.rowIds track by $index">
        <td
          class="ids"
          ng-class="{ 'soft-highlight': app.hoveringRow === $parent.$index, 'selected': app.rowSelected($parent.$index) }"
          ng-if="app.matrix.rowIds.length"
          ng-mouseenter="app.enterRow($index)"
          ng-click="app.selectRow($index)">{{ app.matrix.rowHeader($index) }}</td>
        <td
          class="cell"
          ng-class="{
            'soft-highlight-horizontally': app.hoveringRow === $parent.$index,
            'soft-highlight-vertically': app.hoveringColumn === $index,
            'selected': app.cellSelected($index,...

SCSS

@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700);

$colorBlindBlue: #50b4e9;
$colorBlindYellow: #f0e442;

$colorDirectHoverBg: rgba(0, 0, 0, 0.2);
$colorIndirectHoverBg: rgba(0, 0, 0, 0.1);
$colorSelectedBg: $colorBlindYellow;

#app {
  font-family: 'Source Sans Pro', sans-serif;
  font-size: 14px;
}

#table {
  .ids {
    font-weight: bold;
    color: #000;
    
    &:hover {
      cursor: pointer;
    }
    
    &.soft-highlight {
      background: $colorIndirectHoverBg;
    }
    
    &.selected {
      background: lighten($colorSelectedBg, 15%);
    }
  }
  
  .cell {
    color: #333;
    
    &:hover {
      color: #000;
      background: $colorDirectHoverBg;
      box-shadow: none !important;
    }
    
    &.soft-highlight-horizontally {
      box-shadow: inset 0 2px 0 0 $colorIndirectHoverBg, inset 0 -2px 0 0 $colorIndirectHoverBg;
    }
    
    &.soft-select-horizontally {
      box-shadow: inset 0 2px 0 0 $colorSelectedBg, inset 0 -2px 0 0 $colorSelectedBg;
    }
    
    &.soft-highlight-vertically {
      box-shadow: inset 2px 0 0 0 $colorIndirectHoverBg, inset -2px 0 0 0 $colorIndirectHoverBg;
    }
    
    &.soft-select-vertically {
      box-shadow: inset 2px 0 0 0 $colorSelectedBg, inset -2px 0 0 0 $colorSelectedBg;
    }
    
    &.soft-select-horizontally.soft-select-vertically {
      box-shadow: inset 0 0 0 2px $colorSelectedBg;
    }
  
    &:last-child {
      &.soft-highlight-horizontally {
        box-shadow: inset 0 2px 0 0 $colorIndirectHoverBg, inset 0 -2px 0 0 $colorIndirectHoverBg, inset -2px 0 0 0 $colorIndirectHoverBg;
      }
      &.soft-select-horizontally {
        box-shadow: inset 0 2px 0 0 $colorSelectedBg, inset 0 -2px 0 0 $colorSelectedBg, inset -2px 0 0 0 $colorSelectedBg;
      }
    }
  
    &.selected {
      background: $colorSelectedBg;
    }
  }
  
  td, th {
    min-width: 2rem;
    padding: 0.25rem;
    text-align: center;
  }
  
  input {
    width: 2rem;
    text-align: center;
   ...

JavaScript

// Final matrix factory function used by Angular
var matrixFactory = function (stampit, eventStamp, matrixStamp) {
  // The final matrix object is composed of the object and matrix factory
  // functions.
  return stampit.compose(eventStamp, matrixStamp);
};

// Matrix selection service
var matrixSelectionService = function (
  stampit, eventStamp, matrixSelectionStamp
) {
  // App-wide selection service is initialized only once.
  var selections = stampit.compose(eventStamp, matrixSelectionStamp)();
  return selections;
};

var apiService = (function () {
  var Q;

  function api (_q_) {
    Q = _q_;
  }

  api.prototype.getData = function () {
    return Q.when(DUMMY_DATA);
  };

  return api;
}());

// App controller wrapper
var matrixAppCtrl = (function () {
  // Private
  var API;
  var MATRIX;
  var MATRIX_SELECTION;

  // App controller
  function matrixApp (_matrix_, _matrixSelection_, _api_) {
    MATRIX = _matrix_;
    MATRIX_SELECTION = _matrixSelection_;
    API = _api_;

    this.matrixPromise = API.getData().then(function (data) {
      this.data = data;
      this.matrix = MATRIX(null, this.data, true, true);

      // Set dimensionality.
      MATRIX_SELECTION.dimensions = this.matrix.getDimensionality();

      return this.matrix;
    }.bind(this));

    // Link matrix selection methods.
    this.selectCell = MATRIX_SELECTION.selectCell;
    this.selectColumn = MATRIX_SELECTION.selectColumn;
    this.selectRow = MATRIX_SELECTION.selectRow;
    this.cellSelected = MATRIX_SELECTION.cellSelected;
    this.columnSelected = MATRIX_SELECTION.columnSelected;
    this.rowSelected = MATRIX_SELECTION.rowSelected;
  }

  // When mouse leaves the table element.
  matrixApp.prototype.leaveTableBody = function () {
    this.hoveringRow = null;
    this.hoveringColumn = null;
  };

  // When mouse enters a column.
  matrixApp.prototype.enterColumn = function (id) {
    this.hoveringRow = null;
    this.hoveringColumn = id;
  };

  // When mouse enters a row.
 ...