source: consulta_publica/visualization/templates/visualization.index.html @ 7784803

baseconstituyenteestudiantesgeneralplan_patriasala
Last change on this file since 7784803 was 7310249, checked in by rudmanmrrod <rudman22@…>, 7 años ago

Solventadas consultas en generales en la consulta y procesamiento, agregados graficos de barra y torta para las respuestas simple/multiple/si-no de la consulta, Agregado modelos de estado, municipio y parroquia de Argenis

  • Propiedad mode establecida a 100644
File size: 22.1 KB
Línea 
1{% extends 'base.template.html' %}
2{% load staticfiles %}
3{% block title %} Visualización {% endblock %}
4{% block headScript %}
5    <link rel="stylesheet" type="text/css" href="{% static "topic_explorer/css/topic_explorer.css" %}"/>
6    <script src="{% static "js/d3.v3.min.js" %}"></script>
7    <script src="{% static "topic_explorer/js/util.js" %}"></script>
8    <script src="{% static "topic_explorer/js/fulltext.js" %}"></script>
9    <script src="{% static "topic_explorer/js/icons.js" %}"></script>
10{%endblock%}
11{% block superContent %}
12<div class="content" id="content">
13    <h1 class="text-center">Visualización de Tópicos</h1><hr>
14    <div class="container">
15      <div class="row">
16        <div class="col-md-offset-5">
17          <div class="form-inline">
18            <div class="btn-group">
19              <button type="button" id="submit" class="btn btn-default" >Visualizar</button>
20              <a class="btn btn-default dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></a>
21              <ul class="dropdown-menu">
22                {% for k in topics_range %}
23                  <li><a href="javascript:visualize({{k}})">{{k}} Topics</a></li>
24                {% endfor %}
25              </ul>
26            </div>
27          </div>
28        </div>
29      </div>
30   
31      <div class="progress non-null" role="progressbar" id="status">
32        <div class="progress-bar progress-bar-striped active" aria-valuemin="0" aria-valuemax="100" style="width: 45%">
33          <div class="bar" style="width:25%">Loading documents...</div>
34        </div>
35      </div>
36   
37    </div>
38   
39    <div id="chart"> </div><br><br>
40   
41    <div id="controls" style="display:none;">
42      <strong>Opciones</strong>
43      <label class="checkbox"><input class="sort" type="checkbox"> Orden alfabético</label>
44      <label class="checkbox"><input class="scale" type="checkbox"> Normalizar barras de tópicos</label>
45      <button class="btn btn-default reset" type="button" onclick="resetTopicSort()" disabled>Restaurar orden de tópicos</button><br>
46      <button class="btn btn-default topdoc" type='button' style="display:none">Ordenar documentos para tópico [Topic]</button>
47    </div>
48</div>
49<script>
50  var scrollLegend;
51  $('#helpBtn').click(function() {
52      $('.help').toggle();
53      if (!$('#helpBtn').hasClass('active')) {
54        $('#helpBtn').data('tooltip').options.title = "Hide help";
55        $('#helpBtn').addClass('active');
56      } else {
57        $('#helpBtn').data('tooltip').options.title = "Show help";
58        $('#helpBtn').removeClass('active');
59      }
60      scrollLegend();
61    });
62
63    var docid = "{{filename}}" ;
64    if (docid!='None') {
65      docid = decodeURIComponent(docid);
66      $('#hidden_id').val(docid);
67      $('.twitter-share-button').attr('data-text', "What's similar to " +docid+"? Discover with the #InPhO Topic Explorer");
68   
69    }
70
71    var roottopic = '{{topic_no}}' ;
72
73    if (roottopic!='None') {
74      $('.title').html('Topic ' + roottopic);
75      $('.twitter-share-button').attr('data-text', "Check out topic "+ roottopic+" at the #InPhO Topic Explorer!");
76    }
77   
78    if (docid!='None' || roottopic!='None')
79      $('.non-null').show()
80    else
81      $('.null').show();
82
83    function visualize(k) {
84      if (docid!='None') {
85        var url = "{0}//{1}:{2}/administrador/visualizacion/doc/{{id}}/{3}/".format(window.location.protocol, window.location.hostname, window.location.port, k);
86        url += docid ;
87      }
88      else
89      {
90        var url = "{0}//{1}:{2}/administrador/visualizacion/topic/{{id}}/{3}/{{topic_no}}/".format(window.location.protocol, window.location.hostname, window.location.port, k);
91      }
92      window.location = url;
93    }
94
95var icons = ["link","ver"]; 
96var maxRows = 25;
97var minCols = 2;
98
99var margin = {top: 80, right: 40, bottom: 20, left: 15 + (icons.length * 20)},
100    width = 660 - margin.left - margin.right,
101    height = 300 - margin.top - margin.bottom;
102
103var x = d3.scale.linear()
104    .range([0, width]);
105
106var y = d3.scale.ordinal()
107    .rangeRoundBands([0, height], .1, 0);
108
109var xAxis = d3.svg.axis()
110    .scale(x)
111    .orient("top")
112    .ticks(10, "%");
113
114var yAxis = d3.svg.axis()
115    .scale(y)
116    .orient("left");
117
118function computeWidth(numCols) { 
119  $('#legend').attr("width", margin.right + (numCols*25) + 20 + margin.right);
120  $('#main').attr("width", Math.max($(window).width() - $('#legend').width() - 200 + margin.right, 750));
121  $('#controls').css("left", Math.max($(window).width() - $('#legend').width() - 200 + margin.right, 750) + 40);
122  width = Math.max($(window).width() - $('#legend').width() - 200 + margin.right, 750) - margin.left - margin.right;
123  x = d3.scale.linear()
124    .range([0, width]);
125  x.domain([0,1]);
126  xAxis = d3.svg.axis()
127    .scale(x)
128    .orient("top")
129    .ticks(10, "%");
130}
131
132function computeHeight(data, numLegendRows) { 
133  height = (data.length * 20);// - margin.top - margin.bottom;
134  y = d3.scale.ordinal()
135   .rangeRoundBands([0, height], .1, 0);
136  y.domain(data.map(function(d) { return d.doc; }));
137  yAxis = d3.svg.axis()
138    .scale(y)
139    .orient("left");
140}
141
142var dataset;
143var original_root;
144
145var svg = d3.select("#chart").append("svg")
146    .attr("width", width + margin.left + margin.right)
147    .attr("height", height + margin.top + margin.bottom)
148    .attr("id","main")
149    .attr("class", "main")
150  .append("g")
151    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
152    .on("mouseleave", function() {
153        $(".legend rect").removeClass('hover').tooltip('hide');
154      });
155
156var legend = d3.select("#chart").append("svg")
157    .attr("width", "350")
158    .attr("id", "legend")
159    .attr("class", "main")
160  .append("g")
161    .attr("transform","translate("+margin.right+","+ margin.top + ")");
162
163function calculateTopicMap(data, scale, sortFn){
164  data.forEach(function(d) {
165    var sizeFactor = (scale) ? d.prob : 1.0
166    var x0 = 0;
167    if (sortFn) d.topicMap = d3.keys(original_root.topics)
168      .sort(sortFn)
169      .map(function(name) { return {name: name, x0: x0, x1: x0 += +(d.topics[name]*sizeFactor) }; });
170    else // maintain sort order
171      d.topicMap = d.topicMap.map(function (topic) { return topic.name; })
172        .map(function(name) { return {name: name, x0: x0, x1: x0 += +(d.topics[name]*sizeFactor) }; });
173  });
174 
175}
176
177var url;
178
179if (docid!='None') {
180  url = "/administrador/visualizacion/docs_topics/{{id}}/{{k_param}}/" + docid;
181}
182else {
183  url = "/administrador/visualizacion/topics/{{id}}/{{k_param}}/" + roottopic;
184}
185
186var n = inpho.util.getValueForURLParam('n');
187if (n) url += "?n=" + n;
188
189var tops;
190d3.json(url, function(error, data) {
191  $('#status .bar').css('width', '50%').text('Loading topics...');
192  if (error) {
193    $('#status .progress-bar').removeClass('active progress-bar-striped');
194    var errormsg;
195   
196    if (roottopic) errormsg = "Invalid topic: " + roottopic + ".";
197    else errormsg = "Invalid document: " + docid + ".";
198
199    $('#status .bar').addClass('progress-bar-danger').text(errormsg);
200    return false;
201  }
202  d3.json("/administrador/visualizacion/topics.json/{{id}}/{{k_param}}", function(error_top, topics) {
203    $('#status .bar').css('width', '75%').text('Rendering chart...');
204    if (error_top) {
205      $('#status .progress-bar').removeClass('active progress-bar-striped');
206      $('#status .bar-danger').addClass('progress-bar-danger').text('Could not load topic list.');
207      return false;
208    }
209    $('#submit').text(d3.keys(topics).length + ' Tópicos');
210   
211 
212    var legendCols = Math.max(Math.ceil(d3.keys(topics).length / Math.min(data.length, maxRows)), minCols);
213    var legendFactor = Math.ceil(d3.keys(topics).length / legendCols);
214    computeHeight(data,legendFactor);
215
216    $("#main").attr("height", height + margin.top + margin.bottom);
217    $("#legend").attr("height", (legendFactor * 20) + margin.top + margin.bottom);
218    computeWidth(legendCols);
219 
220 
221    x.domain([0, 1.0]);
222    tops = topics;
223      //.sort();
224    dataset = data;
225    original_root = data[0];
226    if (roottopic) docid = data[0]['doc'];
227 
228    calculateTopicMap(data, true, function(a,b) {return data[0].topics[b] - data[0].topics[a];});
229 
230 
231 
232    svg.append("g")
233        .attr("class", "x axis")
234        .attr("transform", "translate(10,-10)")
235        .call(xAxis)
236      .append("text")
237        //.attr("transform", "rotate(-120)")
238        .attr("class", "axis_label")
239        .attr("dy", "-2em")
240        .style("text-anchor", "start")
241        .text("Similarity to " + (roottopic ? ("Topic " + roottopic) : '"'+original_root['label']+'"'));
242 
243    svg.append("g")
244        .attr("class", "y axis")
245        .call(yAxis)
246        .selectAll("text")
247        .attr("class", function(d) { return (d == docid && roottopic != null) ? "primary" : "" })
248        .on("click", function(d) { window.location.href = "administrador/visualizacion/doc/{{id}}/" + d;})
249 
250    svg.select(".y.axis").selectAll("g")
251        .insert("rect", ":first-child")
252          .attr("x", -margin.left + 5)
253          .attr("y", -9)
254          .attr("width", margin.left-5)
255          .attr("height", 18)
256          .style("opacity", "0");
257 
258    var ticks = svg.select(".y.axis").selectAll("g")
259        .on("mouseenter", function(d) { 
260          $('text', this).attr('text-decoration', 'underline')
261            .attr('font-weight', 'bold');     
262          svg.selectAll(".doc")
263            .filter(function(doc,i) { return doc.doc == d})
264            .attr("class", function(d) { return (d.doc == docid ? "doc primary" : "doc") + " hover"}); 
265          })
266        .on("mouseleave", function(d) { 
267          $('text',this).removeAttr('text-decoration')
268            .removeAttr('font-weight'); 
269          svg.selectAll(".doc")
270            .filter(function(doc,i) { return doc.doc == d})
271            .attr("class", function(d) { return d.doc == docid ? "doc primary" : "doc"}); 
272          });
273
274    for (var i = 0; i < icons.length; i++) {
275      icon_fns[icons[i]](ticks,i);
276    }
277 
278    // draw total bar
279    var doc = svg.selectAll("doc")
280        .data(data)
281      .enter().append("g")
282        .attr("class", function(d) { return d.doc == docid ? "doc primary" : "doc"})
283        .attr("transform", function(d) { return "translate(10," + y(d.doc) + ")"; })
284        .on("mouseover", function(d) {
285            var tick = $("text:contains(" + d.doc +")")
286              .filter(function() {return $(this).text().trim() == d.doc })
287              .attr("font-weight", "bold");
288            icons.reduce(function(prev,cur) {
289              return prev.next(".{0}Icon".format(cur)).css('opacity', '1.0');
290            }, tick);
291          })
292        .on("mouseout", function(d) {
293            var tick = $("text:contains(" + d.doc +")")
294              .filter(function() {return $(this).text().trim() == d.doc })
295              .attr("font-weight", "normal");
296            icons.reduce(function(prev, cur) {
297              return prev.next(".{0}Icon".format(cur)).css('opacity', '');
298            }, tick);
299          });
300 
301    // Draw topic bars
302    doc.selectAll("rect")
303        .data(function(d) { return d.topicMap; })
304      .enter().append("rect")
305        .attr("height", y.rangeBand())
306        .attr("x", function(d) { return x(d.x0); })
307        .attr("width", function(d) { return x(d.x1) - x(d.x0); })
308        .attr("class", function(d) { return "top_" + d.name; })
309        .on("mouseover", function(d) {
310            // SVG element z-index determined by render order, not style sheet
311            // so element must be reappended to the end on hover so border
312            // is not occluded
313            var parent = $(this).parent();
314            $(this).detach().appendTo(parent);
315            $(".docLabel", parent).detach().appendTo(parent);
316            $(".docLabel", parent).addClass("hover");
317            $('.legend rect').not('.top_' + d.name).tooltip('hide');
318            $(".top_" + d.name).addClass('hover');
319            $('.legend rect.top_' + d.name).tooltip('show');
320          })
321        .on("mouseout", function(d) {
322            var parent = $(this).parent();
323            $(".docLabel", parent).removeClass("hover");
324            $(".top_" + d.name).removeClass('hover');
325          })
326        .on("click", function(d) { topicSort(d.name); })
327        .style("fill", function(d) { return topics[d.name]['color']; });
328   
329    doc.append("text")
330          .text(function(d) { return d.label; })
331          .attr("class","docLabel")
332          .attr("dx", "3")
333          .attr("dy", "13");
334    var legendElts = legend.selectAll(".legend")
335        .data(data[0].topicMap.map(function(t) { return t.name;}))
336      .enter().append("g")
337        .attr("class", function(d) { return "legend top_" + d; })
338        .attr("transform", function(d, i) { return "translate("+(55 * Math.floor(i / legendFactor))+"," + y(i % legendFactor) + ")"; });
339 
340    legendElts.append("rect")
341        .attr("width", 18)
342        .attr("height", 18)
343        .attr("class", function(d) { return "top_" + d; })
344        .style("fill", function(d) { return topics[d]['color']; })
345        //.attr("data-toggle", "tooltip")
346        .attr("data-placement", "right")
347        .attr("title", function(d) { 
348          return "<strong>Topic {0}:</strong> <!--H(T<sub>{0}</sub>)={1}-->".format(d, topics[d].H.toFixed(2)) + "<br />"
349            + d3.keys(topics[d].words).sort(function(a,b) {
350              if (topics[d].words[a] > topics[d].words[b])
351                return -1;
352              else if (topics[d].words[a] < topics[d].words[b])
353                return 1;
354              else
355                return 0;
356            }).join(", ") + ", ..."; })
357        .on("click", function(d) { topicSort(d); })
358        .on("mouseover", function(d) {
359            $(".top_" + d).addClass('hover').tooltip('show');
360          })
361        .on("mouseout", function(d) {
362            $(".top_" + d).removeClass('hover').tooltip('hide');
363          });
364 
365    $(".legend rect").tooltip({container:'body', trigger: 'manual', animation: false, html: true});
366 
367    legendElts.append("text")
368        .attr("dx", -6)
369        .attr("y", 9)
370        .attr("dy", ".35em")
371        .style("text-anchor", "end")
372        .text(function(d) { return d; });
373 
374 
375    legend.append("text")
376        .attr("dx", -6)
377        .attr("dy", "-.35em")
378        .attr("font-weight", "bold")
379        .style("text-anchor", "end")
380        .text(d3.keys(topics).length);
381    legend.append("text")
382        //.attr("transform", "rotate(-120)")
383        .attr("class", "axis_label")
384        .attr("dy", "-.35em")
385        .attr("font-weight", "bold")
386        .style("text-anchor", "start")
387        .text("Topics");
388    legend.append("text")
389        //.attr("transform", "rotate(-120)")
390        .attr("class", "axis_label")
391        .attr("dy", "-.45em")
392        .attr("dx", "5em")
393        .attr("font-size", "10px")
394        .style("text-anchor", "start")
395        .text("ordered by P( T | " + docid + " )");
396
397    d3.select(window).on('resize', resize);
398 
399    function resize() {
400      computeWidth(legendCols);
401 
402      /* Update the axis with the new scale */
403      svg.select('.x.axis')
404        .call(xAxis);
405 
406      doc.selectAll('rect')
407        .attr("x", function(d) { return x(d.x0); })
408        .attr("width", function(d) { return x(d.x1) - x(d.x0); });
409    }
410     
411    d3.select(".sort").on("change", alphabetSort);
412   
413    $('#status .progress-bar').addClass('progress-bar-success').css("width","100%").attr("aria-valuenow","100").text("Complete!");
414    setTimeout(function() { 
415      $('#status').hide(500);
416      setTimeout(function() {$('#controls').css({'top' : $('#legend').height() + $('#legend').position().top}).show();}, 500);
417      } , 500);
418 
419    $(window).on("scroll", scrollLegend);
420    scrollLegend = function() {
421      var scrollPos = $(window).scrollTop();
422      var chartHeight = $('#chart').position().top;
423      var legendHeight = $('#legend').height();
424      var heightFac = -60;
425      if((scrollPos - chartHeight - margin.top - heightFac) <= 0) {
426        $('#legend').css({'position': 'absolute', 'top' : chartHeight});
427        $('#controls').css({'position': 'absolute', 'top' : legendHeight + chartHeight});
428      } else if ((scrollPos - chartHeight - heightFac) < (margin.top)) {
429        $('#legend').css({'position': 'absolute', 'top' : scrollPos + heightFac});
430        $('#controls').css({'position': 'absolute', 'top' : legendHeight+ scrollPos + heightFac});
431      } else {
432        $('#legend').css({'position': 'fixed', 'top' : heightFac});
433        $('#controls').css({'position': 'fixed', 'top' : legendHeight + heightFac});
434      }}
435 
436    for (var i = 0; i < icons.length; i++) {
437      $(".{0}Icon".format(icons[i])).tooltip({placement: 'top', title: icon_tooltips[icons[i]], container: 'body', html: true, animation: false});
438    }
439  }); 
440});
441
442  function scaleTopics() {
443    var numTopics = dataset[0].topics.length;
444    var delay = function(d, i) { return i * (500/numTopics); },
445        negdelay = function(d, i) { return (numTopics-i) * (500/numTopics); };
446
447    calculateTopicMap(dataset, !this.checked);
448
449    $(".doc").each(function(i,elt) {
450        $(elt).children()
451          .sort(function(a,b) { return $(a).attr('x') - $(b).attr('x'); })
452          .each(function(j,child) {
453            $(child).detach().appendTo($(elt));
454        })
455      });
456
457    svg.selectAll(".doc")
458      .selectAll("rect")
459      .data(function(d) { return d.topicMap; })
460      .style("fill", function(d) { return tops[d.name]['color']; })
461      /*.on("mouseover", function(d) {
462          // SVG element z-index determined by render order, not style sheet
463          // so element must be reappended to the end on hover so border
464          // is not occluded
465          var parent = $(this).parent();
466          $(this).detach().appendTo(parent);
467          $(".docLabel", parent).detach().appendTo(parent);
468          $('.legend rect').not('.top_' + d.name).tooltip('hide');
469          $(".top_" + d.name).addClass('hover');
470          $('.legend rect.top_' + d.name).tooltip('show');
471        })
472      .on("mouseout", function(d) {
473          $(".top_" + d.name).removeClass('hover');
474        })*/
475      .transition().duration(500).ease("linear").delay(this.checked ? delay : negdelay)
476      .attr("x", function(d) { return x(d.x0); })
477      .attr("width", function(d) { return x(d.x1) - x(d.x0); })
478      .attr("class", function(d) { return "top_" + d.name; });
479
480    svg.selectAll(".x.axis text.axis_label").text(this.checked ? 
481      "Proportion of document assigned to topic" : 
482      ("Similarity to " + (roottopic ? ("Topic " + roottopic) : '"'+original_root.label+'"')));
483  }
484
485  d3.select(".scale").on("change", scaleTopics);
486  function sortDataset(sortFn) {
487    dataset = dataset.sort(sortFn);
488
489    var y0 = y.domain(dataset
490        .map(function(d) { return d.doc; }))
491        .copy();
492
493    var transition = svg.transition().duration(500),
494        delay = function(d, i) { return i * 25; };
495
496    transition.selectAll(".doc")
497        .delay(delay)
498        .attr("transform", function(d) { return "translate(10," + y(d.doc) + ")"; });
499        //.attr("y", function(d) { return y(d.doc); });
500
501    transition.select(".y.axis")
502        .call(yAxis)
503      .selectAll("g")
504        .selectAll("text")
505        .delay(delay);
506  }
507
508  function alphabetSort() {
509    // Copy-on-write since tweens are evaluated after a delay.
510    if (this.checked)
511      sortDataset(function(a, b) { return d3.ascending(a.doc, b.doc); });
512    else
513      sortDataset(function(a, b) { return b.prob - a.prob; });
514  }
515
516  function resetTopicSort() {
517    $('.reset').attr('disabled',true);
518    $('.topicsort').attr('disabled',true);
519    $('.selected').removeClass('selected');
520    $('.topdoc').hide();
521    $('.topdoc').text('Top Documents for [Topic]');
522    if (!($('.sort')[0].checked))
523      sortDataset(function(a,b) { return b.prob - a.prob; });
524
525    redrawBars(function(a,b) { return original_root.topics[b] - original_root.topics[a]; });
526  }
527
528  function topicSort(topic) {
529    // Copy-on-write since tweens are evaluated after a delay.
530    $('.sort').removeAttr('checked');
531    if (topic) {
532      sortDataset(function(a, b) { return b.topics[topic] - a.topics[topic]; });
533      $('.selected').removeClass('selected');
534      $(".top_" + topic).addClass('selected');
535      $('.reset').removeAttr('disabled');
536      $('.topdoc').text('Top Documents for Topic ' + topic);
537      $('.topdoc').show();
538      $('.topdoc').click(function URL() {location.href = location.origin + '/administrador/visualizacion/topic/{{id}}/{{k_param}}/' + topic;});
539      $('.topdoc').mouseenter(function() {
540          $('.legend rect').not('.top_' + topic).tooltip('hide');
541          $(".legend rect.top_" + topic).tooltip('show'); });
542      $('.topdoc').mouseleave(function() { $(".top_" + topic).tooltip('hide'); });
543
544    } else {
545      $('.selected').removeClass('selected');
546      sortDataset(function(a, b) { return b.prob - a.prob; });
547    }
548
549
550    var sortFn = function(a,b) {
551      if (a == topic) return -1;
552      else if (b == topic) return 1;
553      else return dataset[0].topics[b] - dataset[0].topics[a];
554      //else return original_root.topics[b] - original_root.topics[a];
555    } 
556    redrawBars(sortFn);
557  }
558
559  function redrawBars(sortFn) { 
560    $("#legend .hover").removeClass("hover");
561    var numTopics = dataset[0].topics.length;
562    var delay = function(d, i) { return i * (1000/numTopics); },
563        negdelay = function(d, i) { return (numTopics-i) * (1000/numTopics); };
564    calculateTopicMap(dataset, !($('.scale')[0].checked), sortFn);
565   
566    svg.selectAll(".doc")
567      .selectAll("rect")
568      .data(function(d) { return d.topicMap; })
569      .style("fill", function(d) { return tops[d.name]['color']; })
570      /*
571      .on("mouseover", function(d) {
572          // SVG element z-index determined by render order, not style sheet
573          // so element must be reappended to the end on hover so border
574          // is not occluded
575          var parent = $(this).parent();
576          $(this).detach().appendTo(parent);
577          $(".docLabel", parent).detach().appendTo(parent);
578          $('.legend rect').not('.top_' + d.name).tooltip('hide');
579          $(".top_" + d.name).addClass('hover');
580          $('.legend rect.top_' + d.name).tooltip('show');
581        })
582      .on("mouseout", function(d) {
583          $(".top_" + d.name).removeClass('hover');
584        })*/
585      .transition().duration(1000).ease("linear").delay(this.checked ? delay : negdelay)
586      .attr("x", function(d) { return x(d.x0); })
587      .attr("width", function(d) { return x(d.x1) - x(d.x0); })
588      .attr("class", function(d) { return "top_" + d.name; });
589
590  }
591 
592   
593</script>
594
595{% endblock %}
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.