source: js/viewer-f0/js/NeuronDrawer.js @ 216

Last change on this file since 216 was 216, checked in by mmichalski, 10 years ago

Fix bug with many SmartLayouts? on the same page

  • Property svn:eol-style set to native
File size: 8.5 KB
Line 
1function NeuronDrawer(contextName, width, height) {
2    this._canvasWidth = width;
3    this._canvasHeight = height;
4    this._containerContextName = contextName;
5    this._unknown_symbol=[1,4, 25,25, 75,25, 75,75, 25,75, 25,25];
6    this._neuron_symbol=[1,4, 75,50, 25,0, 25,99, 75,50, 100,50];
7    this._inputonly_symbol=[1,5, 25,40, 35,40, 45,50, 35,60, 25,60, 25,40];
8    this._outputonly_symbol=[1,7, 75,50, 75,60, 55,60, 65,50, 55,40, 75,40, 75,50, 100,50];
9    this._neurons = undefined;
10    this._SCALE = 150;
11    this._scale = 1;
12    this._min_scale = 0.1;
13    this._lineDebug = false;
14    //Kinetic.js
15    this._stage = undefined;
16    this._layer = undefined;
17}
18
19NeuronDrawer.prototype.initializeNewCanvas = function () {
20
21    if(typeof (this._canvasWidth) == "undefined" && typeof (this._canvasHeight) == "undefined")
22        {
23        var div = $("#" + this._containerContextName);
24        this._canvasWidth = div.width();
25        this._canvasHeight = div.height();
26    }
27
28    this._stage = new Kinetic.Stage({
29        container: this._containerContextName,
30        width: this._canvasWidth,
31        height: this._canvasHeight,
32        draggable: true
33    });
34
35    this._layer = new Kinetic.Layer();
36
37    this._addZoom();
38}
39
40NeuronDrawer.prototype._addZoom = function(){
41    var self = this;
42
43    var isFirefox = (/Firefox/i.test(navigator.userAgent)) ? true : false;
44
45    var mousewheelevt= isFirefox ? "DOMMouseScroll" : "mousewheel" //FF doesn't recognize mousewheel as of FF3.x
46
47    document.getElementById(this._containerContextName).addEventListener(mousewheelevt,function(e){
48        e.preventDefault();
49
50        var zoomAmount = 0;
51        if(!isFirefox)
52            zoomAmount = e.wheelDelta * 0.001;
53        else
54            zoomAmount = e.detail * -0.12;
55
56        var newScale = self._stage.scale();
57        newScale.x += zoomAmount;
58        newScale.y += zoomAmount;
59
60        self._stage.scale(newScale)
61        self._stage.draw();
62    });
63}
64
65NeuronDrawer.prototype.drawNeuralNetwork = function (neurons, connections, layouts, classes) {
66
67    this._neurons = [];
68    var offsetFactor = 0;
69
70    for (var i = 0; i < layouts.length; i++) {
71        var scheme = undefined;
72        scheme = this._chooseSchema(i,neurons, connections, classes);
73
74        var neuronData = this._getSize(scheme);
75        neuronData.scheme = scheme;
76        neuronData.x += layouts[i].x * this._SCALE;
77        neuronData.y += -layouts[i].y * this._SCALE;
78
79        this._neurons.push(neuronData);
80        this.drawNeuron(layouts[i].x * this._SCALE, -layouts[i].y * this._SCALE, scheme);
81
82        offsetFactor = Math.min(offsetFactor, layouts[i].x);
83    }
84
85    this._layer.offsetX(offsetFactor * this._SCALE);
86
87    for (var i = 0; i < connections.length; i++)
88        this.drawConnection(i, neurons, connections, layouts);
89}
90
91NeuronDrawer.prototype.drawNeuron = function (x, y, scheme) {
92    var points = [];
93
94    var position = 0;
95    var noOfBlocks = scheme[position++];//number of "blocks" to draw
96    var noOfLines = 0;//number of line to draw
97    for (var i = 0; i < noOfBlocks; i++) {
98        noOfLines = scheme[position++];
99
100        for (var j = 0; j < noOfLines; j++) {
101            points.push(scheme[position++]+x);
102            points.push(scheme[position++]+y);
103        }
104
105        points.push(scheme[position++]+x);
106        points.push(scheme[position++]+y);
107
108        var symbol = new Kinetic.Line({
109            points: points,
110            stroke: 'black',
111            strokeWidth: 1
112        });
113
114        symbol.move({x:0, y: 0});
115        var self = this;
116        symbol.on('mousemove', function(){
117            var mousePos = self._stage.getPointerPosition();
118            var x = mousePos.x;
119            var y = mousePos.y;
120            console.log(x,y);
121        });
122
123        this._layer.add(symbol);
124        points = [];
125    }
126}
127
128NeuronDrawer.prototype._getConnection = function(connections, id, number){
129
130    var counter = 0;
131    for(var i = 0; i < connections.length; i++)
132    {
133        if(connections[i].getDestination() == id)
134            {
135            if(counter == number)
136                return connections[i].getSource();
137            else
138                counter++;
139        }
140    }
141}
142
143NeuronDrawer.prototype.drawConnection = function (id, neurons, connections, einfos) {
144
145    var n2;
146    neuroId = connections[id].getDestination();
147    //this is hack trick to change order of inputs
148    var maxVal = this._inputY(this._getNumberOfInputs(neuroId,connections), connections, neuroId);
149
150    for(var input = 0; input < this._getNumberOfInputs(neuroId,connections); input++)
151    {
152        n2 = this._neurons[this._getConnection(connections, neuroId, input)];
153        var points = [];
154
155        var yw = this._inputY(input, connections, neuroId);
156        var xw = (maxVal-yw) / 4;
157
158        yw += this._neurons[neuroId].y;//add position of object to y
159
160        //Inputs
161        points.push(this._neurons[neuroId].x);//x
162        points.push(yw);//y
163
164        points.push(this._neurons[neuroId].x - xw);//x
165        points.push(yw);//y
166
167        //straight line to second neuron
168        if(this._lineDebug || (this._neurons[neuroId].x > n2.x))
169        {
170            points.push(n2.x+n2.sizeX);
171            points.push(n2.y + n2.sizeY/2);
172        }
173        else
174        {
175            //U - shape
176            //Vertical
177            points.push(this._neurons[neuroId].x - xw);//x
178            points.push(n2.y + n2.sizeY + (input+1)*5);//y
179
180            //Horizontal
181            points.push(n2.x + n2.sizeX);//x
182            points.push(n2.y + n2.sizeY + (input+1)*5);//y
183
184            //Vertical
185            points.push(n2.x + n2.sizeX);//x
186            points.push(n2.y + n2.sizeY/2);//y
187        }
188
189        var line = new Kinetic.Line({
190            points: points,
191            stroke: 'black',
192            strokeWidth: 1
193        });
194        this._layer.add(line);
195    }
196
197}
198
199NeuronDrawer.prototype._inputY = function(number, connections, id){
200    return ((1 + number)* this._neurons[id].sizeY) / ((this._getNumberOfInputs(id, connections)) + 1);
201}
202
203NeuronDrawer.prototype.finalize = function()
204{
205    this._stage.add(this._layer);
206}
207
208NeuronDrawer.prototype._getNumberOfInputs = function(number, connections){
209
210    var counter = 0;
211
212    for(var i = 0; i < connections.length; i++){
213        if(connections[i].getDestination() == number)
214            counter++;
215    }
216
217    return counter;
218}
219
220NeuronDrawer.prototype._getNumberOfOutputs = function(number, connections){
221    var counter = 0;
222
223    for(var i = 0; i < connections.length; i++){
224        if(connections[i].getSource() == number)
225            counter++;
226    }
227
228    return counter;
229}
230
231
232
233NeuronDrawer.prototype._chooseSchema = function(number, neurons, connections, classes)
234{
235    var schema = this._unknown_symbol;
236    var type = neurons[number].getSchemeID();
237
238    if(type != undefined)
239    {
240        if(classes[type].getScheme().length != 0)
241        {
242            if(this._getNumberOfInputs(number, connections) == 0)
243                schema = this._outputonly_symbol;
244            else if (this._getNumberOfOutputs(number, connections) == 0)
245                schema = this._inputonly_symbol;
246            else
247                schema = this._neuron_symbol;
248        }
249    }
250
251    return schema;
252}
253
254NeuronDrawer.prototype._getSize = function(scheme)
255{
256    var neuron = {sizeX: 0, sizeY: 0, x: 0, y: 0};
257
258
259    var minX = Number.MAX_VALUE;
260    var maxX = -1;
261
262    var minY = Number.MAX_VALUE;
263    var maxY = -1;
264
265    var position = 0;
266    var noOfBlocks = scheme[position++];//number of "blocks" to draw
267    var noOfLines = 0;//number of line to draw
268
269    for (var i = 0; i < noOfBlocks; i++) {
270        noOfLines = scheme[position++];
271
272        for (var j = 0; j < noOfLines; j++) {
273
274
275            if(scheme[position] > maxX)
276                maxX = scheme[position];
277            if(scheme[position] < minX)
278                minX = scheme[position];
279            position++;
280
281            if(scheme[position] > maxY)
282                maxX = scheme[position];
283            if(scheme[position] < minY)
284                minY = scheme[position];
285            position++;
286
287
288            if(scheme[position] > maxX)
289                maxX = scheme[position];
290            if(scheme[position] < minX)
291                minX = scheme[position];
292            position++;
293
294            if(scheme[position] > maxY)
295                maxY = scheme[position];
296            if(scheme[position] < minY)
297                minY = scheme[position];
298            position++;
299
300            position = position - 2;
301        }
302        position = position + 2;//move to value which define number of lines to draw
303        neuron.sizeX = maxX - minX;
304        neuron.sizeY = maxY - minY;
305        neuron.x = minX;
306        neuron.y = minY;
307    }
308    return neuron;
309}
Note: See TracBrowser for help on using the repository browser.