alcatel/static/js/treemap.js
changeset 37 3848e1813a30
parent 27 8ca7f2cea729
equal deleted inserted replaced
36:bad0e6c60b63 37:3848e1813a30
     1 /* Génération de données aléatoires */
     1 //$(function(){
     2 
     2 
     3 var data = [],
     3     var IDEALRATIO = 1.33;
     4     startcolor = [ 0, 0, 255 ],
     4 		
     5     endcolor = [ 255, 255, 0 ]
     5     function cuttree(data, x, y, w, h, cut, ratio, callback) {
     6     elementcount = 8;
     6         
     7 
     7         function f(subdata, subx, suby, subw, subh) {
     8 for (var i = 0; i < elementcount; i++) {
     8             if (subdata.length == 1) {
     9     var r = i/elementcount,
     9                 subdata[0].x = subx;
    10         col = _(endcolor).map(function(e,i) {
    10                 subdata[0].y = suby;
    11             var s = startcolor[i]
    11                 subdata[0].w = subw;
    12             return Math.floor(r*e + (1-r)*s)
    12                 subdata[0].h = subh;
    13         });
    13             } else {
    14     data.push({
    14                 callback(subdata, subx, suby, subw, subh)
    15         label: "Cluster " + (1+i),
    15             }
    16         i: i+1,
    16         }
    17         color: "rgb("+col.join(",")+")",
    17         
    18         value: 1+Math.pow(Math.random(),2)*5
    18         var first = _(data).first(cut), rest = _(data).rest(cut);
    19     });
    19         if (!first.length || !rest.length) {
    20 }
    20             return;
    21 
    21         }
    22 /* Génération du Treemap */
    22         if (w/h > IDEALRATIO) {
    23 
    23             var leftw = w * ratio;
    24 data = _(data).sortBy(function(d) { return -d.value; });
    24             f(first, x, y, leftw, h);
    25 
    25             f(rest, x + leftw, y, w - leftw, h);
    26 var IDEALRATIO = 1.25;
    26         } else {
    27 
    27             var toph = h * ratio;
    28 function cuttree(data, x, y, w, h, cut, ratio, callback) {
    28             f(first, x, y, w, toph);
       
    29             f(rest, x, y + toph, w, h - toph);
       
    30         }
       
    31     }
       
    32 
       
    33     function pivot(data, x, y, w, h) {
       
    34         if (data.length == 1) {
       
    35             data[0].x = x;
       
    36             data[0].y = x;
       
    37             data[0].w = w;
       
    38             data[0].h = h;
       
    39             return;
       
    40         }
       
    41         var cut = 1, cumul = 0, bestcumul = 0, total = _(data).reduce(function(a,b){return a+b.value},0), bestcut = Infinity;
       
    42         for (var i = 0; i < data.length - 1; i++) {
       
    43             cumul += data[i].value;
       
    44             var delta = Math.abs(cumul - total/2);
       
    45             if (delta < bestcut) {
       
    46                 bestcut = delta;
       
    47                 bestcumul = cumul;
       
    48                 cut = i+1;
       
    49             } else {
       
    50                 break;
       
    51             }
       
    52         }
       
    53         cuttree(data, x, y, w, h, cut, bestcumul / total, pivot);
       
    54     }
       
    55 
       
    56     function squarify(data, x, y, w, h) {
       
    57         if (data.length == 1) {
       
    58             data[0].x = x;
       
    59             data[0].y = x;
       
    60             data[0].w = w;
       
    61             data[0].h = h;
       
    62             return;
       
    63         }
       
    64         var cut = 1, cumul = 0, bestcumul = 0, total = _(data).reduce(function(a,b){return a+b.value},0), bestcut = Infinity;
       
    65         for (var i = 0; i < data.length - 1; i++) {
       
    66             cumul += data[i].value;
       
    67             cuttree(data, x, y, w, h, i+1, cumul / total, pivot);
       
    68             var ratio = Math.abs(Math.log(IDEALRATIO*data[0].h/data[0].w));
       
    69             if (ratio < bestcut) {
       
    70                 bestcut = ratio;
       
    71                 bestcumul = cumul;
       
    72                 cut = i+1;
       
    73             } else {
       
    74                 break;
       
    75             }
       
    76         }
       
    77         cuttree(data, x, y, w, h, cut, bestcumul / total, squarify);
       
    78     }
    29     
    79     
    30     function f(subdata, subx, suby, subw, subh) {
    80 
    31         if (subdata.length == 1) {
    81     /* Templates des éléments à insérer */
    32             subdata[0].x = subx;
    82    
    33             subdata[0].y = suby;
    83     var articleTemplate = _(
    34             subdata[0].w = subw;
    84         '<div class="cluster-article" style="left: <%=x%>px; top: <%=y%>px; width: <%=w%>px; height: <%=h%>px;">'+
    35             subdata[0].h = subh;
    85             '<img src="<%=image_url%>" />' +
    36         } else {
    86         '</div>'
    37             callback(subdata, subx, suby, subw, subh)
    87     ).template();
    38         }
    88 	
    39     }
    89     var clusterTemplate = _( 
    40     
    90     '<div class="actu" style="left: <%=x%>px; top: <%=y%>px; width: <%=w - 1%>px; height: <%=h - 1%>px; background: #ffffff" data-cluster-id="<%=id%>">'+
    41     var first = _(data).first(cut), rest = _(data).rest(cut);
    91         '<%=articles%>'+ // Pour l'image composite
    42     if (!first.length || !rest.length) {
    92         '<img src="<%=image_url%>" />' + // Pour l'image de cluster
    43         return;
    93         '<div class="voile"></div>'+
    44     }
       
    45     if (w/h > IDEALRATIO) {
       
    46         var leftw = w * ratio;
       
    47         f(first, x, y, leftw, h);
       
    48         f(rest, x + leftw, y, w - leftw, h);
       
    49     } else {
       
    50         var toph = h * ratio;
       
    51         f(first, x, y, w, toph);
       
    52         f(rest, x, y + toph, w, h - toph);
       
    53     }
       
    54 }
       
    55 
       
    56 function pivot(data, x, y, w, h) {
       
    57     var cut = 1, cumul = 0, bestcumul = 0, total = _(data).reduce(function(a,b){return a+b.value},0), bestcut = Infinity;
       
    58     for (var i = 0; i < data.length - 1; i++) {
       
    59         cumul += data[i].value;
       
    60         var delta = Math.abs(cumul - total/2);
       
    61         if (delta < bestcut) {
       
    62             bestcut = delta;
       
    63             bestcumul = cumul;
       
    64             cut = i+1;
       
    65         } else {
       
    66             break;
       
    67         }
       
    68     }
       
    69     cuttree(data, x, y, w, h, cut, bestcumul / total, pivot);
       
    70 }
       
    71 
       
    72 function squarify(data, x, y, w, h) {
       
    73     var cut = 1, cumul = 0, bestcumul = 0, total = _(data).reduce(function(a,b){return a+b.value},0), bestcut = Infinity;
       
    74     for (var i = 0; i < data.length - 1; i++) {
       
    75         cumul += data[i].value;
       
    76         cuttree(data, x, y, w, h, i+1, cumul / total, pivot);
       
    77         var ratio = Math.abs(Math.log(IDEALRATIO*data[0].h/data[0].w));
       
    78         if (ratio < bestcut) {
       
    79             bestcut = ratio;
       
    80             bestcumul = cumul;
       
    81             cut = i+1;
       
    82         } else {
       
    83             break;
       
    84         }
       
    85     }
       
    86     cuttree(data, x, y, w, h, cut, bestcumul / total, squarify);
       
    87 }
       
    88 
       
    89 /* Template des éléments à insérer */
       
    90 var actu = 
       
    91     '<div class="actu" style="left: <%=x%>px; top: <%=y%>px; width: <%=w%>px; height: <%=h%>px; background: <%=color%>">'+
       
    92         '<a href="#">'+
       
    93             '<img src="img/home-visuel-<%-i%>.jpg" alt="" />'+
       
    94         '</a>'+
       
    95         '<div class="inner-actu">'+
    94         '<div class="inner-actu">'+
    96             '<h2><a href="#"><%-label%></a></h2>'+
    95             '<h2><a href="http://localhost:8000/<%=query_id%>/<%=id%>/0/12/0"><%-label%></a></h2>'+
    97             '<div class="links">'+
    96             '<div class="links">'+
    98                 '<ul>'+
    97                 '<ul>'+
    99                     '<li><a href="#" title="Supprimer le cluster" class="trash"></a></li>'+
    98                     '<li><a href="#" title="<%=annotation_count%> Annotations sur ce cluster" class="file"><span><%=annotation_count%></span></a></li>'+
   100                     '<li><a href="#" title="317 Annotations sur ce cluster" class="file"><span>317</span></a></li>'+
       
   101                     '<li><a href="#" title="Ajouter une annotation au cluster" class="comment"></a></li>'+
       
   102                 '</ul>'+
    99                 '</ul>'+
   103             '</div>'+
   100             '</div>'+
   104         '</div>'+
   101         '</div>'+
   105     '</div>';
   102         '<p class="abstract"><%= abstract %></p>'+
   106 var tmpl = _.template(actu);
   103     '</div>'
   107 
   104     ).template();
   108 squarify(data,0,0,760,358);
   105     
   109 
   106     /* Templates pour la vue liste */
   110 document.getElementById('treemap1').innerHTML = _(data).reduce(function(mem, d) {
   107    
   111     return mem + tmpl(d);
   108     var clusterListeTemplate = _(
   112 },"");
   109       '<div class="article" data-cluster-id="<%= id %>">'+
   113 
   110            '<div class="inner-article clearfix">'+
   114 //redimensionnement d'image
   111                '<h2><a href="http://localhost:8000/<%=query_id%>/<%=id%>/0/12/0" title="Lire l\'article" > <%= title %> »</a></h2>'+
   115 $(".actu").each(function(k,v){
   112 			   '<p class="number-article">'+
   116     var wActu = $(this).width();
   113                    '<a href="http://localhost:8000/<%=query_id%>/<%=id%>/0/12/0"><%= documents_number %> articles | <%= annotations.length %> annotations </a>'+
   117     var hActu = $(this).height();
   114                    '<a title="ajouter une annotation" class="add-annotation" href="#"></a>'+
   118     var img = $(this).find('img');
   115                '</p>'+
   119     var wImg = img.width();
   116                 '<div class="article-annotations">'+
   120     var hImg = img.height();
   117                    '<a title="48 annotations" class="blue" href="#" style="width:20%;"></a>'+
   121 
   118                    '<a title="title" class="green" href="#" style="width:20%;"></a>'+
   122     var ratioImg = wImg/hImg;
   119                    '<a title="title" class="red" href="#" style="width:40%;"></a>'+
   123     img.css('height',hActu);
   120                    '<a title="title" class="empty" href="#" style="width:20%;"></a>'+
   124     img.css('width',hActu*ratioImg);
   121                '</div>'+
   125     wImg = img.width();
   122                '<div class="article-content">'+
   126     hImg = img.height();
   123                    '<p class="resume"><%= abstract %></p>'+
   127 
   124                     '<ul class="links">'+
   128     if(wActu>wImg){
   125                        '<ul>'+
   129         var ratioImg = hImg/wImg;
   126                        '<% _(documents).each(function(d) { print("<li><a href=\'" + d.url_document + "\'>" + d.title.replace(/(^.{30,60})[\s].+$/m,\'$1&hellip;\') + "</a></li>"); }) %>'+
   130         img.css('width', wActu);
   127                        '</ul>'+
   131         img.css('height',wActu*ratioImg);
   128                    '</ul>'+
   132         wImg = img.width();
   129                '</div>'+
   133         hImg = img.height();
   130            '</div>'+
   134     }
   131        '</div>'
   135 
   132     ).template();
   136     if (wImg<wActu) {
   133 	
   137         img.css('margin-left',(wActu-wImg)/2);
   134 	var clusterListeTemplateDossierDoc = _(
   138     }else{
   135       '<div class="article" data-cluster-id="<%= id %>">'+
   139         img.css('margin-left',-(wImg-wActu)/2);
   136            '<div class="inner-article clearfix">'+
   140     }
   137                '<h2><a href="http://localhost:8000/documentary_files/<%=user%>/<%=id%>/0/12/<%=doc_id%>" title="Lire l\'article" > <%= title %> »</a></h2>'+
   141     if (hImg<hActu) {
   138 			   '<p class="number-article">'+
   142         img.css('margin-top',(hActu-hImg)/2);
   139                    '<a href="http://localhost:8000/documentary_files/<%=user%>/<%=id%>/0/12/<%=doc_id%>"><%= documents_number %> articles | <%= annotations.length %> annotations </a>'+
   143     }else{
   140                    '<a title="ajouter une annotation" class="add-annotation" href="#"></a>'+
   144         img.css('margin-top',-(hImg-hActu)/2);
   141                '</p>'+
   145     }
   142                 '<div class="article-annotations">'+
   146 });
   143                    '<a title="48 annotations" class="blue" href="#" style="width:20%;"></a>'+
       
   144                    '<a title="title" class="green" href="#" style="width:20%;"></a>'+
       
   145                    '<a title="title" class="red" href="#" style="width:40%;"></a>'+
       
   146                    '<a title="title" class="empty" href="#" style="width:20%;"></a>'+
       
   147                '</div>'+
       
   148                '<div class="article-content">'+
       
   149                    '<p class="resume"><%= abstract %></p>'+
       
   150                     '<ul class="links">'+
       
   151                        '<ul>'+
       
   152                        '<% _(documents).each(function(d) { print("<li><a href=\'" + d.url_document + "\'>" + d.title.replace(/(^.{30,60})[\s].+$/m,\'$1&hellip;\') + "</a></li>"); }) %>'+
       
   153                        '</ul>'+
       
   154                    '</ul>'+
       
   155                '</div>'+
       
   156            '</div>'+
       
   157        '</div>'
       
   158     ).template();
       
   159 	
       
   160 	var clusterTemplateDossierDoc = _( 
       
   161     '<div class="actu" style="left: <%=x%>px; top: <%=y%>px; width: <%=w - 1%>px; height: <%=h - 1%>px; background: #ffffff" data-cluster-id="<%=id%>">'+
       
   162         '<%=articles%>'+ // Pour l'image composite
       
   163         '<img src="<%=image_url%>" />' + // Pour l'image de cluster
       
   164         '<div class="voile"></div>'+
       
   165         '<div class="inner-actu">'+
       
   166             '<h2><a href="http://localhost:8000/documentary_files/<%=user%>/<%=id%>/0/12/<%=doc_id%>"><%-label%></a></h2>'+
       
   167             '<div class="links">'+
       
   168                 '<ul>'+
       
   169                     '<li><a href="#" title="<%=annotation_count%> Annotations sur ce cluster" class="file"><span><%=annotation_count%></span></a></li>'+
       
   170                 '</ul>'+
       
   171             '</div>'+
       
   172         '</div>'+
       
   173         '<p class="abstract"><%= abstract %></p>'+
       
   174     '</div>'
       
   175     ).template();
       
   176 	/* var clusterListeTemplate = _(
       
   177       '<div class="article" data-cluster-id="<%= id %>">'+
       
   178            '<div class="inner-article clearfix">'+
       
   179                '<h2><a onClick="getDocumentsWithAnnotations();" title="Lire l\'article" style="cursor:pointer;"> <%= title %> »</a></h2> <form id="ajaxgetdocuments" method="post" action="/<%=query_id%>/<%=id%>/0/10"> <input type="hidden" id="requestType"  name="requestType" value="documents"/></form>'+
       
   180 			   '<p class="number-article">'+
       
   181                    '<a href="http://localhost:8000/documents_cluster/<%=query_id%>/<%=id%>/0/10"><%= documents_number %> articles | <%= annotations.length %> annotations </a>'+
       
   182                    '<a title="ajouter une annotation" class="add-annotation" href="#"></a>'+
       
   183                '</p>'+
       
   184                 '<div class="article-annotations">'+
       
   185                    '<a title="48 annotations" class="blue" href="#" style="width:20%;"></a>'+
       
   186                    '<a title="title" class="green" href="#" style="width:20%;"></a>'+
       
   187                    '<a title="title" class="red" href="#" style="width:40%;"></a>'+
       
   188                    '<a title="title" class="empty" href="#" style="width:20%;"></a>'+
       
   189                '</div>'+
       
   190                '<div class="article-content">'+
       
   191                    '<p class="resume"><%= abstract %></p>'+
       
   192                     '<ul class="links">'+
       
   193                        '<ul>'+
       
   194                        '<% _(documents).each(function(d) { print("<li><a href=\'" + d.url_document + "\'>" + d.title.replace(/(^.{30,60})[\s].+$/m,\'$1&hellip;\') + "</a></li>"); }) %>'+
       
   195                        '</ul>'+
       
   196                    '</ul>'+
       
   197                '</div>'+
       
   198            '</div>'+
       
   199        '</div>'
       
   200     ).template();
       
   201 	*/
       
   202  var hTreemap = 600;//à définir
       
   203     $('#treemap').height(hTreemap);
       
   204     
       
   205     function showResults(results) 
       
   206 	{
       
   207 		
       
   208 		if (typeof (results.clusters) == 'undefined')
       
   209 		{
       
   210 			$('#create-dossierDoc').hide();
       
   211 		}
       
   212 		else
       
   213 		{
       
   214 			$('#create-dossierDoc').show();
       
   215 		}
       
   216 		$(".articles").empty();
       
   217 		$(".articles").html(_(results.clusters).reduce(function(mem, c) { return mem + clusterListeTemplate(c); },''));
       
   218         var data = _(results.clusters).map(function(cluster, i) {
       
   219             var hue = (parseInt(cluster.id)%6)/6
       
   220             return {
       
   221                 id: cluster.id,
       
   222 				query_id: cluster.query_id,
       
   223                 label: cluster.title,
       
   224                 abstract : cluster.abstract,
       
   225                 value: parseFloat(cluster.weight),
       
   226                 annotation_count: cluster.annotations.length,
       
   227                 image_url: cluster.url_image || false,
       
   228                 articles: cluster.documents.filter(function(article) {
       
   229                     return !!article.url_image
       
   230                 })
       
   231                 .map(function(article, j) {
       
   232                     return {
       
   233                         value: parseFloat(article.weight),
       
   234                         image_url: article.url_image || false
       
   235                     }
       
   236                 })
       
   237             }
       
   238         });
       
   239         data = _(data).sortBy(function(d) {
       
   240             return -d.value;
       
   241         });
       
   242         squarify(data,0,0,760,hTreemap);
       
   243         _(data).each(function(cluster) {
       
   244             squarify(cluster.articles, 0, 0, cluster.w - 1, cluster.h - 1);
       
   245             _(cluster.articles).sortBy(function(d) {
       
   246                 return -d.value;
       
   247             });
       
   248             cluster.articles = _(cluster.articles).reduce(function(mem, a) {
       
   249                 return mem + articleTemplate(a);
       
   250             }, "");
       
   251         });
       
   252         var treemapHtml = _(data).reduce(function(mem, d) {
       
   253             return mem + clusterTemplate(d);
       
   254         },"");
       
   255 		$('#treemap #actus').empty();
       
   256         $('#treemap #actus').html(treemapHtml);
       
   257 
       
   258         //redimensionnement d'image        
       
   259         $(".actu img").each(function() 
       
   260 		{
       
   261 			
       
   262 			var img = $(this),
       
   263                 div = $(this).parent();
       
   264             $(this).load(function() {
       
   265                 var iw = $(this).width(),
       
   266                     ih = $(this).height(),
       
   267                     dw = $(this).parent().width(),
       
   268                     dh = $(this).parent().height(),
       
   269                     scale = Math.max(dw/iw, dh/ih),
       
   270                     niw = iw * scale,
       
   271                     nih = ih * scale;
       
   272                 img.css({
       
   273                     width: niw,
       
   274                     height: nih,
       
   275                     "margin-left": (dw - niw) / 2,
       
   276                     "margin-top": (dh - nih) / 3
       
   277                 });
       
   278             });
       
   279         });
       
   280         
       
   281      /*   $(".cluster").html(data.reduce(function(mem, c) {
       
   282             return mem + '<li><a href="http://localhost:8000/'+c.query_id+'/'+c.id+'/0/12/0" title="Afficher le cluster" data-cluster-id="' + c.id + '">' + c.label + '</a></li>'
       
   283         }, ''));
       
   284         
       
   285         $(".actu, .cluster a, .article").hover
       
   286 		(
       
   287             function() 
       
   288 			{
       
   289                 $("body").trigger("select-cluster", $(this).attr("data-cluster-id"));
       
   290             },
       
   291             function() 
       
   292 			{
       
   293                 $("body").trigger("unselect-cluster", $(this).attr("data-cluster-id"));
       
   294             }
       
   295         )*/
       
   296 		
       
   297         
       
   298     }
       
   299     
       
   300 	 function showResultsDossierDoc(results) 
       
   301 	 {
       
   302 		$(".articles").empty();
       
   303 		$(".articles").html(_(results.clusters).reduce(function(mem, c) { return mem + clusterListeTemplateDossierDoc(c); },''));
       
   304 		 var data = _(results.clusters).map(function(cluster, i) {
       
   305 			 var hue = (parseInt(cluster.id)%6)/6
       
   306             return {
       
   307                 id: cluster.id,
       
   308 				doc_id: cluster.doc_id,
       
   309 				user: cluster.user,
       
   310                 label: cluster.title,
       
   311                 abstract : cluster.abstract,
       
   312                 value: parseFloat(cluster.weight),
       
   313                 annotation_count: cluster.annotations.length,
       
   314                 image_url: cluster.url_image || false,
       
   315                 articles: cluster.documents.filter(function(article) {
       
   316                     return !!article.url_image
       
   317                 })
       
   318                 .map(function(article, j) {
       
   319                     return {
       
   320                         value: parseFloat(article.weight),
       
   321                         image_url: article.url_image || false
       
   322                     }
       
   323                 })
       
   324             }
       
   325         });
       
   326 	
       
   327         data = _(data).sortBy(function(d) {
       
   328             return -d.value;
       
   329         });
       
   330 
       
   331 		squarify(data,0,0,760,hTreemap);
       
   332 		_(data).each(function(cluster) {
       
   333             squarify(cluster.articles, 0, 0, cluster.w - 1, cluster.h - 1);
       
   334             _(cluster.articles).sortBy(function(d) {
       
   335                 return -d.value;
       
   336             });
       
   337             cluster.articles = _(cluster.articles).reduce(function(mem, a) {
       
   338                 return mem + articleTemplate(a);
       
   339             }, "");
       
   340         });
       
   341 		 var treemapHtml = _(data).reduce(function(mem, d) {
       
   342             return mem + clusterTemplateDossierDoc(d);
       
   343         },"");
       
   344 		$('#treemap #actus').empty();
       
   345         $('#treemap #actus').html(treemapHtml);
       
   346 
       
   347         //redimensionnement d'image        
       
   348         $(".actu img").each(function() 
       
   349 		{
       
   350 			var img = $(this),
       
   351                 div = $(this).parent();
       
   352 			var loadThisImage = function() {
       
   353                 var iw = img.width(),
       
   354                     ih = img.height(),
       
   355                     dw = div.width(),
       
   356                     dh = div.height(),
       
   357                     scale = Math.max(dw/iw, dh/ih),
       
   358                     niw = iw * scale,
       
   359                     nih = ih * scale;
       
   360                 img.css({
       
   361                     width: niw,
       
   362                     height: nih,
       
   363                     "margin-left": (dw - niw) / 2,
       
   364                     "margin-top": (dh - nih) / 3
       
   365                 });
       
   366             }
       
   367 			if (this.width) {
       
   368 				loadThisImage();
       
   369 			} else {
       
   370             	img.load(loadThisImage);
       
   371 			}
       
   372         });
       
   373   
       
   374         /*$("body").on("select-cluster", function(e, clusterid) {
       
   375             $(".actu[data-cluster-id='" + clusterid + "'], .cluster a[data-cluster-id='" + clusterid + "'], .article[data-cluster-id='" + clusterid + "']").addClass("selected");
       
   376         });
       
   377         $("body").on("unselect-cluster", function(e, clusterid) {
       
   378             $(".actu[data-cluster-id='" + clusterid + "'], .cluster a[data-cluster-id='" + clusterid + "'], .article[data-cluster-id='" + clusterid + "']").removeClass("selected");
       
   379         });*/
       
   380     }
       
   381 
       
   382 
       
   383     $("#liste").hide();
       
   384 //})