toolkit/javascript/nco/tapestry.js
changeset 47 c0b4a8b5a012
equal deleted inserted replaced
46:efd9c589177a 47:c0b4a8b5a012
       
     1 function Tapestry(donnees, parametres) {
       
     2 
       
     3 //	Initialisation des attributs
       
     4 	var mesDonnees = donnees;
       
     5 	this.zoomlvl = 0;
       
     6 	this.beginIndexs=[0,5,0,0];
       
     7 	this.decalageParent = [0,10,10,1];
       
     8 	this.listePosition=[[],[]];
       
     9 
       
    10 
       
    11 	this.parametres = {
       
    12 			name: null,
       
    13 			hauteur: 330,
       
    14 			largeur: 1100,	
       
    15 			selector: "#tapestry",
       
    16 			selectorHaut : null,
       
    17 			selectorBas : null,
       
    18 			relations: null,
       
    19 			contenu: null,
       
    20 			template: null
       
    21 	};
       
    22 	
       
    23 	this.etendre(parametres);
       
    24 	
       
    25 	
       
    26 	/* -- Gestion des valeurs par defaut -- */
       
    27 	
       
    28 	if (null==this.parametres.name) {
       
    29 		this.parametres.name = this.parametres.selector;
       
    30 	}
       
    31 	if (null==this.parametres.hauteur) {
       
    32 		this.parametres.hauteur = 400;
       
    33 	}
       
    34 	if (null==this.parametres.largeur) {
       
    35 		this.parametres.largeur = 900;
       
    36 	}
       
    37 	if (null==this.parametres.selectorBas) {
       
    38 		this.parametres.selectorBas = "#timelinebasse";
       
    39 	}
       
    40 	if (null==this.parametres.selectorHaut) {
       
    41 		this.parametres.selectorHaut = "#timelinehaute";
       
    42 	}
       
    43 	if (null==this.parametres.contenu) {
       
    44 		if (null!=this.parametres.template) {
       
    45 			this.template = jQuery(this.parametres.template.selector);
       
    46 			this.template.remove();
       
    47 			this.parametres.contenu = this.renderContent;
       
    48 		}
       
    49 		else {
       
    50 			this.parametres.contenu = this.defaultContent;
       
    51 		}
       
    52 	}
       
    53 	
       
    54 	
       
    55 	
       
    56 	//----------------------------------------------------------------------
       
    57 	// INITIALISATION : on calcule les positions / dimensions des futurs objets
       
    58 	this.listePosition=this.getPosition();
       
    59 	var object = this;
       
    60 	var larg,haut;
       
    61 	larg = String(this.parametres.largeur/5) + "px";
       
    62 	larg2=String(this.parametres.largeur/10) + "px";
       
    63 	larg3= String(9*this.parametres.largeur/100) + "px";
       
    64 	haut = String(this.parametres.hauteur/2 -1) + "px" ;
       
    65 	haut2 = String(this.parametres.hauteur) + "px" ;
       
    66 	this.lastIndexs = [9,18,160,1441];
       
    67 
       
    68 
       
    69 	//----------------------------------------------------------------------
       
    70 	// FENETRE DE FOND
       
    71 	this.globalTapestry = d3.select(object.parametres.selector);
       
    72 	this.globalTapestry.append('div').attr('id','timelinehaute');
       
    73 	this.globalTapestry.append('div').attr('id','timelinebasse');
       
    74 
       
    75 	this.tapestryHtml = d3.select(object.parametres.selectorHaut)
       
    76 	.style('position', 'relative')
       
    77 	.style('left','200px')
       
    78 	.style('width', object.parametres.largeur + 'px')
       
    79 	.style('height', object.parametres.hauteur + 'px')
       
    80 	.style('background-color', 'black');	
       
    81 	//.style('overflow','hidden');
       
    82 
       
    83 	//----------------------------------------------------------------------
       
    84 	// BOUTON DEZOOM
       
    85 	var left = this.parametres.largeur/2 +100+"px";
       
    86 	this.boutonZoom = d3.select(object.parametres.selectorBas).append('button')
       
    87 	.attr('id',"dezoom")
       
    88 	.style('position', 'relative')
       
    89 	.style('top','5px')
       
    90 	.style('left',left)
       
    91 	.style('width', "200px")
       
    92 	.style('height',"20px")
       
    93 	.style('background-color', 'grey')	
       
    94 	.style('margin-top', '5px')
       
    95 	.style('stroke-width','2px')
       
    96 	.style('stroke','black')
       
    97 	.style('display','none')
       
    98 	.html("<p class = 'title' style = \" width:200px;\"> Dezoom </p>")
       
    99 	.on('mouseover', function(){d3.select(this).style('opacity', 0.8);})
       
   100 	.on('mouseout', function(){d3.select(this).style('opacity', 1);})
       
   101 	.on('click',function(){object.agencerDezoom(mesDonnees);});
       
   102 
       
   103 	//----------------------------------------------------------------------
       
   104 	// BOUTON SLIDELEFT
       
   105 	var html = "<img class = 'img' src = \"data/boutongauche.png\" style=\" width:"+larg3+"; height:"+haut+"; margin-top: 0px; margin-left: 0px; stroke-width:0px\" />";
       
   106 	this.boutonSlideGauche = d3.select(object.parametres.selectorHaut).append('button')
       
   107 	.attr('id',"sliderLeft")
       
   108 	.style('position', 'absolute')
       
   109 	.style('z-index',1)
       
   110 	.style('width', larg2)
       
   111 	.style('height',haut)
       
   112 	.style('background-color', 'black')	
       
   113 	.style('opacity',0.2)
       
   114 	.style('stroke','black')
       
   115 	.html(html)
       
   116 	.on('mouseover', function(){
       
   117 		if (object.beginIndexs[object.zoomlvl]!=0){
       
   118 		d3.select(this).style('opacity', 0.8);}})
       
   119 	.on('mouseout', function(){
       
   120 		var lvl = object.zoomlvl;
       
   121 		if (object.beginIndexs[lvl]!=0){
       
   122 		d3.select(this).style('opacity', 1);}})
       
   123 	.on('click',function(){object.sliderLeft(mesDonnees);});
       
   124 
       
   125 	//----------------------------------------------------------------------
       
   126 	// BOUTON SLIDERIGHT
       
   127 	left = this.parametres.largeur*9/10 + "px";
       
   128 	this.boutonSlideDroite = d3.select(this.parametres.selectorHaut).append('button')
       
   129 	.attr('id',"sliderRight")
       
   130 	.style('position', 'absolute')
       
   131 	.style('z-index',1)
       
   132 	.style('top',-5)
       
   133 	.style('left',left)
       
   134 	.style('width', larg2)
       
   135 	.style('height',haut)
       
   136 	.style('background-color', 'black')	
       
   137 	.style('margin-top', '5px')
       
   138 	.style('stroke-width','2px')
       
   139 	.style('stroke','black')
       
   140 	.style('opacity',0.2)
       
   141 	.html("<img class = 'img' src = \"data/boutondroite.png\" style=\" width:"+larg3+"; height:"+haut+"; margin-top: 0px; margin-left: 0px; stroke-width:0px\" />")
       
   142 	.on('mouseover', function(){
       
   143 		var lvl = object.zoomlvl;
       
   144 		if (object.beginIndexs[lvl]!=object.lastIndexs[lvl]-9){
       
   145 		d3.select(this).style('opacity', 0.8);}})
       
   146 	.on('mouseout', function(){
       
   147 		var lvl = object.zoomlvl;
       
   148 		if (object.beginIndexs[lvl]!=object.lastIndexs[lvl]-9){
       
   149 			d3.select(this).style('opacity', 1);}})
       
   150 	.on('click',function(){object.sliderRight(mesDonnees);});
       
   151 
       
   152 	
       
   153 	//----------------------------------------------------------------------
       
   154 	// INIT DES PETITES FENETRES
       
   155 
       
   156 	d3.select(this.parametres.selectorHaut).selectAll()
       
   157 	.data(mesDonnees[0].slice(0, 9)).enter().append("div")
       
   158 	.attr('class', 'cell')
       
   159 	.attr('id', "middle")
       
   160 	.attr('indexInTap',function(index){return index;})
       
   161 	.on('mouseover', function(){if (object.zoomlvl!=3){d3.select(this)
       
   162 		.transition()
       
   163 		.duration(120)
       
   164 		.style('opacity', 0.8)
       
   165 		.style('stroke', 'black')
       
   166 		.style('stroke-width', '3px');}})
       
   167 	.on('mouseout', function(){d3.select(this)
       
   168 		.transition()
       
   169 		.duration(120)
       
   170 		.style('opacity', 1)
       
   171 		.style('stroke', 'white')
       
   172 		.style('stroke-width', '0px');})
       
   173 	.on('click',function(datum,index){object.agencerZoom(datum,index,mesDonnees);})
       
   174 	.on('scroll',function(datum,index){object.agencerZoom(datum,index);})
       
   175 	.style('position', 'absolute')
       
   176 	.style('width', larg)
       
   177 	.style('height',haut)
       
   178 	.style('background-color', 'black')
       
   179 	.style('text-align','center')
       
   180 	.html(function(datum,index){return object.parametres.contenu.call(object, this,datum);})
       
   181 	.style('left', function(datum, index) {
       
   182 		return object.listePosition[index][0];
       
   183 			})
       
   184 	.style('top', function(datum, index) {
       
   185 			return object.listePosition[index][1];
       
   186 			});
       
   187 	if (null!=this.parametres.relations) {
       
   188 		this.parametres.relations.add(this.parametres.name, this);
       
   189 		
       
   190 		d3.select(this.parametres.selectorHaut).selectAll("div")
       
   191 			.each(function(datum) {
       
   192 				var item = d3.select(this);
       
   193 				datum["relationName"] = object.parametres.name +'.'+ datum.name;
       
   194 				object.parametres.relations.add(datum.relationName, item);
       
   195 			});
       
   196 	}
       
   197 //	d3.select("#timelinehaute").selectAll("#middle")
       
   198 //				.append('button')
       
   199 //				.attr('class', 'dezoom-butoon')
       
   200 //				.attr('id', "dezoom")
       
   201 //				.style('width','180px')
       
   202 //				.style('height','20px')
       
   203 //				.style('position','absolute')
       
   204 //				.style('top','180')
       
   205 //				.style('opacity',' 0,8')
       
   206 //				.style('background','dark-grey')
       
   207 //				.style('z-index',10)
       
   208 //				.attr('onmouseover',"this.style(\"stroke\",\"white\");" );			
       
   209 ;
       
   210 }
       
   211 
       
   212 Tapestry.prototype = {		
       
   213 		sleep: function(ms, args, obj) {
       
   214 		    /* Called at the top of a function to invoke a delay in processing that
       
   215 		       function
       
   216 
       
   217 		       Returns true if the function should be executed, and false if the sleep
       
   218 		       timer is activated. 
       
   219 
       
   220 		       At the end of the sleep tiemout, the calling function is re-called by
       
   221 		       calling it with "apply (obj, args || [])".
       
   222 		    */
       
   223 
       
   224 		    var caller = sleep.caller;
       
   225 		    if (caller.sleepTimer) { 
       
   226 		      /* if invoked from timeout function, delete timer and return false */
       
   227 		      delete caller.sleepTimer;
       
   228 		      return true;
       
   229 		    }},
       
   230 		    
       
   231 		etendre: function(parametres) {
       
   232 			if (null==parametres || "object"!=typeof(parametres)) {
       
   233 				return;
       
   234 			}
       
   235 			
       
   236 			for (var cle in parametres) {
       
   237 				this.parametres[cle] = parametres[cle];
       
   238 			}
       
   239 		},
       
   240 
       
   241 		getPosition: function(){	// renvoie une liste contenant la position(x,y) absolute des fenêtres de la tapestry
       
   242 			var l,h;
       
   243 			l= this.parametres.largeur;
       
   244 			h= this.parametres.hauteur;
       
   245 			var listposition=[];
       
   246 			for (var i=0;i<9;i++){listposition.push([(i*0.5)*l/5,h/2*((i+1)%2)]);}
       
   247 			//listposition.push([4.5*l/5,0]);
       
   248 			return listposition;
       
   249 		},
       
   250 
       
   251 		
       
   252 		
       
   253 		updateLayout: function(lvl,sliceIndex, isSlide,mesDonnees){		// met a jour la tapestry avec les données[lvl] à l'indice sliceIndex
       
   254 			var object = this;
       
   255 			var duration = isSlide? 40 : 160;
       
   256 			this.tapestryHtml.selectAll("#middle")
       
   257 			
       
   258 			.transition()
       
   259 			.duration(duration)
       
   260 			//.delay(10)
       
   261 			//.delay(function(index){return 10*index;})
       
   262 			.style("opacity", 0);
       
   263 			
       
   264 			var timeout = window.setTimeout(function() {
       
   265 
       
   266 			
       
   267 			
       
   268 			object.tapestryHtml.selectAll("#middle")
       
   269 			.data(mesDonnees[lvl].slice(sliceIndex,sliceIndex+9))
       
   270 			.html(function(datum,index){return object.parametres.contenu.call(object, this,datum);});
       
   271 			
       
   272 			object.tapestryHtml.selectAll("#middle")
       
   273 			.transition()
       
   274 			.duration(2*duration)
       
   275 			.delay(10)
       
   276 			//.delay(function(index){return 10*index;})
       
   277 			.style("opacity", 1);
       
   278 			
       
   279 			object.tapestryHtml.select("#sliderRight")
       
   280 				.transition()
       
   281 				.duration(duration)
       
   282 				.delay(10)
       
   283 				.style('opacity',function(){
       
   284 					if (object.beginIndexs[lvl]+9==object.lastIndexs[lvl]){
       
   285 						return 0.2;
       
   286 					}
       
   287 					else{return 1;}				});
       
   288 			
       
   289 			object.tapestryHtml.select("#sliderLeft")
       
   290 				.transition()
       
   291 				.duration(duration)
       
   292 				.delay(10)
       
   293 				.style('opacity',function(){
       
   294 					if (object.beginIndexs[lvl]==0){
       
   295 						return 0.2;
       
   296 					}
       
   297 					else{return 1;}				});
       
   298 			
       
   299 			object.boutonZoom
       
   300 			.style('display',function(){
       
   301 				if (lvl==0){return 'none';}
       
   302 				else {return 'block';}
       
   303 //				result = (lvl==0) ? 'none' : 'block';
       
   304 //				return result;
       
   305 			});
       
   306 			}, 3*duration);
       
   307 		},
       
   308 
       
   309 		
       
   310 		
       
   311 		sliderLeft: function(mesDonnees){
       
   312 			if (this.zoomlvl!=0){
       
   313 			var lvl= this.zoomlvl;
       
   314 			var father = this.beginIndexs[lvl];
       
   315 			if (father!=0){ 
       
   316 				var coef= (father == 1) ? 1 :2;	
       
   317 				this.beginIndexs[lvl]-=coef;
       
   318 				this.updateLayout(lvl, father-coef,true,mesDonnees);
       
   319 				
       
   320 				
       
   321 				// Gestion des decalages des niveau superieurs
       
   322 				//-------------------------------------------------------------------
       
   323 				if (lvl!=0){
       
   324 					this.decalageParent[lvl-1]-=2;
       
   325 					var decal = this.decalageParent[lvl-1];
       
   326 					if (decal<2){
       
   327 						if (decal==0){
       
   328 							this.decalageParent[lvl-1]=9;
       
   329 							if(this.beginIndexs[lvl-1]!=0){
       
   330 								this.beginIndexs[lvl-1]--;
       
   331 								if (lvl==3){
       
   332 									this.decalageParent[1]--;
       
   333 									if (this.decalageParent[1]==1){	
       
   334 										this.decalageParent[1]=10;
       
   335 										if(this.beginIndexs[1]!=0){this.beginIndexs[1]--;}							
       
   336 									}}}}
       
   337 						else{
       
   338 							this.decalageParent[lvl-1]=10;
       
   339 							if(this.beginIndexs[lvl-1]!=0){
       
   340 								this.beginIndexs[lvl-1]--;
       
   341 								if (lvl==3){
       
   342 									this.decalageParent[1]--;
       
   343 									if (this.decalageParent[1]==1){	
       
   344 										this.decalageParent[1]=10;
       
   345 										if(this.beginIndexs[1]!=0){this.beginIndexs[1]--;}							
       
   346 									}}}}}}}
       
   347 
       
   348 		}},
       
   349 		sliderRight: function(mesDonnees){
       
   350 			if (this.zoomlvl!=0){
       
   351 			//var last = donnees1[this.zoomlvl].length-9;
       
   352 			var lvl=this.zoomlvl;
       
   353 			var last = this.lastIndexs[lvl]-9;
       
   354 			var father = this.beginIndexs[lvl];
       
   355 			if (father!=last){
       
   356 				var coef= (father == last-1) ? 1 :2;	
       
   357 				this.beginIndexs[lvl]+=coef;
       
   358 				this.updateLayout(lvl, father+coef,true,mesDonnees);
       
   359 
       
   360 				// Gestion des decalages des niveau superieurs
       
   361 				//-------------------------------------------------------------------
       
   362 				if (this.zoomlvl!=1){
       
   363 					//var lastFather = donnees1[lvl-1].length-9;
       
   364 					var lastFather = this.lastIndexs[lvl-1]-9;
       
   365 					this.decalageParent[lvl-1]+=2;
       
   366 					decal =this.decalageParent[lvl-1];
       
   367 					if (decal>18){
       
   368 						if (decal==20){
       
   369 							this.decalageParent[lvl-1]=11;
       
   370 							if(this.beginIndexs[lvl-1]!=lastFather){
       
   371 								this.beginIndexs[lvl-1]++;
       
   372 								if (lvl==3){
       
   373 									this.decalageParent[1]++;
       
   374 									if (this.decalageParent[1]==19){	
       
   375 										this.decalageParent[1]=10;
       
   376 										if(this.beginIndexs[1]!=this.lastIndexs-9){this.beginIndexs[1]++;}							
       
   377 									}}}}
       
   378 						else{
       
   379 							this.decalageParent[this.zoomlvl-1]=10;
       
   380 							if(this.beginIndexs[this.zoomlvl-1]!=lastFather){
       
   381 								this.beginIndexs[this.zoomlvl-1]++;
       
   382 								if (lvl==3){
       
   383 									this.decalageParent[0]++;
       
   384 									if (this.decalageParent[1]==19){	
       
   385 										this.decalageParent[1]=10;
       
   386 										if(this.beginIndexs[1]!=mesDonnees[1].length-9){this.beginIndexs[1]++;}							
       
   387 									}}}}}}}
       
   388 		}},
       
   389 		
       
   390 		agencerZoom: function(element,indexx,mesDonnees){
       
   391 			var lvl=element.zoomlvl;
       
   392 			if (lvl !=3){
       
   393 				this.beginIndexs[lvl+1]=element.child-indexx;
       
   394 				this.updateLayout(lvl+1, element.child-indexx,false,mesDonnees);
       
   395 				this.decalageParent[lvl]+=4-indexx;
       
   396 				this.zoomlvl = lvl +1;
       
   397 			}},
       
   398 
       
   399 		agencerDezoom: function(mesDonnees){
       
   400 			var lvl = this.zoomlvl;
       
   401 			if (lvl!=0) {
       
   402 				this.updateLayout(lvl-1, this.beginIndexs[lvl-1],false,mesDonnees);
       
   403 				this.zoomlvl--;
       
   404 				this.decalageParent[lvl-1]=10;
       
   405 			}},
       
   406 			
       
   407 		getDataTapestry: function(json){
       
   408 			
       
   409 		},
       
   410 		renderContent: function(cellule, element) {
       
   411 			
       
   412 			var html;
       
   413 			var img = new Image();
       
   414 			indexx = element.indexx;
       
   415 			img.src= images[indexx];
       
   416 			var wc, hc;
       
   417 			wc = cellule.offsetWidth  ;
       
   418 			hc = cellule.offsetHeight ;
       
   419 			
       
   420 			var data = {
       
   421 				'urlImage': img.src,
       
   422 				'widhtImage': wc +"px",
       
   423 				'heightImage': hc +"px",
       
   424 				'margin-top': hc/2+'px',
       
   425 				'cssDimensionImage': "width:"+ wc + "px; ",
       
   426 				'cssDimensionTitre':" width:" + wc + "px; height:" +hc/10 +"px;",
       
   427 				'titreImage': "image " + indexx
       
   428 			};
       
   429 			
       
   430 			return this.template
       
   431 				.render(data, this.parametres.template.directives).html();
       
   432 		},
       
   433 		
       
   434 		defaultContent: function(cellule, element) {	// cellule contient la div et element ses données
       
   435 			
       
   436 				var html;
       
   437 				var img = new Image();
       
   438 				
       
   439 				indexx = element.indexx;
       
   440 				img.src= images[indexx];
       
   441 				var wc, hc;
       
   442 				wc = cellule.offsetWidth  ;
       
   443 				hc = cellule.offsetHeight ;
       
   444 				html = "<img class = 'img' src = \"" + img.src + "\" style=\"width:"+ wc + "px; height:" +hc + "px;  margin-top:5px; margin-left: 0px;\" />";
       
   445 				html += "<p class = 'title' style = \" width:" + wc + "px; height:" +hc/10 +"px;\"> Image "+String(indexx)+"</p>";
       
   446 				return html;
       
   447 		
       
   448 		}
       
   449 
       
   450 
       
   451 };
       
   452 
       
   453