weighted_directed_graph.js 5.2 KB
Newer Older
1
const DirectedGraphTracer = require('./directed_graph');
N
nem035 已提交
2 3

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

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

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

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

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

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

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

  processStep(step, options) {
J
Jason Park 已提交
48 49 50 51 52 53 54 55 56
    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));
J
Jason Park 已提交
57
        var color = visit ? step.weight === undefined ? this.color.selected : this.color.visited : this.color.left;
J
Jason Park 已提交
58 59 60 61 62 63 64 65 66 67 68 69
        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 已提交
70
        }
J
Jason Park 已提交
71 72
        break;
      default:
J
Jason Park 已提交
73
        super.processStep(step, options);
J
Jason Park 已提交
74
    }
J
Jason Park 已提交
75
  }
J
Jason Park 已提交
76

J
Jason Park 已提交
77 78
  clear() {
    super.clear();
79

J
Jason Park 已提交
80
    this.clearWeights();
J
Jason Park 已提交
81 82 83
  }

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

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

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

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

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

J
Jason Park 已提交
102 103 104 105 106 107
    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 已提交
108

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

J
Jason Park 已提交
115
    context.save();
J
Jason Park 已提交
116

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

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

J
Jason Park 已提交
132 133
      context.fillStyle = color;
    }
J
Jason Park 已提交
134

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

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

J
Jason Park 已提交
146
    context.restore();
J
Jason Park 已提交
147 148 149
  }

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

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

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

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

J
Jason Park 已提交
167 168 169 170 171 172 173
    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 已提交
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
}

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 已提交
195

196
module.exports = WeightedDirectedGraphTracer;