weighted_directed_graph.js 5.2 KB
Newer Older
1 2
'use strict';

3
const DirectedGraphTracer = require('./directed_graph');
N
nem035 已提交
4 5

const {
J
Jason Park 已提交
6
  refineByType
7
} = require('../../tracer_manager/util/index');
N
nem035 已提交
8

J
Jason Park 已提交
9 10 11
class WeightedDirectedGraphTracer extends DirectedGraphTracer {
  static getClassName() {
    return 'WeightedDirectedGraphTracer';
J
Jason Park 已提交
12
  }
J
Jason Park 已提交
13

J
Jason Park 已提交
14 15 16 17 18 19 20
  constructor(name) {
    super(name);

    if (this.isNew) initView(this);
  }

  _weight(target, weight) {
J
Jason Park 已提交
21 22 23 24 25 26
    this.manager.pushStep(this.capsule, {
      type: 'weight',
      target: target,
      weight: weight
    });
    return this;
J
Jason Park 已提交
27 28 29
  }

  _visit(target, source, weight) {
J
Jason Park 已提交
30 31 32 33 34 35 36
    this.manager.pushStep(this.capsule, {
      type: 'visit',
      target: target,
      source: source,
      weight: weight
    });
    return this;
J
Jason Park 已提交
37 38 39
  }

  _leave(target, source, weight) {
J
Jason Park 已提交
40 41 42 43 44 45 46
    this.manager.pushStep(this.capsule, {
      type: 'leave',
      target: target,
      source: source,
      weight: weight
    });
    return this;
J
Jason Park 已提交
47 48 49
  }

  processStep(step, options) {
J
Jason Park 已提交
50 51 52 53 54 55 56 57 58
    switch (step.type) {
      case 'weight':
        var targetNode = this.graph.nodes(this.n(step.target));
        if (step.weight !== undefined) targetNode.weight = refineByType(step.weight);
        break;
      case 'visit':
      case 'leave':
        var visit = step.type == 'visit';
        var targetNode = this.graph.nodes(this.n(step.target));
K
Kevin Nadro 已提交
59
        var color = visit ? step.weight === undefined ? this.selectColor : this.visitedColor : this.leftColor;
J
Jason Park 已提交
60 61 62 63 64 65 66 67 68 69 70 71
        targetNode.color = color;
        if (step.weight !== undefined) targetNode.weight = refineByType(step.weight);
        if (step.source !== undefined) {
          var edgeId = this.e(step.source, step.target);
          var edge = this.graph.edges(edgeId);
          edge.color = color;
          this.graph.dropEdge(edgeId).addEdge(edge);
        }
        if (this.logTracer) {
          var source = step.source;
          if (source === undefined) source = '';
          this.logTracer.print(visit ? source + ' -> ' + step.target : source + ' <- ' + step.target);
J
Jason Park 已提交
72
        }
J
Jason Park 已提交
73 74
        break;
      default:
J
Jason Park 已提交
75
        super.processStep(step, options);
J
Jason Park 已提交
76
    }
J
Jason Park 已提交
77
  }
J
Jason Park 已提交
78

J
Jason Park 已提交
79 80
  clear() {
    super.clear();
81

J
Jason Park 已提交
82
    this.clearWeights();
J
Jason Park 已提交
83 84 85
  }

  clearWeights() {
J
Jason Park 已提交
86 87 88
    this.graph.nodes().forEach(function (node) {
      node.weight = 0;
    });
J
Jason Park 已提交
89 90 91
  }

  drawEdgeWeight(edge, source, target, color, context, settings) {
J
Jason Park 已提交
92 93
    if (source == target)
      return;
J
Jason Park 已提交
94

J
Jason Park 已提交
95 96
    var prefix = settings('prefix') || '',
      size = edge[prefix + 'size'] || 1;
J
Jason Park 已提交
97

J
Jason Park 已提交
98 99
    if (size < settings('edgeLabelThreshold'))
      return;
J
Jason Park 已提交
100

J
Jason Park 已提交
101 102
    if (0 === settings('edgeLabelSizePowRatio'))
      throw '"edgeLabelSizePowRatio" must not be 0.';
J
Jason Park 已提交
103

J
Jason Park 已提交
104 105 106 107 108 109
    var fontSize,
      x = (source[prefix + 'x'] + target[prefix + 'x']) / 2,
      y = (source[prefix + 'y'] + target[prefix + 'y']) / 2,
      dX = target[prefix + 'x'] - source[prefix + 'x'],
      dY = target[prefix + 'y'] - source[prefix + 'y'],
      angle = Math.atan2(dY, dX);
J
Jason Park 已提交
110

J
Jason Park 已提交
111 112 113 114 115
    fontSize = (settings('edgeLabelSize') === 'fixed') ?
      settings('defaultEdgeLabelSize') :
    settings('defaultEdgeLabelSize') *
    size *
    Math.pow(size, -1 / settings('edgeLabelSizePowRatio'));
J
Jason Park 已提交
116

J
Jason Park 已提交
117
    context.save();
J
Jason Park 已提交
118

J
Jason Park 已提交
119 120 121 122 123 124
    if (edge.active) {
      context.font = [
        settings('activeFontStyle'),
        fontSize + 'px',
        settings('activeFont') || settings('font')
      ].join(' ');
J
Jason Park 已提交
125

J
Jason Park 已提交
126 127 128 129 130 131 132
      context.fillStyle = color;
    } else {
      context.font = [
        settings('fontStyle'),
        fontSize + 'px',
        settings('font')
      ].join(' ');
J
Jason Park 已提交
133

J
Jason Park 已提交
134 135
      context.fillStyle = color;
    }
J
Jason Park 已提交
136

J
Jason Park 已提交
137 138
    context.textAlign = 'center';
    context.textBaseline = 'alphabetic';
J
Jason Park 已提交
139

J
Jason Park 已提交
140 141 142 143 144 145 146
    context.translate(x, y);
    context.rotate(angle);
    context.fillText(
      edge.weight,
      0,
      (-size / 2) - 3
    );
J
Jason Park 已提交
147

J
Jason Park 已提交
148
    context.restore();
J
Jason Park 已提交
149 150 151
  }

  drawNodeWeight(node, context, settings) {
J
Jason Park 已提交
152 153 154
    var fontSize,
      prefix = settings('prefix') || '',
      size = node[prefix + 'size'];
J
Jason Park 已提交
155

J
Jason Park 已提交
156 157
    if (size < settings('labelThreshold'))
      return;
J
Jason Park 已提交
158

J
Jason Park 已提交
159 160 161
    fontSize = (settings('labelSize') === 'fixed') ?
      settings('defaultLabelSize') :
    settings('labelSizeRatio') * size;
J
Jason Park 已提交
162

J
Jason Park 已提交
163 164 165 166 167
    context.font = (settings('fontStyle') ? settings('fontStyle') + ' ' : '') +
      fontSize + 'px ' + settings('font');
    context.fillStyle = (settings('labelColor') === 'node') ?
      (node.color || settings('defaultNodeColor')) :
      settings('defaultLabelColor');
J
Jason Park 已提交
168

J
Jason Park 已提交
169 170 171 172 173 174 175
    context.textAlign = 'left';
    context.fillText(
      node.weight,
      Math.round(node[prefix + 'x'] + size * 1.5),
      Math.round(node[prefix + 'y'] + fontSize / 3)
    );
  }
J
Jason Park 已提交
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
}

const initView = (tracer) => {
  tracer.s.settings({
    edgeLabelSize: 'proportional',
    defaultEdgeLabelSize: 20,
    edgeLabelSizePowRatio: 0.8,
    funcLabelsDef(node, context, settings) {
      tracer.drawNodeWeight(node, context, settings);
      tracer.drawLabel(node, context, settings);
    },
    funcHoversDef(node, context, settings) {
      tracer.drawOnHover(node, context, settings, tracer.drawEdgeWeight);
    },
    funcEdgesArrow(edge, source, target, context, settings) {
      var color = tracer.getColor(edge, source, target, settings);
      tracer.drawArrow(edge, source, target, color, context, settings);
      tracer.drawEdgeWeight(edge, source, target, color, context, settings);
    }
  });
};
J
Jason Park 已提交
197

198
module.exports = WeightedDirectedGraphTracer;