Widget:PlaceNamesCharts: Difference between revisions
From International Robin Hood Bibliography
mNo edit summary |
mNo edit summary |
||
(31 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
<noinclude><div class="no-img">This widget generates | <noinclude><div class="no-img">This widget generates charts on landing pages. It takes no parameters.</div></noinclude><includeonly><script> | ||
<script | //Timeline widget | ||
(function() { | (function() { | ||
window.IRHB = window.IRHB || {}; | window.IRHB = window.IRHB || {}; | ||
window.IRHB. | window.IRHB.timeline = {}; | ||
window.IRHB. | var t = window.IRHB.timeline; | ||
window.IRHB. | |||
window.IRHB.get = window.IRHB.get || function get (elem) { | |||
if (typeof elem === "string") { | |||
elem = document.getElementById(elem); | |||
} | |||
window.IRHB. | return elem; | ||
}; | |||
var get = window.IRHB.get; | |||
function | t.create = function(elem, callback) { | ||
var | var values = elem.firstElementChild.innerHTML.trim(); | ||
var | values = values.substr(0, values.length - 1);// Remove final comma | ||
for (var i = 0; i < | values = values.replace('"', "").replace('"', ""); | ||
var valuesAr = values.split("|"); | |||
var nVals = valuesAr.length; | |||
var pages = {}; | |||
if (nVals != 0) { | |||
for (var i = 0; i < nVals; i++) { | |||
var ar = valuesAr[i].split("¤"); | |||
) | var year = ar[1]; | ||
if (year != "") { | |||
var decade = getDecade(year); | |||
if (!pages.hasOwnProperty(decade)) { | |||
pages[decade] = []; | |||
} | |||
pages[decade].push( | |||
{ | |||
"year": year, | |||
"page": ar[0] | |||
} | |||
) | |||
} | } | ||
} | } | ||
var pText = "<div class='chrtHead'>Timeline</div>"; | |||
var curCentury = 0, cText = "", cTotal; | |||
for (var prop in pages) { | |||
if (pages.hasOwnProperty(prop)) { | |||
var century = getCentury(prop); | |||
if (century !== curCentury) { | |||
if (curCentury !== 0) { | |||
var cntStr = curCentury + (curCentury !== "21" ? "th" : "st") + " Cent."; | |||
var cHead = "<div class='tLnCnt' id='c" + curCentury + "'><div>" + cntStr + " (" + cTotal + ")</div>"; | |||
pText += cHead + "<div>" + cText + "</div></div>"; | |||
} | |||
cTotal = 0; | |||
curCentury = century; | |||
cText = ""; | |||
} | |||
var nPages = pages[prop].length; | |||
cTotal += nPages; | |||
var decStr = prop + "–" + String((parseInt(prop) + 9)).substring(2) + " (" + nPages + ")"; | |||
cText += "<div class='tLnDec' id='i" + prop + "'><div>" + decStr + "</div><ul>"; | |||
for (var i = 0; i < nPages; i++) { | |||
cText += "<li class='tLnItem'><span>" + pages[prop][i].year + " – " + pages[prop][i].page + "</span><div></div></li>"; | |||
} | |||
cText += "</ul></div>" | |||
} | |||
} | |||
var cntStr = curCentury + (curCentury !== "21" ? "th" : "st") + " Cent."; | |||
var cHead = "<div class='tLnCnt' id='c" + curCentury + "'><div>" + cntStr + " (" + cTotal + ")</div>"; | |||
pText += cHead + "<div>" + cText + "</div></div>"; | |||
elem.innerHTML = pText; | |||
var centuries = get("tline").getElementsByClassName("tLnCnt"); | |||
var nCnts = centuries.length; | |||
for (var i = 0; i < nCnts; i++) { | |||
initDiv(centuries[i]); | |||
} | |||
var decades = get("tline").getElementsByClassName("tLnDec"); | |||
var nDecs = decades.length; | |||
for (var i = 0; i < nDecs; i++) { | |||
initDiv(decades[i]); | |||
} | |||
var items = get("tline").getElementsByClassName("tLnItem"); | |||
var nItems = items.length; | |||
for (var i = 0; i < nItems; i++) { | |||
items[i].onclick = callback; | |||
} | } | ||
elem.style.display = "block"; | |||
} | } | ||
} | } | ||
t.getDecade = function(year) { | |||
var decade = year % 10 !== 0 ? year : year - 1; | |||
decade = (Math.floor(decade / 10) * 10) + 1; | |||
return decade; | |||
}; | }; | ||
var getDecade = t.getDecade; | |||
t.getCentury = function(decade) { | |||
var | var century = parseInt(decade / 100) + 1; | ||
return century; | |||
}; | |||
var getCentury = t.getCentury; | |||
var | var divClickHandler = function () { | ||
var | var delay = 25; | ||
if ( | var p = this.nextElementSibling.firstElementChild; | ||
if (p) { | |||
var disp = window.getComputedStyle(p, null).getPropertyValue("display"); | |||
disp = disp == "block" ? "none" : "block"; | |||
if (disp == "none") { | |||
p = this.nextElementSibling.lastElementChild; | |||
} | |||
while (true) { | |||
setTimeout(toggleRow, delay, p, disp); | |||
p = disp == "block" ? p.nextElementSibling : p.previousElementSibling; | |||
if (!p) { | |||
if ( | |||
break; | break; | ||
} else { | |||
delay += 25; | |||
} | } | ||
} | } | ||
} | } | ||
}; | |||
function initDiv(eDiv) { | |||
var heading = eDiv.firstElementChild; | |||
heading.addEventListener("click", divClickHandler); | |||
} | } | ||
var toggleRow = function(s, state) { | |||
s.style.display = state; | |||
}; | |||
})(); | |||
//Charts | |||
(function() { | |||
var t = window.IRHB.timeline; | |||
var get = window.IRHB.get; | |||
var chartOptions = { | |||
"scales": { | |||
"xAxes": [ | |||
{ | |||
"barPercentage": 1.0, | |||
"barThickness": "flex", | |||
"gridLines": { | |||
"offsetGridLines": true, | |||
"drawBorder": false, | |||
"display": false | |||
}, | |||
"ticks": { | |||
"autoSkip": false, | |||
"maxRotation": 90, | |||
"minRotation": 90 | |||
} | } | ||
} | } | ||
], | |||
"yAxes": [ | |||
{ | |||
"gridLines": { | |||
"drawBorder": false | |||
} | } | ||
} | } | ||
] | |||
}, | |||
"legend": { | |||
"display":false | |||
}, | |||
"title": { | |||
"display": true, | |||
"fontSize": 28, | |||
"fontFamily": "'Open Sans Condensed', Helvetica, Arial, sans-serif", | |||
"fontColor": '#964d4d', | |||
"fontStyle": "bold", | |||
"padding": 20 | |||
}, | |||
"tooltips": { | |||
"backgroundColor": "#ffffff", | |||
"titleFontColor": "#000000", | |||
"bodyFontColor": "#000000", | |||
"borderColor": "#bdbdbd", | |||
"borderWidth": 1, | |||
"titleFontStyle": "normal" | |||
}, | |||
"responsive": true, | |||
"maintainAspectRatio": false | |||
}; | |||
function replaceAll (str, find, replacement) { | |||
return str.replace(new RegExp(escapeRegEx(find), 'g'), replacement); | |||
}; | |||
function escapeRegEx (str) { | |||
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); | |||
}; | |||
function prepareCharts() { | |||
var tc = get("tChart"); | |||
var cType = "bar"; | |||
if (tc) { | |||
makeChart( | |||
tc, "typeCvs", cType, "Type", | |||
{"Public house": 0, "Monument": 0, "Building": 0, "Church": 0, | |||
"Prehistoric site": 0, "Natural feature": 0, "Settlement": 0, "Area": 0, | |||
"Thoroughfare": 0, "Transport": 0, "Establishment": 0, "Association": 0, | |||
"Artifact": 0, "Miscellaneous": 0 | |||
} | } | ||
); | |||
} | |||
tc = get("cChart"); | |||
if (tc) { | |||
makeChart( | |||
tc, "cCvs", cType, "Century", | |||
{ | |||
"14th": 0, "15th": 0, "16th": 0, "17th": 0, "18th": 0, "19th": 0, | |||
"20th": 0, "21st": 0, "Unknown": 0 | |||
} | } | ||
); | |||
} | |||
tc = get("iChart"); | |||
if (tc) { | |||
makeChart( | |||
tc, "iCvs", cType, "Interest", | |||
{ | |||
"Robin Hood name": 0, "Local tradition": 0, "Literary locale": 0, | |||
"Artifacts": 0, "Miscellaneous": 0 | |||
} | } | ||
); | |||
} | |||
tc = get("sChart"); | |||
if (tc) { | |||
makeChart(tc, "sCvs", "doughnut", "Status", {"Extant": 0, "Defunct": 0}); | |||
} | |||
tc = get("tline"); | |||
if (tc) { | |||
//Non-empty query result in paragraph, if no paragraph, no timeline: | |||
if (tc.firstElementChild) { | |||
window.IRHB.timeline.create(tc, prepareItemCard); | |||
} else { | |||
get("sChart").style.paddingBottom = "6em"; | |||
} | |||
} | |||
} | |||
function makeChart(elem, cvsId, cType, lbl, cats) { | |||
var values = elem.firstElementChild.innerHTML.trim(); | |||
values = values.substr(0, values.length - 1);// Remove final comma | |||
values = replaceAll(values, '""', "Unknown"); | |||
values = replaceAll(values, '"', ""); | |||
var valuesAr = values.split(","); | |||
var nVals = valuesAr.length; | |||
if (nVals != 0) { | |||
var lbls = Object.getOwnPropertyNames(cats); | |||
var nLbls = lbls.length; | |||
elem.innerHTML = "<canvas id='" + cvsId + "'></canvas>"; | |||
var maxBar = 0; | |||
for (var i = 0; i < nVals; i++) { | |||
var v = valuesAr[i]; | |||
cats[v]++; | |||
v = cats[v]; | |||
if (v > maxBar) { | |||
maxBar = v; | |||
} | } | ||
} | } | ||
var cData = [], cColrs = []; | |||
var | for (var i = 0; i < nLbls; i++) { | ||
var | cData.push(cats[lbls[i]]); | ||
var | cColrs.push("#4d8375"); | ||
if ( | } | ||
if (lbl === "Status") { | |||
cColrs[1] = "#82a89e"; | |||
} | |||
var chrt = new Chart( get(cvsId), { | |||
type: cType, | |||
data: { | |||
labels: lbls, | |||
datasets: [{label: lbl, backgroundColor: cColrs, data: cData}] | |||
}, | |||
options: chartOptions | |||
}); | |||
if (lbl === "Status") { | |||
chrt.options.scales.xAxes = [ | |||
{"gridLines": {"drawBorder": false, "display": false}, | |||
"ticks": { "display": false} | |||
} | |||
]; | |||
chrt.options.scales.yAxes = [ | |||
{"gridLines": {"drawBorder": false, "display": false}, | |||
"ticks": { "display": false} | |||
} | |||
]; | |||
chrt.options.legend.display = true; | |||
} else { | } else { | ||
chrt.options.tooltips.callbacks = { | |||
"label": function(tooltipItem, data) { | |||
var label = data.datasets[tooltipItem.datasetIndex].label || ''; | |||
if (label) { | |||
label = "Count: "; | |||
} | |||
label += tooltipItem.yLabel; | |||
return label; | |||
} | } | ||
} | } | ||
} | } | ||
if ( | var step; | ||
if (maxBar < 6) { | |||
step = 1; | |||
} else if (maxBar < 11) { | |||
step = 2; | |||
} else if (maxBar < 26) { | |||
step = 5; | |||
} else if (maxBar < 101) { | |||
step = 10; | |||
} else if (maxBar < 501) { | |||
step = 25; | |||
} else { | |||
step = 50; | |||
} | } | ||
chrt.options.scales.yAxes[0].ticks.stepSize = step; | |||
chrt.options.title.text = lbl; | |||
elem.style.display = "block"; | |||
} | } | ||
} | } | ||
var | function prepareItemCard(event) { | ||
var t = event.target; | |||
if (t.tagName != "A") { | |||
var | var tc = event.currentTarget; | ||
var | var item = tc.firstChild.innerHTML; | ||
var card = tc.firstChild.nextSibling; | |||
if (card.innerHTML == "") { | |||
if ( | var start = item.indexOf(" – ") + " – ".length; | ||
var | item = encodeURIComponent(item.substring(start)); | ||
var qry = "https://www.irhb.org/wiki/api.php?action=ask&query=[[" + item + "]]|?Geopoint|?Pnadmdiv|?Pnfirstrecord|?Pnimage|?Pninterest|?Pnstatus|?Pntype|?Pnvicinity|?Century|?Pnaka&format=json"; | |||
query(qry, "POST", makeItemCard); | |||
} else { | |||
card.innerHTML = ""; | |||
card.style.display = "none"; | |||
} | } | ||
} else { | |||
event.stopPropagation(); | |||
} | } | ||
} | |||
var | |||
function makeItemCard(resp) { | |||
var res = JSON.parse(resp); | |||
res = res.query.results; | |||
res = res[Object.keys(res)[0]];//First property in "res.query.results" | |||
var page = res.fulltext; | |||
var firstRec = res.printouts.Pnfirstrecord; | |||
var dec = t.getDecade(firstRec); | |||
var itemName = firstRec + " – " + page; | |||
var decadeDiv = get("i" + dec); | |||
var lst = decadeDiv.firstChild.nextSibling; | |||
var lstItems = lst.children; | |||
var nItems = lstItems.length; | |||
for (var i = 0; i < nItems; i++) { | |||
if (lstItems[i].firstChild.innerHTML == itemName) { | |||
var card = lstItems[i].firstChild.nextSibling; | |||
var imgId = "img" + dec + "_" + i; | |||
card.innerHTML = "<img class='cardImg' id='" + imgId + "'></img>"; | |||
var txt = "<div class='cardText'><table>"; | |||
var safePage = page.replace("'", "%27"); | |||
txt += "<tr><td>Page</td><td><a href='https://www.irhb.org/wiki/index.php/" + safePage + "'>" + page + "</a></td></tr>"; | |||
var lt = res.printouts.Geopoint[0] ? res.printouts.Geopoint[0].lat : "?"; | |||
var ln = res.printouts.Geopoint[0] ? res.printouts.Geopoint[0].lon : "?"; | |||
txt += "<tr><td>Lat.</td><td>" + lt + "</td></tr>"; | |||
txt += "<tr><td>Lon.</td><td>" + ln + "</td></tr>"; | |||
txt += "<tr><td>Adm. div.</td><td>" + res.printouts.Pnadmdiv[0] + "</td></tr>"; | |||
var vic = res.printouts.Pnvicinity[0]; | |||
vic = vic.replace("''", "<i>").replace("''", "</i>"); | |||
txt += "<tr><td>Vicinity</td><td>" + vic + "</td></tr>"; | |||
txt += "<tr><td>Type</td><td>" + res.printouts.Pntype[0] + "</td></tr>"; | |||
txt += "<tr><td>Interest</td><td>" + res.printouts.Pninterest[0] + "</td></tr>"; | |||
txt += "<tr><td>Status</td><td>" + res.printouts.Pnstatus[0] + "</td></tr>"; | |||
txt += "<tr><td>First rec.</td><td>" + res.printouts.Pnfirstrecord[0] + "</td></tr>"; | |||
var century = res.printouts.Century[0]; | |||
if (century) { | |||
txt += "<tr><td>Century</td><td>" + res.printouts.Century[0] + "</td></tr>"; | |||
} | |||
var aka = res.printouts.Pnaka; | |||
var akaTxt = ""; | |||
var nAka = aka.length; | |||
for (var i = 0; i < nAka; i++) { | |||
akaTxt += "; " + aka[i]; | |||
} | |||
akaTxt = akaTxt.replace("; ", ""); | |||
if (akaTxt !== "") { | |||
txt += "<tr><td>A.k.a.</td><td>" + akaTxt + "</td></tr></table>"; | |||
} | |||
card.innerHTML += txt; | |||
var imgName = res.printouts.Pnimage; | |||
var img = get(imgId); | |||
if (imgName != "") { | |||
var tempImg = new Image(); | |||
tempImg.onload = function() { | |||
img.src = this.src | |||
card.style.display = "block"; | |||
}; | |||
tempImg.src = "https://www.irhb.org/wiki/thumb.php?f=" + encodeURIComponent(res.printouts.Pnimage) + "&w=195"; | |||
img.style.display = "block"; | |||
} else { | |||
img.style.display = "none"; | |||
card.style.display = "block"; | |||
} | |||
break; | |||
} | } | ||
} | } | ||
} | |||
var | |||
function query(qry, method, callBack) { | |||
var xmlhttp = new XMLHttpRequest(); | |||
xmlhttp.onreadystatechange = function() { | |||
if (xmlhttp.readyState == XMLHttpRequest.DONE ) { | |||
if (xmlhttp.status == 200) { | |||
callBack(xmlhttp.responseText); | |||
} else if (xmlhttp.status == 400) { | |||
say("An error occurred; closing down!"); | |||
} | |||
else { | |||
callBack(xmlhttp.responseText); | |||
} | |||
} | |||
}; | |||
xmlhttp.open(method, qry, true); | |||
xmlhttp.send(); | |||
} | } | ||
var script = document.createElement('script'); | |||
script.type = 'text/javascript'; | |||
script.src = "https://www.irhb.org/wiki/js/Chart.js"; | |||
script.onreadystatechange = prepareCharts; | |||
script.onload = prepareCharts; | |||
document.head.appendChild(script); | |||
})(); | })(); | ||
</script> | </script></includeonly> | ||
</includeonly> |
Revision as of 10:40, 6 June 2019
This widget generates charts on landing pages. It takes no parameters.