all files / candela/components/SurvivalPlot/ index.js

68.92% Statements 51/74
80.49% Branches 33/41
56.25% Functions 9/16
22.22% Lines 6/27
15 statements, 3 functions, 18 branches Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96                                                                                                                                                                                      
import VisComponent from '../../VisComponent';
import VegaChart from '../../VisComponent/mixin/VegaChart';
import spec from './spec.json';
 
export default class SurvivalPlot extends VegaChart(VisComponent, spec) {
  static get options () {
    return [
      {
        name: 'data',
        type: 'table',
        format: 'objectlist'
      },
      {
        name: 'time',
        type: 'string',
        format: 'text',
        domain: {
          mode: 'field',
          from: 'data',
          fieldTypes: ['number', 'integer']
        }
      },
      {
        name: 'censor',
        type: 'string',
        format: 'text',
        domain: {
          mode: 'field',
          from: 'data',
          fieldTypes: ['integer', 'boolean']
        }
      },
      {
        name: 'group',
        type: 'string',
        format: 'text',
        optional: true,
        domain: {
          mode: 'field',
          from: 'data',
          fieldTypes: ['string', 'date', 'number', 'integer', 'boolean']
        }
      }
    ];
  }
 
  constructor (el, options) {
    super(el, options);
 
    // Sort the events by time.
    options.data.sort((x, y) => x[options.time] - y[options.time]);
 
    // If there is no 'group' parameter, fake one up.
    if (!options.group) {
      options.group = 'group';
      options.data.forEach(d => d.group = 0);
    }
 
    // Collect the grouping values, and count how many belong to each group.
    let groups = {};
    options.data.forEach(d => {
      const key = d[options.group];
      if (!groups[key]) {
        groups[key] = {
          survivors: 1
        };
      }
 
      groups[key].survivors++;
    });
 
    // Append a dummy value to the start of the dataset, one per group.
    const dummies = Object.keys(groups).map(g => {
      let x = {
        time: 0
      };
 
      x[options.group] = g;
 
      return x;
    });
    options.data = [...dummies, ...options.data];
 
    // Compute the number of survivors at each event. A patient is assumed to
    // have not survived, unless the reason for the event is "right censoring"
    // (aka, censor == 1).
    options.data.forEach(d => {
      if (d[options.censor] !== 0) {
        groups[d[options.group]].survivors--;
      }
      d.survivors = groups[d[options.group]].survivors;
    });
  }
}