2 normalize: function(node) {
3 if (node.component_name) { //"wsn430-11.devlille.iot-lab.info",
4 var s = node.component_name.split('.');
5 if (s[2] == 'iot-lab' && s[3] == 'info') {
6 node.arch = s[0].split('-')[0];
7 node.id = s[0].split('-')[1];
16 Senslab.Map = function() {
20 "Suspected": 0xFF3030,
30 function Map($container) {
39 this.pointerDetectRay = new THREE.Raycaster();
40 this.pointerDetectRay.ray.direction.set(0, -1, 0);
41 this.projector = new THREE.Projector();
42 this.mouse2D = new THREE.Vector3(0, 0, 0);
44 this.renderer = new THREE.CanvasRenderer();
45 this.renderer.setSize(this.width, this.height);
47 this.camera = new THREE.PerspectiveCamera(75, this.width / this.height, 1, 10000);
49 this.scene = new THREE.Scene();
50 this.scene.add(this.camera);
52 this.updatePosition();
57 this.$nodeInputs = {};
59 $.each(archs, function(i, arch) {
60 self.nodes[arch] = [];
61 self.$nodeInputs[arch] = $("<input type='text' placeholder='" + arch + "'>")
64 self.nodes[arch] = expand($(this).val());
65 self.updateColor(arch);
69 var $canvas = $(this.renderer.domElement)
70 .mousemove(function(e) {
71 self.mouse2D.x = ((e.pageX - $canvas.offset().left) / $canvas.width()) * 2 - 1;
72 self.mouse2D.y = -((e.pageY - $canvas.offset().top) / $canvas.height()) * 2 + 1;
75 self.theta -= e.pageX - self.mouse2D.pageX;
76 self.phi += e.pageY - self.mouse2D.pageY;
82 self.mouse2D.pageX = e.pageX;
83 self.mouse2D.pageY = e.pageY;
85 self.updatePosition();
88 }).mousedown(function(e) {
92 self.pointerDetectRay = self.projector.pickingRay(self.mouse2D.clone(), self.camera);
93 var intersects = self.pointerDetectRay.intersectObjects(self.scene.children);
94 if (intersects.length > 0 && self.select(intersects[0].object)) {
95 var node = intersects[0].object;
96 var $nodeInput = self.$nodeInputs[node.arch];
97 $nodeInput.val(factorize(self.nodes[node.arch]));
102 self.mouse2D.pageX = e.pageX;
103 self.mouse2D.pageY = e.pageY;
107 }).mouseup(function(e) {
114 }).mouseleave(function(e) {
116 }).mousewheel(function(e, delta) {
118 self.distance += delta * 5;
119 self.updatePosition();
123 $container.append($canvas);
126 function getCenter(nodes) {
127 var xmin = 0, ymin = 0, zmin = 0;
128 var xmax = 0, ymax = 0, zmax = 0;
130 for (var i = 0; i < nodes.length; ++i) {
131 if (nodes[i].x > xmax) xmax = nodes[i].x;
132 if (nodes[i].x < xmin) xmin = nodes[i].x;
133 if (nodes[i].y > ymax) ymax = nodes[i].y;
134 if (nodes[i].y < ymin) ymin = nodes[i].y;
135 if (nodes[i].z > zmax) zmax = nodes[i].z;
136 if (nodes[i].z < zmin) zmin = nodes[i].z;
138 return {x: (xmax + xmin) / 2, y: (ymax + ymin) / 2, z: (zmax + zmin) / 2};
141 function setColor(node) {
142 node.material.color.setHex(colors[node.boot_state] || colors["Selected"]);
145 Map.prototype.addNodes = function(nodes) {
146 var center = getCenter(nodes);
147 var program = function(context) {
149 context.arc(0, 0, 1, 0, Math.PI * 2, true);
154 for(var i = 0; i < nodes.length; ++i) {
155 var material = new THREE.ParticleCanvasMaterial({program: program});
156 var particle = new THREE.Particle(material);
158 particle.id = nodes[i].id;
159 particle.arch = nodes[i].arch;
160 particle.boot_state = nodes[i].boot_state;
161 particle.position.x = (nodes[i].x - center.x) * 10;
162 particle.position.y = (nodes[i].y - center.y) * 10;
163 particle.position.z = (nodes[i].z - center.z) * 10;
164 particle.scale.x = particle.scale.y = 1;
166 this.scene.add(particle);
171 Map.prototype.select = function(node) {
172 if (node.boot_state == "Suspected") {
174 } else if (node.boot_state == "Alive") {
175 var array = this.nodes[node.arch];
176 array.push(parseInt(node.id));
177 array.sort(nodeSort);
178 node.boot_state = "Selected";
182 var array = this.nodes[node.arch];
183 var index = $.inArray(parseInt(node.id), array);
184 index > -1 && array.splice(index, 1);
185 node.boot_state = "Alive";
191 function factorize(nodes) {
194 var intervalStart = 0;
196 for (var i = 0; i < nodes.length; ++i) {
198 if (nodes[i] == prev + 1) {
201 factorized.push(intervalStart + "-" + prev);
206 if (nodes[i] == prev + 1) {
207 intervalStart = prev;
210 prev && factorized.push(prev);
215 factorized.push(intervalStart ? intervalStart + "-" + prev : prev);
216 return factorized.join(",");
219 function expand(input) {
220 var factorized = input.split(",");
222 for (var i = 0; i < factorized.length; ++i) {
223 var d = factorized[i].split("-");
225 for (var j = parseInt(d[0]); j < parseInt(d[1]) + 1; j++) {
229 expanded.push(parseInt(factorized[i]));
232 expanded.sort(nodeSort);
233 for (var i = 1; i < expanded.length; i++) {
234 if (expanded[i] == expanded[i - 1]) {
235 expanded.splice(i--, 1);
241 function nodeSort(a, b) {
245 Map.prototype.updateColor = function(arch) {
246 var nodes = this.scene.children;
247 for (var i = 0; i < nodes.length; ++i) {
248 if (nodes[i].arch == arch && nodes[i].boot_state != "Suspected") {
249 var id = parseInt(nodes[i].id);
250 var array = this.nodes[arch];
251 nodes[i].boot_state = $.inArray(id, array) == -1 ? "Alive" : "Selected";
258 Map.prototype.updatePosition = function() {
259 this.camera.position.x = this.distance * Math.sin(this.theta * Math.PI / 360) * Math.cos(this.phi * Math.PI / 360);
260 this.camera.position.y = this.distance * Math.sin(this.phi * Math.PI / 360);
261 this.camera.position.z = this.distance * Math.cos(this.theta * Math.PI / 360) * Math.cos(this.phi * Math.PI / 360);
262 this.camera.lookAt(this.scene.position);
263 this.camera.updateMatrix();
266 Map.prototype.update = function() {
267 this.renderer.render(this.scene, this.camera);