123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- /**
- * 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 +=
- "<div class='item-place-person'>\
- <div class='item-place-person-label'>" +
- element['text'] +
- "<br /><span class='num_occ'>[Lettere inviate: " + element['sent'] + "]</span>\
- <br /><span class='num_occ'>[Lettere ricevute: " + element['received'] + "]</span>\
- <br /><span class='num_occ'>[Totale corrispondenza: " + element['count'] + "]</span>\
- </div>\
- <div class='item-place-person-action'>\
- <div class='persona' id='" + element['hlink'] +"'>\
- <i class='fa fa-user' style='cursor:pointer'></i>\
- </div>\
- </div>\
- </div>";
- });
- 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 = "<div id='users_icon' class='no_info_icon'> \
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 512'> \
- <!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d='M319.9 320c57.41 0 103.1-46.56 103.1-104c0-57.44-46.54-104-103.1-104c-57.41 0-103.1 46.56-103.1 104C215.9 273.4 262.5 320 319.9 320zM369.9 352H270.1C191.6 352 128 411.7 128 485.3C128 500.1 140.7 512 156.4 512h327.2C499.3 512 512 500.1 512 485.3C512 411.7 448.4 352 369.9 352zM512 160c44.18 0 80-35.82 80-80S556.2 0 512 0c-44.18 0-80 35.82-80 80S467.8 160 512 160zM183.9 216c0-5.449 .9824-10.63 1.609-15.91C174.6 194.1 162.6 192 149.9 192H88.08C39.44 192 0 233.8 0 285.3C0 295.6 7.887 304 17.62 304h199.5C196.7 280.2 183.9 249.7 183.9 216zM128 160c44.18 0 80-35.82 80-80S172.2 0 128 0C83.82 0 48 35.82 48 80S83.82 160 128 160zM551.9 192h-61.84c-12.8 0-24.88 3.037-35.86 8.24C454.8 205.5 455.8 210.6 455.8 216c0 33.71-12.78 64.21-33.16 88h199.7C632.1 304 640 295.6 640 285.3C640 233.8 600.6 192 551.9 192z'/> \
- </svg> \
- <p>Nessuna persona trovata</p> \
- </div>";
- $("#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 <g> svg elements
- function createWordCloud(words){
- const rectObjs = []
- let allBooms = 0
- let attempts = 0;
- for(let ind=0;ind<words.length;ind++){
- let id0 = "word"+ind;
- let praaaa = document.getElementById(id0).getBoundingClientRect();
- //console.log('BB of '+id0, praaaa);
- attempts++;
- let boom = false;
- // rectangle definition
- // let width = 120 + Math.round(50*Math.random());
- // let height = 40;
- let fontSize = getFontSize(ind);
- let width = praaaa.width;
- //let height = fontSize;
- let height = praaaa.height;
- let xR = 1250 + Math.round( (Math.random()-0.5)*(1000 + 6*ind) );
- let yR = 750 + Math.round( (Math.random()-0.5)*(400 + 4*ind) );
- let angle = 90*(Math.floor(3*Math.random())-1);
- let text = words[ind];
- //console.log('Rect:', width, height, xR, yR, angle, text);
- let newRect = new Rect(width, height, xR, yR, angle, text, fontSize);
- //console.log('nnn', newRect);
- for(let rect of rectObjs){
- boom = checkColl(newRect, rect);
- if(boom) break;
- }
- if(boom){
- allBooms++;
- if(allBooms<10) ind--;
- else(allBooms = 0);
- continue;
- }
- allBooms = 0;
- rectObjs.push(newRect);
- }
- console.log('Attempted:', attempts);
- console.log('Placed:', rectObjs.length);
- const rectTexts = [];
- rectObjs.forEach(rect => rectTexts.push(rect.printCoords()));
- let rects = rectTexts.join('\n');
- return rects;
- }
- function getFontSize(weight){
- return Math.max(80-weight, 30);
- }
|