source: js/viewer-f0/js/SmartLayout.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: 6.5 KB
Line 
1function SmartLayout(neu, con) {
2    this.neuroSL = neu;
3    this.neuroConnSL = con;
4    this.N = this.neuroSL.length;
5    this.blocks = [];
6    this.einfos = [];
7    var parent = this;
8
9    einfo = function () {
10        this.block = null;
11        this.x = null;
12        this.y = null;
13    }
14
15    this.Block = function (number) {
16        this.id = number;
17        this.elements = [];
18        this.w = 1;
19        this.h = 1;
20        this.minx = 0;
21        this.miny = 0;
22        this.maxx = 0;
23        this.maxy = 0;
24        this.addElement(number, 0, 0);
25        blocks[this.id] = this;
26        this.map = [];
27    }
28
29    this.Block.prototype.destroy = function () {
30        blocks[this.id] = 0;
31        this.freeMap();
32    }
33
34    this.Block.prototype.freeMap = function () {
35        if (this.map)
36            this.map = [];
37    }
38
39    this.Block.prototype.needMap = function () {
40        if (this.map)
41            return;
42        this.createMap();
43    }
44
45    this.Block.prototype.createMap = function () {
46        this.freeMap();
47        this.w = this.maxx - this.minx + 1;
48        this.h = this.maxy - this.miny + 1;
49        for (var i = 0; i < this.w * this.h; i++)
50            this.map.push(0);
51
52        for (var i = 0; i < this.elements.length; i++) {
53            var e = this.elements[i];
54            this.map[this.w * (parent.einfos[e].y - this.miny) + (parent.einfos[e].x - this.minx)] = 1;
55        }
56    }
57
58    this.Block.prototype.addElement = function (number, x, y) {
59        this.elements.push(number);
60        parent.einfos[number].x = x;
61        parent.einfos[number].y = y;
62        parent.einfos[number].block = this;
63    }
64}
65
66SmartLayout.prototype.create = function () {
67    /////////////////////////
68    //////Phase one//////////
69    /////////////////////////
70    blocks = new Array(this.N);
71    for (var i = 0; i < this.N; i++) {
72        this.einfos.push(new einfo())
73    }
74
75    for (var i = 0; i < this.N; i++)
76        this.setElement(i);
77
78    /////////////////////////
79    //////Phase two//////////
80    /////////////////////////
81
82    var first = null;
83    var el;
84    for (el = 0; el < this.N; el++) {
85        if (blocks[el]) {
86            first = blocks[el];
87            el++;
88            break;
89        }
90    }
91
92    while (el < this.N) {
93        if ((first.maxx - first.minx) > (first.maxy - first.miny)) {
94            var y = first.maxy + 2;
95            var x = first.minx;
96            var ex = first.maxx;
97            while (el < this.N) {
98                if (blocks[el]) {
99                    var dx = blocks[el].maxx - blocks[el].minx + 2;
100                    this.merge(first, blocks[el], x - blocks[el].minx, y - blocks[el].miny);
101                    x += dx;
102                    if (x > ex)
103                        break;
104                }
105                el++;
106            }
107        }
108        else {
109            var x = first.maxx + 2;
110            var y = first.miny;
111            var ey = first.maxy;
112            while (el < this.N) {
113                if (blocks[el]) {
114                    var dy = blocks[el].maxy - blocks[el].miny + 2;
115                    this.merge(first, blocks[el], x - blocks[el].minx, y - blocks[el].miny);
116                    y += dy;
117                    if (y > ey)
118                        break;
119                }
120                el++;
121            }
122        }
123    }
124
125    //Pokazanie wartości
126    if (first) // at this stage we have a single block containing all neurons
127    {
128        var i;
129        first.createMap();
130        for (i = 0; i < first.elements.length; i++) {
131            el = first.elements[i];
132        }
133        delete first;
134    }
135}
136
137
138SmartLayout.prototype.canMerge = function (block, block2, dx, dy) {
139    var x1, y1, x2, y2;
140
141    x1 = Math.max(0, block2.minx - block.minx + dx);
142    x2 = Math.min(block.maxx - block.minx, -block.minx + dx + block2.maxx);
143    if (x1 > x2)
144        return 1;
145
146
147    y1 = Math.max(0, block2.miny - block.miny + dy);
148    y2 = Math.min(block.maxy - block.miny, -block.miny + dy + block2.maxy);
149    if (y1 > y2)
150        return 1;
151
152
153    var x, y;
154    dx += block2.minx - block.minx; //dx,dy relative to minx,miny
155    dy += block2.miny - block.miny;
156
157    block.createMap();
158    block2.createMap();
159
160    for (y = y1; y <= y2; y++) {
161        for (x = x1; x <= x2; x++)
162            if (block.map[block.w * y + x] && block2.map[block2.w * (y - dy) + (x - dx)])
163                return 0;
164    }
165    return 1;
166
167}
168
169SmartLayout.prototype.merge = function (block, block2, dx, dy) {
170
171    if (!this.canMerge(block, block2, dx, dy))
172        return 0;
173
174    block.freeMap();
175
176
177    for (var i = 0; i < block2.elements.length; i++) {
178        var e = block2.elements[i];
179        block.addElement(e, this.einfos[e].x + dx, this.einfos[e].y + dy);
180    }
181
182    block.minx = Math.min(block.minx, dx + block2.minx);
183    block.miny = Math.min(block.miny, dy + block2.miny);
184    block.maxx = Math.max(block.maxx, dx + block2.maxx);
185    block.maxy = Math.max(block.maxy, dy + block2.maxy);
186
187
188    block2.destroy();
189    delete block2;
190    return 1;
191}
192
193SmartLayout.prototype.connectAsInput = function (e, e2) {
194    var b, b2;
195
196    b = this.einfos[e].block;
197
198
199    if (!this.einfos[e2].block)
200        new Block(e2);
201
202    b2 = this.einfos[e2].block;
203
204    if (b == b2) {
205        return;
206    }
207    var dx, dy;
208    dx = this.einfos[e].x - this.einfos[e2].x;
209    dy = this.einfos[e].y - this.einfos[e2].y;
210
211    if (this.merge(b, b2, dx - 1, dy))
212        return;
213
214    for (var proba = 1; ; proba++) {
215        if (this.merge(b, b2, dx - 1, dy - proba))
216            return;
217        if (this.merge(b, b2, dx - 1, dy + proba))
218            return;
219    }
220}
221
222SmartLayout.prototype.setElement = function (e) {
223    if (this.einfos[e].block != null) {
224        return;
225    }
226
227    new this.Block(e);
228
229    var n = this.getNumOfInCon(e);
230    for (var we = 0; we < n; we++) {
231        var e2 = this.getLink(e, we);
232        if (e2 < 0)
233            continue;
234        if (e == e2)
235            continue;
236        this.setElement(e2);
237        this.connectAsInput(e, e2);
238    }
239}
240
241SmartLayout.prototype.getNumOfInCon = function (nr) {
242    var number = 0;
243    for (var i = 0; i < this.neuroConnSL.length; i++) {
244        if (this.neuroConnSL[i].getDestination() == nr)
245            number++;
246    }
247    return number;
248}
249
250SmartLayout.prototype.getLink = function (destination, number) {
251    var temp = 0;
252    for (var i = 0; i < this.neuroConnSL.length; i++) {
253        if (this.neuroConnSL[i].getDestination() == destination) {
254
255            if (temp == number)
256                return this.neuroConnSL[i].getSource();
257            else
258                temp++;
259        }
260    }
261}
Note: See TracBrowser for help on using the repository browser.