First feature complete rebuilt of analysis interface

This commit is contained in:
Stephan Porada 2020-04-06 12:32:29 +02:00
parent 38e1408e01
commit 12586bb13d
3 changed files with 104 additions and 49 deletions

View File

@ -96,7 +96,7 @@ def pj_corpus_analysis_query(query):
@socketio.on('pj_corpus_analysis_inspect_match') @socketio.on('pj_corpus_analysis_inspect_match')
@socketio_login_required @socketio_login_required
def pj_corpus_analysis_inspect_match(payload): def pj_corpus_analysis_inspect_match(payload):
logger.warning(payload) payload = payload["payload"]
client = pj_corpus_analysis_clients.get(request.sid) client = pj_corpus_analysis_clients.get(request.sid)
if client is None: if client is None:
socketio.emit('query', '[424]: Failed Dependency', socketio.emit('query', '[424]: Failed Dependency',
@ -106,8 +106,9 @@ def pj_corpus_analysis_inspect_match(payload):
corpus = client.corpora.get('CORPUS') corpus = client.corpora.get('CORPUS')
s = corpus.attributes.structural.get('s') s = corpus.attributes.structural.get('s')
match_context = s.export(payload['first_cpos'], payload['last_cpos'], match_context = s.export(payload['first_cpos'], payload['last_cpos'],
context=3, expand_lists=True) context=3, expand_lists=False)
socketio.emit('pj_corpus_analysis_inspect_match', match_context['cpos_ranges'] = True
socketio.emit('pj_match_context',
{'payload': match_context}, room=request.sid) {'payload': match_context}, room=request.sid)

View File

@ -86,58 +86,80 @@ function inspect(dataIndex) {
// This function should be in the AnalysisClient class as a method. // This function should be in the AnalysisClient class as a method.
console.log("Inspect!"); console.log("Inspect!");
console.log(results.resultsJSON.matches[dataIndex].c); console.log(results.resultsJSON.matches[dataIndex].c);
contextResultsElement = document.getElementById("context-results");
contextResultsElement.innerHTML = ""; // clear it from old inspects
contextModal.open(); contextModal.open();
nopaque.socket.emit("pj_corpus_analysis_inspect_match", nopaque.socket.emit("pj_corpus_analysis_inspect_match",
{payload: {first_cpos: results.resultsJSON.matches[dataIndex].c[0], {payload: {
last_cpos: results.resultsJSON.matches[dataIndex].c[1]}}); first_cpos: results.resultsJSON.matches[dataIndex].c[0],
last_cpos: results.resultsJSON.matches[dataIndex].c[1]
}
});
} }
function showMatchContext(payload) { function showMatchContext(response) {
let contextData = response.payload
let contextResultsElement; let contextResultsElement;
let sentenceElement let contextModalLoading;
let contextModalReady;
let expertModeSwitchElement
let partElement
let token; let token;
let tokenElement; let tokenElement;
console.log("###### match_context ######"); console.log("###### match_context ######");
console.log("Incoming data:", payload); console.log("Incoming data:", contextData);
expertModeSwitchElement = document.getElementById("display-options-form-expert_mode");
contextResultsElement = document.getElementById("context-results"); contextResultsElement = document.getElementById("context-results");
contextResultsElement.innerHTML = "<p>&nbsp;</p>"; contextModalLoading = document.getElementById("context-modal-loading");
document.getElementById("context-modal-loading").classList.add("hide"); contextModalLoading.classList.add("hide");
document.getElementById("context-modal-ready").classList.remove("hide"); contextModalReady = document.getElementById("context-modal-ready");
contextModalReady.classList.remove("hide");
for (let [key, value] of Object.entries(payload['context_s_cpos'])) { if (contextData.cpos_ranges == true) {
sentenceElement = document.createElement("p"); // python range like function from MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Sequence_generator_(range)
for (let cpos of value) { const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
token = payload["cpos_lookup"][cpos]; lc = range(contextData.match.lc[0], contextData.match.lc[1], 1)
tokenElement = document.createElement("span"); c = range(contextData.match.c[0], contextData.match.c[1], 1)
tokenElement.classList.add("token"); rc = range(contextData.match.rc[0], contextData.match.rc[1], 1)
if (payload["match_cpos_list"].includes(cpos)) { } else {
tokenElement.classList.add("bold"); lc = contextData.match.lc;
tokenElement.classList.add("light-green"); c = contextData.match.c;
} rc = contextData.match.rc;
tokenElement.dataset.cpos = cpos; }
tokenElement.innerText = token["word"];
var expertModeSwitchElement = document.getElementById("expert-mode-switch"); partElement = document.createElement("p");
if (expertModeSwitchElement.checked) { for (let cpos of lc) {
expertModeOn([tokenElement], payload); token = contextData["cpos_lookup"][cpos];
} partElement.insertAdjacentHTML("beforeend", `<span class="token" data-cpos="${cpos}">${token["word"]} </span>`);
sentenceElement.append(tokenElement); contextResultsElement.append(partElement);
sentenceElement.append(document.createTextNode(" ")); }
} for (let cpos of c) {
contextResultsElement.append(sentenceElement); token = contextData["cpos_lookup"][cpos];
partElement.insertAdjacentHTML("beforeend", `<span class="token bold underline" data-cpos="${cpos}" style="text-decoration-line: underline;">${token["word"]} </span>`);
contextResultsElement.append(partElement);
}
for (let cpos of rc) {
token = contextData["cpos_lookup"][cpos];
partElement.insertAdjacentHTML("beforeend", `<span class="token" data-cpos="${cpos}">${token["word"]} </span>`);
contextResultsElement.append(partElement);
}
if (expertModeSwitchElement.checked) {
let tokenElements = partElement.getElementsByClassName("token");
expertModeOn(tokenElements, contextData);
} }
} }
// ###### Display options changing live how the matches are being displayed ###### // ###### Display options changing live how the matches are being displayed ######
// Event function that changes the shown hits per page. // Event function that changes the shown hits per page.
// Just alters the resultList.page property // Just alters the resultsList.page property
function changeHitsPerPage(event) { function changeHitsPerPage(event) {
try { try {
resultList.page = event.target.value; resultsList.page = event.target.value;
resultList.update(); resultsList.update();
nopaque.flash("Updated matches per page.") nopaque.flash("Updated matches per page.")
} catch (e) { } catch (e) {
console.log("resultList has no results right now. Live update of items per page is useless for now."); console.log("resultsList has no results right now. Live update of items per page is useless for now.");
} }
} }
@ -190,7 +212,7 @@ function eventHandlerCheck(event) {
console.log("pagination used!"); console.log("pagination used!");
console.log(expertModeSwitchElement.checked); console.log(expertModeSwitchElement.checked);
if (expertModeSwitchElement.checked) { if (expertModeSwitchElement.checked) {
expertModeOn(event.currentTarget.tokenElements, result); expertModeOn(event.currentTarget.tokenElements, resultsJSON);
} else if (!expertModeSwitchElement.checked) { } else if (!expertModeSwitchElement.checked) {
event.preventDefault(); event.preventDefault();
console.log("prevented! Destroy"); console.log("prevented! Destroy");
@ -199,19 +221,21 @@ function eventHandlerCheck(event) {
} }
// function to apply extra information and animation to every token // function to apply extra information and animation to every token
function expertModeOn(tokenElements, result_lookup) { function expertModeOn(tokenElements, results) {
let token; let token;
console.log("expertModeOn!"); console.log("expertModeOn!");
console.log(results);
console.log("hier:", tokenElements);
for (let tokenElement of tokenElements) { for (let tokenElement of tokenElements) {
tokenElement.classList.add("chip"); tokenElement.classList.add("chip");
tokenElement.classList.add("hoverable"); tokenElement.classList.add("hoverable");
tokenElement.classList.add("expert-view"); tokenElement.classList.add("expert-view");
token = result_lookup["cpos_lookup"][tokenElement.dataset.cpos]; token = results["cpos_lookup"][tokenElement.dataset.cpos];
tokenElement.addEventListener("mouseover", function(event) { tokenElement.addEventListener("mouseover", function(event) {
console.log("Mouseover!"); console.log("Mouseover!");
console.log(event.target); console.log(event.target);
token = result_lookup["cpos_lookup"][event.target.dataset.cpos]; token = results["cpos_lookup"][event.target.dataset.cpos];
addToolTipToTokenElement(event.target, token); addToolTipToTokenElement(event.target, token);
}); });
} }
@ -235,16 +259,12 @@ function addToolTipToTokenElement(tokenElement, token) {
NER: ${token["ner"]} NER: ${token["ner"]}
</td> </td>
<td class="left-align"> <td class="left-align">
Title: ${result["text_lookup"][token["text"]]["title"]}<br> Title: ${resultsJSON["text_lookup"][token["text"]]["title"]}<br>
Author: ${result["text_lookup"][token["text"]]["author"]}<br> Author: ${resultsJSON["text_lookup"][token["text"]]["author"]}<br>
Publishing year: ${result["text_lookup"][token["text"]]["publishing_year"]} Publishing year: ${resultsJSON["text_lookup"][token["text"]]["publishing_year"]}
</td> </td>
</tr> </tr>
</table>`, </table>`});
"inDuration": 1500,
"margin": 15,
"position": "top",
"transitionMovement": 0});
} }
// function to remove extra informations and animations from tokens // function to remove extra informations and animations from tokens

View File

@ -327,10 +327,44 @@
// get context of one match if inspected via socket.io // get context of one match if inspected via socket.io
nopaque.socket.on("pj_match_context", showMatchContext); nopaque.socket.on("pj_match_context", showMatchContext);
// live update of hits per page if hits per page value is changed
hitsPerPageInputElement = document.getElementById("display-options-form-results_per_page");
hitsPerPageInputElement.onchange = changeHitsPerPage;
// live update of lr context per item if context value is changed
contextPerItemElement = document.getElementById("display-options-form-result_context");
contextPerItemElement.onchange = changeContext;
// eventListener if pagination is used to apply new context size to new page
// and also activate inspect match if queryFinished is true
paginationElements = document.getElementsByClassName("pagination");
for (element of paginationElements) {
element.addEventListener("click", changeContext);
element.addEventListener("click", activateInspect);
}
// epxert mode table view
expertModeSwitchElement = document.getElementById("display-options-form-expert_mode");
expertModeSwitchElement.addEventListener("change", function(event) {
let currentTokenElements = document.getElementsByClassName("token");
let paginationElements = document.getElementsByClassName("pagination");
if (event.target.checked) {
console.log("Checked!");
expertModeOn(currentTokenElements, resultsJSON);
for (element of paginationElements) {
element.tokenElements = currentTokenElements;
element.addEventListener("click", eventHandlerCheck);
}
} else {
console.log("Unchecked!");
expertModeOff(currentTokenElements);
console.log("unchecked! Destroy");
}
})
}); });
// Add onclick to open download modal when Export Results button is pressed
// Add onclick to open download modal wen Export Results button is pressed
queryResultsExportElement.onclick = function() { queryResultsExportElement.onclick = function() {
exportModal.open(); exportModal.open();
} }