function NeuronDrawer(contextName, width, height) { this._canvasWidth = width; this._canvasHeight = height; this._containerContextName = contextName; this._unknown_symbol=[1,4, 25,25, 75,25, 75,75, 25,75, 25,25]; this._neuron_symbol=[1,4, 75,50, 25,0, 25,99, 75,50, 100,50]; this._inputonly_symbol=[1,5, 25,40, 35,40, 45,50, 35,60, 25,60, 25,40]; this._outputonly_symbol=[1,7, 75,50, 75,60, 55,60, 65,50, 55,40, 75,40, 75,50, 100,50]; this._neurons = undefined; this._SCALE = 150; this._scale = 1; this._min_scale = 0.1; //Kinetic.js this._stage = undefined; this._layer = undefined; } NeuronDrawer.prototype.initializeNewCanvas = function () { this._stage = new Kinetic.Stage({ container: this._containerContextName, width: this._canvasWidth, height: this._canvasHeight, draggable: true }); this._layer = new Kinetic.Layer(); this._addZoom(); } NeuronDrawer.prototype._addZoom = function(){ var self = this; var isFirefox = (/Firefox/i.test(navigator.userAgent)) ? true : false; var mousewheelevt= isFirefox ? "DOMMouseScroll" : "mousewheel" //FF doesn't recognize mousewheel as of FF3.x document.getElementById(this._containerContextName).addEventListener(mousewheelevt,function(e){ e.preventDefault(); var zoomAmount = 0; if(!isFirefox) zoomAmount = e.wheelDelta * 0.001; else zoomAmount = e.detail * -0.12; var newScale = self._stage.scale(); newScale.x += zoomAmount; newScale.y += zoomAmount; self._stage.scale(newScale) self._stage.draw(); }); } NeuronDrawer.prototype.drawNeuralNetwork = function (neurons, connections, layouts, classes) { this._neurons = []; var offsetFactor = 0; for (var i = 0; i < layouts.length; i++) { var scheme = undefined; scheme = this._chooseSchema(i,neurons, connections, classes); var neuronData = this._getSize(scheme); neuronData.scheme = scheme; neuronData.x += layouts[i].x * this._SCALE; neuronData.y += -layouts[i].y * this._SCALE; this._neurons.push(neuronData); this.drawNeuron(layouts[i].x * this._SCALE, -layouts[i].y * this._SCALE, scheme); offsetFactor = Math.min(offsetFactor, layouts[i].x); } this._layer.offsetX(offsetFactor * this._SCALE); for (var i = 0; i < connections.length; i++) this.drawConnection(i, neurons, connections, einfos); } NeuronDrawer.prototype.drawNeuron = function (x, y, scheme) { var points = []; var position = 0; var noOfBlocks = scheme[position++];//number of "blocks" to draw var noOfLines = 0;//number of line to draw for (var i = 0; i < noOfBlocks; i++) { noOfLines = scheme[position++]; for (var j = 0; j < noOfLines; j++) { points.push(scheme[position++]+x); points.push(scheme[position++]+y); } points.push(scheme[position++]+x); points.push(scheme[position++]+y); var symbol = new Kinetic.Line({ points: points, stroke: 'black', strokeWidth: 1 }); symbol.move({x:0, y: 0}); var self = this; symbol.on('mousemove', function(){ var mousePos = self._stage.getPointerPosition(); var x = mousePos.x; var y = mousePos.y; console.log(x,y); }); this._layer.add(symbol); points = []; } } NeuronDrawer.prototype._getConnection = function(connections, id, number){ var counter = 0; for(var i = 0; i < connections.length; i++) { if(connections[i].getDestination() == id) { if(counter == number) return connections[i].getSource(); else counter++; } } } NeuronDrawer.prototype.drawConnection = function (id, neurons, connections, einfos) { var n2; neuroId = connections[id].getDestination(); //this is hack trick to change order of inputs var maxVal = this._inputY(this._getNumberOfInputs(neuroId,connections), connections, neuroId); for(var input = 0; input < this._getNumberOfInputs(neuroId,connections); input++) { n2 = this._neurons[this._getConnection(connections, neuroId, input)]; var points = []; var yw = this._inputY(input, connections, neuroId); var xw = (maxVal-yw) / 4; yw += this._neurons[neuroId].y;//add position of object to y points.push(this._neurons[neuroId].x);//x points.push(yw);//y points.push(this._neurons[neuroId].x - xw);//x points.push(yw);//y points.push(n2.x+n2.sizeX); points.push(n2.y + n2.sizeY/2); /*if(diagram?) { //straight forward } else { //U-shape }*/ var line = new Kinetic.Line({ points: points, stroke: 'black', strokeWidth: 1 }); this._layer.add(line); } } NeuronDrawer.prototype._inputY = function(number, connections, id){ return ((1 + number)* this._neurons[id].sizeY) / ((this._getNumberOfInputs(id, connections)) + 1); } NeuronDrawer.prototype.finalize = function() { this._stage.add(this._layer); } NeuronDrawer.prototype._getNumberOfInputs = function(number, connections){ var counter = 0; for(var i = 0; i < connections.length; i++){ if(connections[i].getDestination() == number) counter++; } return counter; } NeuronDrawer.prototype._getNumberOfOutputs = function(number, connections){ var counter = 0; for(var i = 0; i < connections.length; i++){ if(connections[i].getSource() == number) counter++; } return counter; } NeuronDrawer.prototype._chooseSchema = function(number, neurons, connections, classes) { var schema = this._unknown_symbol; var type = neurons[number].getSchemeID(); if(type != undefined) { if(classes[type].getScheme().length != 0) { if(this._getNumberOfInputs(number, connections) == 0) schema = this._outputonly_symbol; else if (this._getNumberOfOutputs(number, connections) == 0) schema = this._inputonly_symbol; else schema = this._neuron_symbol; } } return schema; } NeuronDrawer.prototype._getSize = function(scheme) { var neuron = {sizeX: 0, sizeY: 0, x: 0, y: 0}; var minX = Number.MAX_VALUE; var maxX = -1; var minY = Number.MAX_VALUE; var maxY = -1; var position = 0; var noOfBlocks = scheme[position++];//number of "blocks" to draw var noOfLines = 0;//number of line to draw for (var i = 0; i < noOfBlocks; i++) { noOfLines = scheme[position++]; for (var j = 0; j < noOfLines; j++) { if(scheme[position] > maxX) maxX = scheme[position]; if(scheme[position] < minX) minX = scheme[position]; position++; if(scheme[position] > maxY) maxX = scheme[position]; if(scheme[position] < minY) minY = scheme[position]; position++; if(scheme[position] > maxX) maxX = scheme[position]; if(scheme[position] < minX) minX = scheme[position]; position++; if(scheme[position] > maxY) maxY = scheme[position]; if(scheme[position] < minY) minY = scheme[position]; position++; position = position - 2; } position = position + 2;//move to value which define number of lines to draw neuron.sizeX = maxX - minX; neuron.sizeY = maxY - minY; neuron.x = minX; neuron.y = minY; } return neuron; }