2 normalize: function(node) {
5 if (node.component_name) { // wsn430-11.devlille.iot-lab.info
6 info = node.component_name.split(".");
7 } else if (node.hrn) { // iotlab.a8-11\.devgrenoble\.iot-lab\.info
8 var info = node.hrn.split("\\.");
9 info[0] = info[0].split(".")[1];
12 if (info && info[2] == "iot-lab" && info[3] == "info") {
13 node.arch = info[0].split("-")[0];
14 node.id = info[0].split("-")[1];
18 console.warn("could not normalize node :");
25 Senslab.Map = function() {
29 "Suspected": 0xFF3030,
39 function Map($container) {
48 this.pointerDetectRay = new THREE.Raycaster();
49 this.pointerDetectRay.ray.direction.set(0, -1, 0);
50 this.projector = new THREE.Projector();
51 this.mouse2D = new THREE.Vector3(0, 0, 0);
53 this.renderer = new THREE.CanvasRenderer();
54 this.renderer.setSize(this.width, this.height);
56 this.camera = new THREE.PerspectiveCamera(75, this.width / this.height, 1, 10000);
58 this.scene = new THREE.Scene();
59 this.scene.add(this.camera);
61 this.updatePosition();
66 this.$nodeInputs = {};
68 $.each(archs, function(i, arch) {
69 self.nodes[arch] = [];
70 self.$nodeInputs[arch] = $("<input type='text' placeholder='" + arch + "'>")
73 self.nodes[arch] = expand($(this).val());
74 self.updateColor(arch);
78 var $canvas = $(this.renderer.domElement)
79 .mousemove(function(e) {
80 self.mouse2D.x = ((e.pageX - $canvas.offset().left) / $canvas.width()) * 2 - 1;
81 self.mouse2D.y = -((e.pageY - $canvas.offset().top) / $canvas.height()) * 2 + 1;
84 self.theta -= e.pageX - self.mouse2D.pageX;
85 self.phi += e.pageY - self.mouse2D.pageY;
91 self.mouse2D.pageX = e.pageX;
92 self.mouse2D.pageY = e.pageY;
94 self.updatePosition();
97 }).mousedown(function(e) {
101 self.pointerDetectRay = self.projector.pickingRay(self.mouse2D.clone(), self.camera);
102 var intersects = self.pointerDetectRay.intersectObjects(self.scene.children);
103 if (intersects.length > 0 && self.select(intersects[0].object)) {
104 var node = intersects[0].object;
105 var $nodeInput = self.$nodeInputs[node.arch];
106 $nodeInput.val(factorize(self.nodes[node.arch]));
111 self.mouse2D.pageX = e.pageX;
112 self.mouse2D.pageY = e.pageY;
116 }).mouseup(function(e) {
123 }).mouseleave(function(e) {
125 }).mousewheel(function(e, delta) {
127 self.distance += delta * 5;
128 self.updatePosition();
132 $container.append($canvas);
135 function getCenter(nodes) {
136 var xmin = 0, ymin = 0, zmin = 0;
137 var xmax = 0, ymax = 0, zmax = 0;
139 for (var i = 0; i < nodes.length; ++i) {
140 if (nodes[i].x > xmax) xmax = nodes[i].x;
141 if (nodes[i].x < xmin) xmin = nodes[i].x;
142 if (nodes[i].y > ymax) ymax = nodes[i].y;
143 if (nodes[i].y < ymin) ymin = nodes[i].y;
144 if (nodes[i].z > zmax) zmax = nodes[i].z;
145 if (nodes[i].z < zmin) zmin = nodes[i].z;
147 return {x: (xmax + xmin) / 2, y: (ymax + ymin) / 2, z: (zmax + zmin) / 2};
150 function setColor(node) {
151 node.material.color.setHex(colors[node.boot_state] || colors["Selected"]);
154 Map.prototype.addNodes = function(nodes) {
155 var center = getCenter(nodes);
156 var program = function(context) {
158 context.arc(0, 0, 1, 0, Math.PI * 2, true);
163 for(var i = 0; i < nodes.length; ++i) {
164 var material = new THREE.ParticleCanvasMaterial({program: program});
165 var particle = new THREE.Particle(material);
167 particle.id = nodes[i].id;
168 particle.arch = nodes[i].arch;
169 particle.boot_state = nodes[i].boot_state;
170 particle.position.x = (nodes[i].x - center.x) * 10;
171 particle.position.y = (nodes[i].y - center.y) * 10;
172 particle.position.z = (nodes[i].z - center.z) * 10;
173 particle.scale.x = particle.scale.y = 1;
175 this.scene.add(particle);
180 Map.prototype.select = function(node) {
181 if (node.boot_state == "Suspected") {
183 } else if (node.boot_state == "Alive") {
184 var array = this.nodes[node.arch];
185 array.push(parseInt(node.id));
186 array.sort(nodeSort);
187 node.boot_state = "Selected";
191 var array = this.nodes[node.arch];
192 var index = $.inArray(parseInt(node.id), array);
193 index > -1 && array.splice(index, 1);
194 node.boot_state = "Alive";
200 function factorize(nodes) {
203 var intervalStart = 0;
205 for (var i = 0; i < nodes.length; ++i) {
207 if (nodes[i] == prev + 1) {
210 factorized.push(intervalStart + "-" + prev);
215 if (nodes[i] == prev + 1) {
216 intervalStart = prev;
219 prev && factorized.push(prev);
224 factorized.push(intervalStart ? intervalStart + "-" + prev : prev);
225 return factorized.join(",");
228 function expand(input) {
229 var factorized = input.split(",");
231 for (var i = 0; i < factorized.length; ++i) {
232 var d = factorized[i].split("-");
234 for (var j = parseInt(d[0]); j < parseInt(d[1]) + 1; j++) {
238 expanded.push(parseInt(factorized[i]));
241 expanded.sort(nodeSort);
242 for (var i = 1; i < expanded.length; i++) {
243 if (expanded[i] == expanded[i - 1]) {
244 expanded.splice(i--, 1);
250 function nodeSort(a, b) {
254 Map.prototype.updateColor = function(arch) {
255 var nodes = this.scene.children;
256 for (var i = 0; i < nodes.length; ++i) {
257 if (nodes[i].arch == arch && nodes[i].boot_state != "Suspected") {
258 var id = parseInt(nodes[i].id);
259 var array = this.nodes[arch];
260 nodes[i].boot_state = $.inArray(id, array) == -1 ? "Alive" : "Selected";
267 Map.prototype.updatePosition = function() {
268 this.camera.position.x = this.distance * Math.sin(this.theta * Math.PI / 360) * Math.cos(this.phi * Math.PI / 360);
269 this.camera.position.y = this.distance * Math.sin(this.phi * Math.PI / 360);
270 this.camera.position.z = this.distance * Math.cos(this.theta * Math.PI / 360) * Math.cos(this.phi * Math.PI / 360);
271 this.camera.lookAt(this.scene.position);
272 this.camera.updateMatrix();
275 Map.prototype.update = function() {
276 this.renderer.render(this.scene, this.camera);