diff -r efd9c589177a -r c0b4a8b5a012 toolkit/exemples/tapisserie/scripts/tapestry.js --- /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("

Dezoom

") + .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 = ""; + 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("") + .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 = ""; + html += "

Image "+String(indexx)+"

"; + return html; + + } + + +}; + +