/** * QUERY SECTION * * */ // SPARQL Query text -- 'prefixes' and 'thisUrlParams' defined in people.js; let queryNetwork = prefixes + " SELECT COUNT(?event1) AS ?count1 COUNT(?event2) AS ?count2 ?uri2 SAMPLE(?label2) AS ?text \ WHERE { \ {?event1 rdf:type crm:EL1_Exchange_Letters . \ ?event_to rdfs:subClassOf ?event1; \ rdf:type crm:EL2_Send_Letter ; \ crm:P01_has_domain ?pc_to . \ ?pc_to crm:P02_has_range ?uri . \ ?uri rdfs:label ?label . \ ?event_from rdfs:subClassOf ?event1; \ rdf:type crm:EL3_Receive_Letter; \ crm:P01_has_domain ?pc_from . \ ?pc_from crm:P02_has_range ?uri2 . \ ?uri2 rdfs:label ?label2 . \ FILTER (?uri = <" + thisUrlParams.link + ">) \ } UNION { \ ?event2 rdf:type crm:EL1_Exchange_Letters . \ ?event_to rdfs:subClassOf ?event2; \ rdf:type crm:EL3_Receive_Letter ; \ crm:P01_has_domain ?pc_from . \ ?pc_from crm:P02_has_range ?uri . \ ?uri rdfs:label ?label . \ ?event_from rdfs:subClassOf ?event2; \ rdf:type crm:EL2_Send_Letter; \ crm:P01_has_domain ?pc_to . \ ?pc_to crm:P02_has_range ?uri2 . \ ?uri2 rdfs:label ?label2 . \ FILTER (?uri = <" + thisUrlParams.link + ">) \ } \ }" // 'prepareQueryURL' defined in people.js let queryNet = prepareQueryURL(queryNetwork); // do the query, call data processor on successful output $.ajax({ url: queryNet, dataType: "json", success: (data) => handle_word_network(data) }); /** * COMPONENT CREATION SECTION * * */ // Master function, takes data output from the query and creates the HTML for the Word Cloud component of the page function handle_word_network(json){ // Pre-process data let tempArray = processQuery(json); let words = prepareWords(tempArray); // Create page elements doListPersonNetwork(tempArray); doWordCloud(words); } // Return structured object from raw query data for further processing function processQuery(json) { const tempArray = []; $.each( json['results']['bindings'], (index, value) => { let text = value['text']['value']; let link = value['uri2']['value']; let sent = parseInt(value['count1']['value']); let received = parseInt(value['count2']['value']); let count = sent + received; tempArray.push({'text': text, 'sent': sent, 'received': received, 'count': count, 'hlink': link}); } ); tempArray.sort((a, b) => b.count - a.count); return tempArray; } // Define font size, according to the number of words and limiting the impact of huge counts -- to refactor?? function prepareWords(tempArray){ const words = []; if (tempArray.length < 8) { // Less than 8 results -- font size is just = count/2 + constant for (let k=tempArray.length-1; k>=0; k--) { let text = tempArray[k]['text']; let preSize = tempArray[k]['count'] + 36; console.log('mann', preSize) let link = tempArray[k]['hlink']; words.push( { 'text': text, 'size': preSize/2 + 6, 'hlink': link } ); } } else { // More than 8 results -- font size = count except for especially "big" words let temp = 0; for (let k=tempArray.length-1; k>=0; k--) { let text = tempArray[k]['text']; let count = tempArray[k]['count']; let link = tempArray[k]['hlink']; let preSize = 0; if ((count - temp) > 50) { preSize = temp + 12; } else { preSize = count; } words.push( { 'text': text, 'size': preSize/2 + 6, 'hlink': link } ); temp = preSize; } } console.log('tempArray', tempArray) console.log('words', words) return words; } // Create formatted list of people in the network function doListPersonNetwork(tempArray){ let ArrayNames = ""; tempArray.forEach(element => { ArrayNames += "
\
" + element['text'] + "
[Lettere inviate: " + element['sent'] + "]\
[Lettere ricevute: " + element['received'] + "]\
[Totale corrispondenza: " + element['count'] + "]\
\
\
\ \
\
\
"; }); document.getElementById("list_person_network").innerHTML = ArrayNames; } // Create the word cloud function doWordCloud(myWords){ // Clear word cloud div $('#myWordCloud').empty(); // OVERALL GRAPHIC SETTINGS for the cloud container -- id, dimensions, position // set the dimensions and margins of the graph let modifierWidth = 0.4; let modifierHeigth = 0.4; let marginHeight = 0; let marginWidth = 0;; let margin = { top: marginHeight, right: marginWidth, bottom: marginHeight, left: marginWidth}; let width = modifierWidth*window.innerWidth; let height = modifierHeigth*window.innerHeight; // append the svg object to the body of the page let svg = d3.select("#myWordCloud") .append("svg") .attr("id", "wordcloudNetwork") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .attr("style", "border:1px solid black") .append("g") .attr("transform", "translate(" + (width*0.5) + "," + (height*0.5) + ")") .attr("overflow","scroll"); // In case of empty cloud, draw special page and exit if (myWords.length == 0){ drawEmptyWordCloud(); return; } // THE ACTUAL CLOUD // Constructs a new cloud layout instance. It runs an algorithm to find the position of words that suits your requirements // Wordcloud features that are different from one word to the other must be here let layout = d3.layout.cloud() // Constructs the cloud .size([1.5*width, 1.2*height]) // Sets width and height .words(myWords) // put words in; expects an array of objects. Format is free, it all depends on the definition of the functions that are applied to define the cloud structure. // // A js curiosity: ~ is a bitwise not operator. On a number, the double bitwise not ~~ has the net effect of giving the integer part, that is: floor on positives and ceiling on negatives. .rotate( () => { return ~~(Math.random() * 2);} ) .fontSize( word => { return word['size']; } ) // font size of words .on("end", word => draw(word, svg)); layout.start(); } // Helper function for the Word Cloud -- // it draws the words // Wordcloud features that are THE SAME from one word to the other can be here ?? function draw(words, svg) { let cloud = svg.selectAll("g text") .data(words, word => word.text) // What does this do? //Entering words cloud.enter() .append("text") .style("font-family", "Impact") .attr("text-anchor", "middle") .attr('font-size', 1) .append("a") .attr("href", word => word.hlink) .attr("data-toggle", "tooltip") .text( word => { return word.text; }); //Entering and exiting words cloud.transition() .duration(600) .style("font-size", function(d) { return d.size + "px"; }) .attr("transform", function(d) { return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")"; }) .style("fill-opacity", 1); //Exiting words cloud.exit() .transition() .duration(200) .style('fill-opacity', 1e-6) .attr('font-size', 1) .remove(); } // Helper function -- draw special empty word cloud if there are no occurrences function drawEmptyWordCloud(){ let wordIcon = "
\ \ \ \

Nessuna persona trovata

\
"; $("#wordcloudNetwork").css("display", "none"); $("#references_network").css("display", "none"); document.getElementById("myWordCloud").innerHTML = wordIcon; } // Customized word cloud code // Takes a list of words, returns the innerHTML for a Word Cloud as a string containing multiple svg elements function createWordCloud(words){ const rectObjs = [] let allBooms = 0 let attempts = 0; for(let ind=0;ind rectTexts.push(rect.printCoords())); let rects = rectTexts.join('\n'); return rects; } function getFontSize(weight){ return Math.max(80-weight, 30); }