toolkit/exemples/tapisserie/scripts/tapestry.js
changeset 47 c0b4a8b5a012
child 48 1b2dffb4ac2b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolkit/exemples/tapisserie/scripts/tapestry.js	Thu Apr 10 14:20:23 2014 +0200
@@ -0,0 +1,453 @@
+function Tapestry(donnees, parametres) {
+
+//	Initialisation des attributs
+	var mesDonnees = donnees;
+	this.zoomlvl = 0;
+	this.beginIndexs=[0,5,0,0];
+	this.decalageParent = [0,10,10,1];
+	this.listePosition=[[],[]];
+
+
+	this.parametres = {
+			name: null,
+			hauteur: 330,
+			largeur: 1100,	
+			selector: "#tapestry",
+			selectorHaut : null,
+			selectorBas : null,
+			relations: null,
+			contenu: null,
+			template: null
+	};
+	
+	this.etendre(parametres);
+	
+	
+	/* -- Gestion des valeurs par defaut -- */
+	
+	if (null==this.parametres.name) {
+		this.parametres.name = this.parametres.selector;
+	}
+	if (null==this.parametres.hauteur) {
+		this.parametres.hauteur = 400;
+	}
+	if (null==this.parametres.largeur) {
+		this.parametres.largeur = 900;
+	}
+	if (null==this.parametres.selectorBas) {
+		this.parametres.selectorBas = "#timelinebasse";
+	}
+	if (null==this.parametres.selectorHaut) {
+		this.parametres.selectorHaut = "#timelinehaute";
+	}
+	if (null==this.parametres.contenu) {
+		if (null!=this.parametres.template) {
+			this.template = jQuery(this.parametres.template.selector);
+			this.template.remove();
+			this.parametres.contenu = this.renderContent;
+		}
+		else {
+			this.parametres.contenu = this.defaultContent;
+		}
+	}
+	
+	
+	
+	//----------------------------------------------------------------------
+	// INITIALISATION : on calcule les positions / dimensions des futurs objets
+	this.listePosition=this.getPosition();
+	var object = this;
+	var larg,haut;
+	larg = String(this.parametres.largeur/5) + "px";
+	larg2=String(this.parametres.largeur/10) + "px";
+	larg3= String(9*this.parametres.largeur/100) + "px";
+	haut = String(this.parametres.hauteur/2 -1) + "px" ;
+	haut2 = String(this.parametres.hauteur) + "px" ;
+	this.lastIndexs = [9,18,160,1441];
+
+
+	//----------------------------------------------------------------------
+	// FENETRE DE FOND
+	this.globalTapestry = d3.select(object.parametres.selector);
+	this.globalTapestry.append('div').attr('id','timelinehaute');
+	this.globalTapestry.append('div').attr('id','timelinebasse');
+
+	this.tapestryHtml = d3.select(object.parametres.selectorHaut)
+	.style('position', 'relative')
+	.style('left','200px')
+	.style('width', object.parametres.largeur + 'px')
+	.style('height', object.parametres.hauteur + 'px')
+	.style('background-color', 'black');	
+	//.style('overflow','hidden');
+
+	//----------------------------------------------------------------------
+	// BOUTON DEZOOM
+	var left = this.parametres.largeur/2 +100+"px";
+	this.boutonZoom = d3.select(object.parametres.selectorBas).append('button')
+	.attr('id',"dezoom")
+	.style('position', 'relative')
+	.style('top','5px')
+	.style('left',left)
+	.style('width', "200px")
+	.style('height',"20px")
+	.style('background-color', 'grey')	
+	.style('margin-top', '5px')
+	.style('stroke-width','2px')
+	.style('stroke','black')
+	.style('display','none')
+	.html("<p class = 'title' style = \" width:200px;\"> Dezoom </p>")
+	.on('mouseover', function(){d3.select(this).style('opacity', 0.8);})
+	.on('mouseout', function(){d3.select(this).style('opacity', 1);})
+	.on('click',function(){object.agencerDezoom(mesDonnees);});
+
+	//----------------------------------------------------------------------
+	// BOUTON SLIDELEFT
+	var html = "<img class = 'img' src = \"data/boutongauche.png\" style=\" width:"+larg3+"; height:"+haut+"; margin-top: 0px; margin-left: 0px; stroke-width:0px\" />";
+	this.boutonSlideGauche = d3.select(object.parametres.selectorHaut).append('button')
+	.attr('id',"sliderLeft")
+	.style('position', 'absolute')
+	.style('z-index',1)
+	.style('width', larg2)
+	.style('height',haut)
+	.style('background-color', 'black')	
+	.style('opacity',0.2)
+	.style('stroke','black')
+	.html(html)
+	.on('mouseover', function(){
+		if (object.beginIndexs[object.zoomlvl]!=0){
+		d3.select(this).style('opacity', 0.8);}})
+	.on('mouseout', function(){
+		var lvl = object.zoomlvl;
+		if (object.beginIndexs[lvl]!=0){
+		d3.select(this).style('opacity', 1);}})
+	.on('click',function(){object.sliderLeft(mesDonnees);});
+
+	//----------------------------------------------------------------------
+	// BOUTON SLIDERIGHT
+	left = this.parametres.largeur*9/10 + "px";
+	this.boutonSlideDroite = d3.select(this.parametres.selectorHaut).append('button')
+	.attr('id',"sliderRight")
+	.style('position', 'absolute')
+	.style('z-index',1)
+	.style('top',-5)
+	.style('left',left)
+	.style('width', larg2)
+	.style('height',haut)
+	.style('background-color', 'black')	
+	.style('margin-top', '5px')
+	.style('stroke-width','2px')
+	.style('stroke','black')
+	.style('opacity',0.2)
+	.html("<img class = 'img' src = \"data/boutondroite.png\" style=\" width:"+larg3+"; height:"+haut+"; margin-top: 0px; margin-left: 0px; stroke-width:0px\" />")
+	.on('mouseover', function(){
+		var lvl = object.zoomlvl;
+		if (object.beginIndexs[lvl]!=object.lastIndexs[lvl]-9){
+		d3.select(this).style('opacity', 0.8);}})
+	.on('mouseout', function(){
+		var lvl = object.zoomlvl;
+		if (object.beginIndexs[lvl]!=object.lastIndexs[lvl]-9){
+			d3.select(this).style('opacity', 1);}})
+	.on('click',function(){object.sliderRight(mesDonnees);});
+
+	
+	//----------------------------------------------------------------------
+	// INIT DES PETITES FENETRES
+
+	d3.select(this.parametres.selectorHaut).selectAll()
+	.data(mesDonnees[0].slice(0, 9)).enter().append("div")
+	.attr('class', 'cell')
+	.attr('id', "middle")
+	.attr('indexInTap',function(index){return index;})
+	.on('mouseover', function(){if (object.zoomlvl!=3){d3.select(this)
+		.transition()
+		.duration(120)
+		.style('opacity', 0.8)
+		.style('stroke', 'black')
+		.style('stroke-width', '3px');}})
+	.on('mouseout', function(){d3.select(this)
+		.transition()
+		.duration(120)
+		.style('opacity', 1)
+		.style('stroke', 'white')
+		.style('stroke-width', '0px');})
+	.on('click',function(datum,index){object.agencerZoom(datum,index,mesDonnees);})
+	.on('scroll',function(datum,index){object.agencerZoom(datum,index);})
+	.style('position', 'absolute')
+	.style('width', larg)
+	.style('height',haut)
+	.style('background-color', 'black')
+	.style('text-align','center')
+	.html(function(datum,index){return object.parametres.contenu.call(object, this,datum);})
+	.style('left', function(datum, index) {
+		return object.listePosition[index][0];
+			})
+	.style('top', function(datum, index) {
+			return object.listePosition[index][1];
+			});
+	if (null!=this.parametres.relations) {
+		this.parametres.relations.add(this.parametres.name, this);
+		
+		d3.select(this.parametres.selectorHaut).selectAll("div")
+			.each(function(datum) {
+				var item = d3.select(this);
+				datum["relationName"] = object.parametres.name +'.'+ datum.name;
+				object.parametres.relations.add(datum.relationName, item);
+			});
+	}
+//	d3.select("#timelinehaute").selectAll("#middle")
+//				.append('button')
+//				.attr('class', 'dezoom-butoon')
+//				.attr('id', "dezoom")
+//				.style('width','180px')
+//				.style('height','20px')
+//				.style('position','absolute')
+//				.style('top','180')
+//				.style('opacity',' 0,8')
+//				.style('background','dark-grey')
+//				.style('z-index',10)
+//				.attr('onmouseover',"this.style(\"stroke\",\"white\");" );			
+;
+}
+
+Tapestry.prototype = {		
+		sleep: function(ms, args, obj) {
+		    /* Called at the top of a function to invoke a delay in processing that
+		       function
+
+		       Returns true if the function should be executed, and false if the sleep
+		       timer is activated. 
+
+		       At the end of the sleep tiemout, the calling function is re-called by
+		       calling it with "apply (obj, args || [])".
+		    */
+
+		    var caller = sleep.caller;
+		    if (caller.sleepTimer) { 
+		      /* if invoked from timeout function, delete timer and return false */
+		      delete caller.sleepTimer;
+		      return true;
+		    }},
+		    
+		etendre: function(parametres) {
+			if (null==parametres || "object"!=typeof(parametres)) {
+				return;
+			}
+			
+			for (var cle in parametres) {
+				this.parametres[cle] = parametres[cle];
+			}
+		},
+
+		getPosition: function(){	// renvoie une liste contenant la position(x,y) absolute des fenêtres de la tapestry
+			var l,h;
+			l= this.parametres.largeur;
+			h= this.parametres.hauteur;
+			var listposition=[];
+			for (var i=0;i<9;i++){listposition.push([(i*0.5)*l/5,h/2*((i+1)%2)]);}
+			//listposition.push([4.5*l/5,0]);
+			return listposition;
+		},
+
+		
+		
+		updateLayout: function(lvl,sliceIndex, isSlide,mesDonnees){		// met a jour la tapestry avec les données[lvl] à l'indice sliceIndex
+			var object = this;
+			var duration = isSlide? 40 : 160;
+			this.tapestryHtml.selectAll("#middle")
+			
+			.transition()
+			.duration(duration)
+			//.delay(10)
+			//.delay(function(index){return 10*index;})
+			.style("opacity", 0);
+			
+			var timeout = window.setTimeout(function() {
+
+			
+			
+			object.tapestryHtml.selectAll("#middle")
+			.data(mesDonnees[lvl].slice(sliceIndex,sliceIndex+9))
+			.html(function(datum,index){return object.parametres.contenu.call(object, this,datum);});
+			
+			object.tapestryHtml.selectAll("#middle")
+			.transition()
+			.duration(2*duration)
+			.delay(10)
+			//.delay(function(index){return 10*index;})
+			.style("opacity", 1);
+			
+			object.tapestryHtml.select("#sliderRight")
+				.transition()
+				.duration(duration)
+				.delay(10)
+				.style('opacity',function(){
+					if (object.beginIndexs[lvl]+9==object.lastIndexs[lvl]){
+						return 0.2;
+					}
+					else{return 1;}				});
+			
+			object.tapestryHtml.select("#sliderLeft")
+				.transition()
+				.duration(duration)
+				.delay(10)
+				.style('opacity',function(){
+					if (object.beginIndexs[lvl]==0){
+						return 0.2;
+					}
+					else{return 1;}				});
+			
+			object.boutonZoom
+			.style('display',function(){
+				if (lvl==0){return 'none';}
+				else {return 'block';}
+//				result = (lvl==0) ? 'none' : 'block';
+//				return result;
+			});
+			}, 3*duration);
+		},
+
+		
+		
+		sliderLeft: function(mesDonnees){
+			if (this.zoomlvl!=0){
+			var lvl= this.zoomlvl;
+			var father = this.beginIndexs[lvl];
+			if (father!=0){ 
+				var coef= (father == 1) ? 1 :2;	
+				this.beginIndexs[lvl]-=coef;
+				this.updateLayout(lvl, father-coef,true,mesDonnees);
+				
+				
+				// Gestion des decalages des niveau superieurs
+				//-------------------------------------------------------------------
+				if (lvl!=0){
+					this.decalageParent[lvl-1]-=2;
+					var decal = this.decalageParent[lvl-1];
+					if (decal<2){
+						if (decal==0){
+							this.decalageParent[lvl-1]=9;
+							if(this.beginIndexs[lvl-1]!=0){
+								this.beginIndexs[lvl-1]--;
+								if (lvl==3){
+									this.decalageParent[1]--;
+									if (this.decalageParent[1]==1){	
+										this.decalageParent[1]=10;
+										if(this.beginIndexs[1]!=0){this.beginIndexs[1]--;}							
+									}}}}
+						else{
+							this.decalageParent[lvl-1]=10;
+							if(this.beginIndexs[lvl-1]!=0){
+								this.beginIndexs[lvl-1]--;
+								if (lvl==3){
+									this.decalageParent[1]--;
+									if (this.decalageParent[1]==1){	
+										this.decalageParent[1]=10;
+										if(this.beginIndexs[1]!=0){this.beginIndexs[1]--;}							
+									}}}}}}}
+
+		}},
+		sliderRight: function(mesDonnees){
+			if (this.zoomlvl!=0){
+			//var last = donnees1[this.zoomlvl].length-9;
+			var lvl=this.zoomlvl;
+			var last = this.lastIndexs[lvl]-9;
+			var father = this.beginIndexs[lvl];
+			if (father!=last){
+				var coef= (father == last-1) ? 1 :2;	
+				this.beginIndexs[lvl]+=coef;
+				this.updateLayout(lvl, father+coef,true,mesDonnees);
+
+				// Gestion des decalages des niveau superieurs
+				//-------------------------------------------------------------------
+				if (this.zoomlvl!=1){
+					//var lastFather = donnees1[lvl-1].length-9;
+					var lastFather = this.lastIndexs[lvl-1]-9;
+					this.decalageParent[lvl-1]+=2;
+					decal =this.decalageParent[lvl-1];
+					if (decal>18){
+						if (decal==20){
+							this.decalageParent[lvl-1]=11;
+							if(this.beginIndexs[lvl-1]!=lastFather){
+								this.beginIndexs[lvl-1]++;
+								if (lvl==3){
+									this.decalageParent[1]++;
+									if (this.decalageParent[1]==19){	
+										this.decalageParent[1]=10;
+										if(this.beginIndexs[1]!=this.lastIndexs-9){this.beginIndexs[1]++;}							
+									}}}}
+						else{
+							this.decalageParent[this.zoomlvl-1]=10;
+							if(this.beginIndexs[this.zoomlvl-1]!=lastFather){
+								this.beginIndexs[this.zoomlvl-1]++;
+								if (lvl==3){
+									this.decalageParent[0]++;
+									if (this.decalageParent[1]==19){	
+										this.decalageParent[1]=10;
+										if(this.beginIndexs[1]!=mesDonnees[1].length-9){this.beginIndexs[1]++;}							
+									}}}}}}}
+		}},
+		
+		agencerZoom: function(element,indexx,mesDonnees){
+			var lvl=element.zoomlvl;
+			if (lvl !=3){
+				this.beginIndexs[lvl+1]=element.child-indexx;
+				this.updateLayout(lvl+1, element.child-indexx,false,mesDonnees);
+				this.decalageParent[lvl]+=4-indexx;
+				this.zoomlvl = lvl +1;
+			}},
+
+		agencerDezoom: function(mesDonnees){
+			var lvl = this.zoomlvl;
+			if (lvl!=0) {
+				this.updateLayout(lvl-1, this.beginIndexs[lvl-1],false,mesDonnees);
+				this.zoomlvl--;
+				this.decalageParent[lvl-1]=10;
+			}},
+			
+		getDataTapestry: function(json){
+			
+		},
+		renderContent: function(cellule, element) {
+			
+			var html;
+			var img = new Image();
+			indexx = element.indexx;
+			img.src= images[indexx];
+			var wc, hc;
+			wc = cellule.offsetWidth  ;
+			hc = cellule.offsetHeight ;
+			
+			var data = {
+				'urlImage': img.src,
+				'widhtImage': wc +"px",
+				'heightImage': hc +"px",
+				'margin-top': hc/2+'px',
+				'cssDimensionImage': "width:"+ wc + "px; ",
+				'cssDimensionTitre':" width:" + wc + "px; height:" +hc/10 +"px;",
+				'titreImage': "image " + indexx
+			};
+			
+			return this.template
+				.render(data, this.parametres.template.directives).html();
+		},
+		
+		defaultContent: function(cellule, element) {	// cellule contient la div et element ses données
+			
+				var html;
+				var img = new Image();
+				
+				indexx = element.indexx;
+				img.src= images[indexx];
+				var wc, hc;
+				wc = cellule.offsetWidth  ;
+				hc = cellule.offsetHeight ;
+				html = "<img class = 'img' src = \"" + img.src + "\" style=\"width:"+ wc + "px; height:" +hc + "px;  margin-top:5px; margin-left: 0px;\" />";
+				html += "<p class = 'title' style = \" width:" + wc + "px; height:" +hc/10 +"px;\"> Image "+String(indexx)+"</p>";
+				return html;
+		
+		}
+
+
+};
+
+