/**
* QUERY SECTION
*
* */
// SPARQL Query text -- 'prefixes' and 'thisUrlParams' defined in people.js;
let queryNetwork = prefixes + (queryManager['querySchedaPersona']['queryNetwork']).replaceAll('{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)
});
// queryLetters defined in people.js
/**
* 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 words = processQuery(json);
// Create page elements
doListPersonNetwork(words);
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 other = parseInt(value['count3']['value']);
let count = sent + received;
tempArray.push({'text': text, 'sent': sent, 'received': received, 'other': other, 'count': count, 'hlink': link});
}
);
tempArray.sort((a, b) => b.count - a.count);
return tempArray;
}
// Create formatted list of people in the network
function doListPersonNetwork(words){
let ArrayNames = "";
words.forEach(element => {
filteredText = element['text'].replace('"', '').replace("'", '');
ArrayNames +=
"
";
});
document.getElementById("list_person_network").innerHTML = ArrayNames;
addEventsToNameList(words);
}
function addEventsToNameList(words){
let counter = 0
for(let word of words){
if(counter>0) break;
let listElem = document.getElementById('tot-' + word.text.replace('"', '').replace("'", ''));
if(listElem!=null){
listElem.addEventListener("click", filterLetters);
listElem.addEventListener("mouseover", highlightWord);
listElem.addEventListener("mouseout", unHighlightWord);
}
counter++;
}
}
function filterLetters(e){
try{
let preText = e.target.parentNode.textContent;
console.log('text content', preText);
let name = preText.split("[")[0];
console.log('name', name);
// responseLet defined in people.js
responseLet.then(data => {
let lettersJson = data.results.bindings;
console.log('AH!', lettersJson[0]);
});
} catch{
console.log("Couldn't get the name");
}
}
// Create the word cloud
function doWordCloud(words){
// Clear word cloud div
$('#myWordCloud').empty();
// OVERALL GRAPHIC SETTINGS for the cloud container -- id, dimensions, position
let width = 0.5*window.outerWidth;
let height = 0.6*width;
// append the svg object to the body of the page
let svg = d3.select("#myWordCloud")
.append("svg")
.attr("id", "wordcloudNetwork")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 " + width + " " + height)
.classed("svg-content", true)
.attr("width", width)
.attr("height", height)
.attr("style", "border:1px solid black")
// In case of empty cloud, draw special page and exit
if (words.length == 0){
drawEmptyWordCloud();
return;
}
// THE ACTUAL CLOUD
svg = document.getElementById('wordcloudNetwork');
console.log(svg);
let zoom = window.devicePixelRatio;
console.log('zoom', zoom);
wcParameters = {
svgWidth: svg.getBoundingClientRect().width,
svgHeight: svg.getBoundingClientRect().height,
maxFontSize: 30/((1+zoom)/2),
minFontSize: 10/((1+zoom)/2)
}
let svgWords = hackWords(words, wcParameters);
svg.innerHTML = svgWords;
let wordCloudText = createWordCloud(words, wcParameters);
svg.innerHTML = wordCloudText;
addEventsToWordCloud(words);
}
// Helper function -- draw special empty word cloud if there are no occurrences
function drawEmptyWordCloud(){
let wordIcon = "
\
\
Nessuna persona trovata
\
";
$("#person_map").css("display", "none");
$("#wordcloudNetwork").css("display", "none");
$("#references_network").css("display", "none");
document.getElementById("person_map_no_res").innerHTML = wordIcon;
}
/*****************************
* Customized word cloud code *
*****************************/
function hackWords(words, parameters){
let weights = words.map(word => word.count);
let minWeight = Math.min(...weights);
let maxFontSize = parameters.maxFontSize;
let minFontSize = parameters.minFontSize;
console.log('weights', weights);
console.log('maxFontSize', maxFontSize);
console.log('minFontSize',minFontSize);
let stringOfWords = "";
for(let ind=0; ind'+words[ind].text+'\n';
}
return stringOfWords;
}
// Takes a list of words, returns the innerHTML for a Word Cloud as a string containing multiple svg elements
function createWordCloud(words, parameters){
let actualUsefulWidth = parameters.svgWidth;
let actualUsefulHeight = parameters.svgHeight;
console.log('Actual SVG dimensions', actualUsefulWidth, actualUsefulHeight);
maxFontSize = parameters.maxFontSize;
minFontSize = parameters.minFontSize;
const rectObjs = []
let allBooms = 0
let attempts = 0;
let outOfBorder = 0;
for(let ind=0;ind=20*(ind+1)) break;
attempts++;
let boom = false;
// word + bounding box parameters definition
let word = words[ind];
let id0 = "word"+ind;
let wordBB = document.getElementById(id0).getBoundingClientRect();
let fontSize = word.fontSize;
let width = wordBB.width;
let height = wordBB.height;
let multiplier = 0.1 + 0.4*Math.max((maxFontSize-fontSize)/(maxFontSize-minFontSize), allBooms/(20*(ind+1)));
let xR = Math.floor(actualUsefulWidth/2-width/2 + randomRange(-multiplier*actualUsefulWidth, multiplier*actualUsefulWidth));
let yR = Math.floor(actualUsefulHeight/2 + randomRange(-multiplier*actualUsefulHeight, multiplier*actualUsefulHeight));
//console.log('x', 'y', xR, yR)
let angle;
if(word.received/word.sent>3) angle = -3;
else if(word.received/word.sent<0.3) angle = 3;
let text = word.text;
//console.log('Rect:', width, height, xR, yR, angle, text);
//
let newRect = new Rect(width, height, xR, yR, angle, text, fontSize);
boom = checkBorder(newRect, 0, actualUsefulWidth, 0, actualUsefulHeight)
if(boom){
outOfBorder++;
if(outOfBorder<30){
ind--;
continue;
} else{
boom = false;
}
}
for(let rect of rectObjs){
boom = checkColl(newRect, rect);
if(boom) break;
}
if(boom){
allBooms++;
ind--;
continue;
}
allBooms = 0;
rectObjs.push(newRect);
}
console.log('Attempted:', attempts);
console.log('Placed:', rectObjs.length);
console.log('booms!', allBooms);
const rectTexts = [];
rectObjs.forEach(rect => rectTexts.push(rect.printCoords(false, maxFontSize, minFontSize)));
let rects = rectTexts.join('\n');
return rects;
}
function getFontSize(weight, minWeight, maxFontSize, minFontSize){
let r1 = weight/10*minWeight - 1/10; // between 0 and a big num
let res = minFontSize + (maxFontSize-minFontSize)*r1/Math.sqrt(1+r1**2);
return res;
}
function randomRange(a, b=0){
return (a-b)*Math.random()+b;
}
function randomInt(a){
return Math.floor(a*Math.random());
}
function randomRangeInt(a, b=0){
let ap = Math.floor(a);
let bp = Math.floor(b);
return Math.floor((ap-bp)*Math.random())+bp;
}
// Check border collision
function checkBorder(rect, minX, maxX, minY, maxY){
if(rect.minXmaxX) return true;
if(rect.minYmaxY) return true;
return false;
}
function addEventsToWordCloud(words){
for(let word of words){
let wcElem = document.getElementById('word-' + word.text.replace('"', '').replace("'", ''));
if(wcElem!=null){
wcElem.addEventListener("click", focusPersonInList);
wcElem.addEventListener("mouseover", highlightWord);
wcElem.addEventListener("mouseout", unHighlightWord);
}
}
}
function focusPersonInList(e){
let targetId = e.target.id;
console.log(targetId);
let listElem = document.getElementById(targetId.replace('word-', 'list-'));
listElem.scrollIntoView({behavior: "smooth", block: "center"});
}
function highlightWord(e){
e.target.style['text-decoration'] = "underline";
}
function unHighlightWord(e){
e.target.style['text-decoration'] = "";
}