Completed
Pull Request — develop (#75)
by
unknown
01:28
created

forcegraph.js ➔ ... ➔ d3.strength   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
c 0
b 0
f 0
nc 2
dl 0
loc 6
rs 9.4285
nop 1
1
define(['d3', 'helper'], function (d3, helper) {
2
  'use strict';
3
4
  return function (config, linkScale, sidebar) {
5
    var self = this;
6
    var el;
7
    var canvas;
8
    var ctx;
9
    var force;
10
    var forceLink;
11
    var scale = 1;
12
    var translateX = sidebar();
13
    var translateY = 0;
14
    // var highlight;
15
    var intNodes = [];
16
    var dictNodes = {};
17
    var intLinks = [];
18
19
    /*
20
    var unknownColor = '#D10E2A';
21
    var uplinkColor = '#5BAAEB';
22
    var highlightColor = 'rgba(252, 227, 198, 0.15)';
23
    var nodeRadius = 6;
24
    var unseenColor = '#FFA726';
25
    */
26
    var nonUplinkColor = '#F2E3C6';
27
    var locationColor = '#00ff00';
28
    var noLocationColor = '#0000ff';
29
    var clientColor = 'rgba(230, 50, 75, 1.0)';
30
    var cableColor = '#50B0F0';
31
32
    function resizeCanvas() {
33
      var r = window.devicePixelRatio;
34
      canvas.width = el.offsetWidth * r;
35
      canvas.height = el.offsetHeight * r;
36
      canvas.style.width = el.offsetWidth + 'px';
37
      canvas.style.height = el.offsetHeight + 'px';
38
      ctx.setTransform(1, 0, 0, 1, 0, 0);
39
      ctx.scale(r, r);
40
    }
41
42
    function drawLink(d) {
43
      ctx.beginPath();
44
      ctx.moveTo(d.source.x, d.source.y);
45
      ctx.lineTo(d.target.x, d.target.y);
46
      ctx.strokeStyle = d.o.type === 'Kabel' ? cableColor : d.color;
47
      ctx.globalAlpha = d.o.type === 'fastd' || d.o.type === 'L2TP' ? 0.2 : 0.8;
48
      ctx.lineWidth = d.o.type === 'fastd' || d.o.type === 'L2TP' ? 1.5 : 2.5;
49
      ctx.stroke();
50
    }
51
52
    function drawNode(d) {
53
      ctx.beginPath();
54
      ctx.moveTo(d.x + 3, d.y);
55
      ctx.arc(d.x, d.y, 6, 0, 2 * Math.PI);
56
      ctx.fillStyle = d.o.node.nodeinfo.location ? locationColor : noLocationColor;
57
      ctx.strokeStyle = nonUplinkColor;
58
      ctx.lineWidth = 5;
59
      ctx.globalAlpha = 1;
60
      ctx.fill();
61
      ctx.stroke();
62
      if (scale > 1) {
63
        ctx.beginPath();
64
        helper.positionClients(ctx, d, Math.PI, d.o.node.statistics.clients, 15);
65
        ctx.fillStyle = clientColor;
66
        ctx.fill();
67
        ctx.beginPath();
68
        var name = d.o.node_id;
69
        if (d.o.node && d.o.node.nodeinfo) {
70
          name = d.o.node.nodeinfo.hostname;
71
        }
72
        ctx.textAlign = 'center';
73
        ctx.fillStyle = '#fff';
74
        ctx.fillText(name, d.x, d.y + 20);
75
      }
76
    }
77
78
    function redraw() {
79
      ctx.save();
80
      ctx.clearRect(0, 0, canvas.width, canvas.height);
81
      ctx.translate(translateX, translateY);
82
      ctx.scale(scale, scale);
83
84
      intLinks.forEach(drawLink);
85
      intNodes.forEach(drawNode);
86
87
      ctx.restore();
88
    }
89
90
    el = document.createElement('div');
91
    el.classList.add('graph');
92
93
    forceLink = d3.forceLink()
94
     .distance(function (d) {
95
       if (d.o.type === 'fastd' || d.o.type === 'L2TP') {
96
         return 0;
97
       }
98
       return 75;
99
     })
100
     .strength(function (d) {
101
       if (d.o.type === 'fastd' || d.o.type === 'L2TP') {
102
         return 0.02;
103
       }
104
       return Math.max(0.5, 1 / d.o.tq);
105
     });
106
107
    var zoom = d3.zoom()
108
         .scaleExtent([1 / 3, 3])
109
         .on('zoom', function () {
110
           scale = d3.event.transform.k;
111
           translateX = d3.event.transform.x;
112
           translateY = d3.event.transform.y;
113
           redraw();
114
         });
115
116
117
    force = d3.forceSimulation()
118
      .force('link', forceLink)
119
      .force('charge', d3.forceManyBody())
120
      .force('center', d3.forceCenter())
121
      .on('tick', redraw);
122
123
    canvas = d3.select(el)
124
      .call(zoom)
125
      .append('canvas')
126
      .node();
127
128
    ctx = canvas.getContext('2d');
129
130
    window.addEventListener('resize', function () {
131
      resizeCanvas();
132
      redraw();
133
    });
134
135
    self.setData = function setData(data) {
136
      intNodes = data.graph.nodes.map(function (d) {
137
        var e;
138
        if (d.id in dictNodes) {
139
          e = dictNodes[d.id];
140
        } else {
141
          e = {};
142
          dictNodes[d.id] = e;
143
        }
144
145
        e.o = d;
146
147
        return e;
148
      });
149
150
      intLinks = data.graph.links.map(function (d) {
151
        var e = {};
152
        e.o = d;
153
        e.source = dictNodes[d.source.id];
154
        e.target = dictNodes[d.target.id];
155
        e.color = linkScale(d.tq).hex();
156
157
        return e;
158
      });
159
160
      force.nodes(intNodes);
161
      forceLink.links(intLinks);
162
163
      force.restart();
164
      resizeCanvas();
165
    };
166
167
    self.resetView = function resetView() {
168
169
    };
170
171
    self.gotoNode = function gotoNode(d) {
172
      highlight = { type: 'node', o: d };
0 ignored issues
show
Bug introduced by
The variable highlight seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.highlight.
Loading history...
173
    };
174
175
    self.gotoLink = function gotoLink(d) {
176
      highlight = { type: 'link', o: d };
0 ignored issues
show
Bug introduced by
The variable highlight seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.highlight.
Loading history...
177
    };
178
179
    self.destroy = function destroy() {
180
      force.stop();
181
      canvas.remove();
182
      force = null;
183
184
      if (el.parentNode) {
185
        el.parentNode.removeChild(el);
186
      }
187
    };
188
189
    self.render = function render(d) {
190
      d.appendChild(el);
191
      resizeCanvas();
192
    };
193
194
    return self;
195
  };
196
});
197