Commit ea03a7c7 authored by Romain Loth's avatar Romain Loth

histogram variant for politoscope daily data

parent d06090e9
......@@ -387,6 +387,12 @@
<!-- filled by query (user search value) to wos api -->
<div id="search_histogram" class="over-panels"></div>
</div><!-- /row -->
<!-- histogram of selected nodes, variant ; TODO unify -->
<div class="histogramDailyVariantModule">
<!-- filled by query (user search value) to wos api -->
<div id="search_histogram2" class="over-panels"></div>
</div><!-- /row -->
</div>
......
/* ---------------------------------------------------------------- */
/* --------------------- search histogram ----------------------- */
/* ---------------------------------------------------------------- */
// TODO be able to expose things from module like a histo.graph object
var hg
var $search_histogram = $("#search_histogram2")
//method for calling the ISC-API and get pubs-distribution of the suggested term
function search_proposed_terms_and_draw( the_queries ) {
console.log("search_proposed_terms_and_draw:\n"
+"i'm searching:\n"
+JSON.stringify(the_queries)) ;
$search_histogram.html("Searching for matching Twitter data...")
// the_queries is an array of str,
// but api.iscpif.fr/v2/pub/politic/france/twitter only takes single LUCENE query
var luc_q = the_queries.map(function (w) { return '('+w+')' }).join(" OR ")
var args = {
// luc_q is a str
"q": luc_q,
"interval": "day"
// no since and until: we want the entire period
}
var docs_days = [] ;
$search_histogram
.html('<p class="micromessage">Waiting for histogram data</p>')
$.ajax({
type: "GET",
url: 'https://api.iscpif.fr/v2/pub/politic/france/twitter/histogram',
data: args,
dataType: "json",
success : function(data, textStatus, jqXHR) {
// ES aggs response, for example
// data = {"took":91,"total":121673,"aggs":{"publicationCount":{"buckets":[{"key":1989,"doc_count":880},{"key":1990,"doc_count":1088},...,{"key":2012,"doc_count":9543},{"key":2013,"doc_count":8832}]}},"hits":{"total":121673,"max_score":0,"hits":[]}}
console.log(">> incoming api data <<")
console.log(data)
if(data.results.total==0) {
return false;
}
else {
for(var i in data.results.hits) {
var elem = data.results.hits[i]
var day = elem.key_as_string+""
var ndocs = elem.doc_count
docs_days.push( [ day , ndocs] )
}
// docs_days is now an array of couples [["2016-01-04T00:00:00.000Z",25],["2016-01-05T00:00:00.000Z",28],...]
// console.log("docs_days",docs_days)
// counts_by_year_array
draw_histogram(docs_days) ;
return true ;
}
},
error: function(exception) {
// console.log("search_proposed_terms_and_draw:exception"
// + JSON.stringify(exception))
$search_histogram
.html('<p class="micromessage">'
+'<b>No histogram</b>: too many nodes selected</b>'
+'</p>')
}
})
}
// gotNodeSet event when Tinawab did main search behavior (select nodes)
$("#searchinput").on("tw:gotNodeSet", function(e) {
// console.warn("event 'nodes' --> the event's nodes: " + JSON.stringify(e.nodeIds)) ;
clean_histogram() ;
// now we may want to do other things (draw histogram, suggest term)
newnodesHistogramBehavior(e.nodeIds, e.q) ;
});
// eraseNodeSet event when Tinawab canceled the previous selections
$("#searchinput").on("tw:eraseNodeSet", function(e) {
// console.warn("event 'erase'") ;
clean_histogram() ;
$search_histogram.hide() ;
});
// emptyNodeSet event when Tinaweb search found nothing
$("#searchinput").on("tw:emptyNodeSet", function(e) {
// console.warn("event 'not found'") ;
clean_histogram() ;
$search_histogram.hide() ;
});
function newnodesHistogramBehavior(selectedNodeIds, unusedQuery) {
// console.log('FUN additionalSearchBehavior' + '\nselectedNodeIds:' +JSON.stringify(selectedNodeIds) ) ;
if( selectedNodeIds != null && selectedNodeIds.length > 0 ) {
// query : IF in the Map -> GO to ISC-API (search and draw it)
var selectedLabels = [] ;
for (i in selectedNodeIds) {
var thisId = selectedNodeIds[i]
if (TW.Nodes[thisId] != null) {
selectedLabels.push(TW.Nodes[thisId].label)
}
else {
console.log('ID error on TW.Nodes['+thisId+']')
}
}
// console.log('\n\n\n<---!--->\nselectedLabels' + JSON.stringify(selectedLabels))
search_proposed_terms_and_draw ( selectedLabels ) ;
}
}
// use dygraph lib to draw below the crowdsourcing div
function draw_histogram(counts_by_days_array) {
// 1) layout for the div#search_histogram
// /!\ this div *needs* padding:0 /!\;
$search_histogram.height("15em").show()
// 2) data preparation
// (cumulated sliding window over [J-7; J])
var cumulated_res = [] ;
for (i in counts_by_days_array) {
var isoDate = counts_by_days_array[i][0]
// 2016-01-04T00:00:00.000Z ~~> 2016/01/04
var theDate = new Date(isoDate)
var sum = 0
var nvalues = 0
for (var j=i; j >= Math.max(i-6, 0); j--) {
sum += counts_by_days_array[j][1]
nvalues++
}
cumulated_res.push([theDate, sum])
}
// console.log('=== GRAPH PREPARATION ===') ;
// console.log("counts_by_days_array", counts_by_days_array)
// console.log('cumulated_res', cumulated_res) ;
var emValue = parseFloat(getComputedStyle(document.body).fontSize)
// 3) call histogram lib
hg = new Dygraph($search_histogram[0],
cumulated_res,
{
labels: ['day', 'n'],
visibility: [true],
// ^^^
// n
drawPoints: true,
// pixels between labels <=> 1.5 em
axes: {
x: { pixelsPerLabel: 3 * emValue },
y: { pixelsPerLabel: 2 * emValue }
},
fillGraph: true,
animatedZoom: false,
// // legend => selected n (instead of %) thx highlightCallback
// highlightCallback: function(e, x, pts, row) {
// // n has i == 2 in counts_by_year_array tuples
// var this_n = hg.getValue(row, 2);
// var legendDiv = document.getElementsByClassName("dygraph-legend")[0]
// legendDiv.innerHTML = "<span style='font-weight: bold; background-color:#FFF; color:#070;'>n = " + this_n + "</span>";
// legendDiv.style.left = 0
// legendDiv.style.paddingLeft = "37%"
// legendDiv.style.paddingTop = "1%"
// legendDiv.style.display = "block"
// legendDiv.style.background = "none"
// }
});
}
function clean_histogram() {
$("#search_histogram").html("") ;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
body {
font-family: Helvetica Neue, Arial, Helvetica, sans-serif;
font-size: 90%;
}
*/
aside {
font-size: 90%;
}
#toc {
vertical-align: top;
width: 200px;
}
#gap {
style="width:0.5em;"
}
#rhs, #lhs {
vertical-align: top;
}
#subtitle a:visited {
color: blue;
}
#workarea {
border-style: solid;
border-color: #ddd;
padding: 4px;
}
#toc .entry {
background-color: #eee;
padding: .7em;
/* These two lines result in indenting wrapped lines forward a little bit. */
/* text-indent: -1em;
padding-left: 1em; */
}
#toc .entry:hover {
color: blue;
cursor: pointer;
}
#toc .entry .selected {
color: #090;
}
#code a:hover {
color: blue;
cursor: pointer;
}
#demotitle {
text-align: center;
font-size: 1.5em;
vertical-align: bottom;
}
.subdued:link,
.subdued:visited,
.subdued:active {
color: #000;
}
.subdued:hover {
color: blue;
}
/*
a {
text-decoration: none;
}
*/
/* CSS for drawing tool */
#workarea #drawing #tool_zoom {
background: url('images/tool-palette.png');
background-position: 0px 0px;
width: 32px;
height: 33px;
margin-left: 50px;
display: inline-block;
}
#workarea #drawing #tool_pencil {
background: url('images/tool-palette.png');
background-position: -32px 0px;
width: 32px;
height: 33px;
display: inline-block;
}
#workarea #drawing #tool_eraser {
background: url('images/tool-palette.png');
background-position: -64px 0px;
width: 33px;
height: 33px;
display: inline-block;
}
#workarea #drawing #toolbar {
display: inline-block;
}
/* CSS for independent series */
#workarea #independent-series .thinborder {
border-width: 1px;
border-spacing: 0px;
border-style: solid;
border-color: black;
border-collapse: collapse;
}
#workarea #independent-series .thinborder td,
#workarea #independent-series .thinborder th {
border-width: 1px;
padding: 5px;
border-style: solid;
border-color: black;
}
/* CSS for resize */
#workarea #resize #div_g {
/* The left and top are just guesses, this needs a proper run-through */
position: absolute;
left: 200px;
right: 10px;
top: 100px;
bottom: 10px;
}
/* CSS for styled-chart-label */
#workarea #styled-chart-labels .infotext {
}
#workarea #styled-chart-labels #div_g .dygraph-label {
/* This applies to the title, x-axis label and y-axis label */
font-family: Georgia, Verdana, serif;
/* can't set font-size because of inline values?? */
}
#workarea #styled-chart-labels #div_g .dygraph-title {
/* This rule only applies to the chart title */
font-size: 12px;
text-shadow: gray 1px 1px 1px; /* color, delta-x, delta-y, blur radius */
}
#workarea #styled-chart-labels #div_g .dygraph-ylabel {
/* This rule only applies to the y-axis label */
font-size: 6px;
text-shadow: gray -1px 1px 1px; /* (offsets are in a rotated frame) */
}
#workarea #styled-chart-labels .chart {
border: 1px dashed black;
margin: 2px 2px 2px 2px;
padding: 2px;
}
#workarea #temperature-sf-ny #bordered {
border: 1px solid red;
}
#workarea #highlighted-series .few .dygraph-legend > span.highlight { border: 1px solid grey; }
#workarea #highlighted-series .many .dygraph-legend > span { display: none; }
#workarea #highlighted-series .many .dygraph-legend > span.highlight { display: inline; }
#workarea #edge-padding fieldset { display: inline-block; vertical-align: top; }
.textarea {
position: absolute;
border: 1px solid black;
background-color: #dddddd;
z-index: 12;
}
.textarea .prompt {
padding-left: 2px;
}
.textarea .buttons {
position: absolute;
bottom: 5px;
right: 5px;
}
.textarea button {
color: #222222;
}
.textarea .editor {
font-family: Inconsolata, Courier New, Courier;
margin: 4px;
}
#modalBackground {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 11;
background-color:#333333;
display: none;
opacity: 0.40;
filter: alpha(opacity=40)
}
/* ------------- module dygraph charts pour histogramme WOS ----------------- */
/* graph div */
#search_histogram2 {
min-height: 12em ;
font-size: 75%;
background-color: #F9F9F9 ;
display: none;
position:relative;
padding: 0 15px;
max-width: 100%;
}
#search_histogram2 canvas {
margin-left: -2em;
}
// Histogram module
// =================
// Presents a histogram from WOS API
// Our module_name is simultaneously 3 things:
// - a DivsFlag for settings_explorerjs
// - our current dir for this module's files (and this init.js)
// - the class of module's html elements
module_name="histogramDailyVariantModule"
// ---- INIT main part -------- (listing all things to load)
// our histogram wrapper styles
loadCSS(module_name+"/histogram.css") ;
// our histogram controller
loadJS(module_name+"/dailyHistogram.js") ;
// dygraph library
// loadCSS(module_name+"/dygraph/gallery.css") ;
loadCSS(module_name+"/dygraph/textarea.css") ;
loadJS(module_name+"/dygraph/dygraph.combined.js") ;
console.log("OK LOADED " + module_name) ;
......@@ -43,8 +43,10 @@ var TW = {}
// flag name is div class to be removed if false
// *and* subdirectory to import if true
// see also ProcessDivsFlags()
TW.DivsFlags["histogramModule"] = true ;
TW.DivsFlags["crowdsourcingModule"] = true ; // £TODO fix topPapers
TW.DivsFlags["histogramModule"] = false ;
TW.DivsFlags["histogramDailyVariantModule"] = true ;
// TODO more generic module integrating the variants cf. experiments/histogramModule_STUB_GENERIQUE
TW.DivsFlags["crowdsourcingModule"] = true ;
TW.SystemStates = {}
TW.SystemStates.level = true;
......
......@@ -614,7 +614,7 @@ function getNodeIDs(elems){
function getSelections(){
params=[];
let params=[];
for(var i in selections){
params.push(TW.Nodes[i].label);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment