Clean up corpus analysis and add new features

This commit is contained in:
Stephan Porada 2020-03-18 15:52:53 +01:00
parent c5e56692b1
commit 3111cc5175
5 changed files with 129 additions and 61 deletions

View File

@ -43,7 +43,7 @@ def corpus_analysis_query(query):
response = {'code': 1}
socketio.emit('corpus_analysis_query', response, room=request.sid)
else:
chunk_size = 500
chunk_size = 100
chunk_start = 0
context = 100
while chunk_start < client.match_count:

View File

@ -7,12 +7,20 @@ function getQueryData(queryFormElement) {
queryData = {"context": formData.get("context"), // global declaration
"hits_per_page": formData.get("hits_per_page"),
"query": formData.get("query")};
console.log("Query data:", queryData);
return queryData
}
// Function to send a query to the CQP server using queryData gatherd with getQueryData
function sendQuery(event) {
// checks if one query has been finished before
// if true result download will be disabled again until query is finished
// also shows progress bar again
if (queryFinished) {
exportQueryResultsElement.classList.add("disabled");
queryResultsDeterminateElement.parentNode.parentNode.classList.remove("hide");
}
event.preventDefault();
queryData = getQueryData(queryFormElement);
nopaque.socket.emit("corpus_analysis_query", queryData.query);
@ -52,6 +60,7 @@ function sendQuery(event) {
// Function used when CQP server sends back the query results using socketio
function recieveResults(response) {
// ERROR code checking
if (response["code"] === 0) {
console.log("[SUCCESS] corpus_analysis_init");
@ -87,6 +96,7 @@ function recieveResults(response) {
// Some hiding and showing of loading animations
queryLoadingElement.classList.add("hide");
queryResultsTableElement.classList.remove("hide");
let queryResultsElement = document.getElementById("query-results");
queryResultsElement.innerHTML = "";
// check if query has any results
@ -100,7 +110,7 @@ function recieveResults(response) {
match_count = chunk["match_count"];
let count_corpus_files = Object.keys(result["text_lookup"]).length;
var resultItems = []; // list for holding every row item
let resultItems = []; // list for holding every row item
// get infos for full match row
for (let [index, match] of chunk["matches"].entries()) {
resultItems.push({...match, ...{"index": index + result["loaded_match_count"]}});
@ -114,12 +124,43 @@ function recieveResults(response) {
});
result["loaded_match_count"] += Object.keys(chunk["matches"]).length;
console.log("After current match count", result["loaded_match_count"]);
let queryResultsMetadataElement = document.getElementById("query-results-metadata");
queryResultsMetadataElement.innerHTML = `<p>The query resulted in a total of ${chunk["match_count"]} matches. </p> <p> ${result["loaded_match_count"]} of ${result["match_count"]} matches in ${count_corpus_files} corpus files have been loaded.</p>`;
queryResultsMetadataElement.appendChild(exportQueryResults);
exportQueryResults.classList.remove("hide");
let queryResultsInteractionElement = document.getElementById("interaction-elements");
queryResultsInteractionElement.appendChild(exportQueryResultsElement);
let queryResultsHeadElement = document.getElementById("query-results-head");
queryResultsHeadElement.classList.remove("hide");
queryStatus = result["loaded_match_count"] / result["match_count"] * 100;
console.log(queryStatus);
queryResultsDeterminateElement.style["width"] = `${queryStatus}%`;
console.log(queryResultsDeterminateElement.style["width"]);
// enable download and inspect when query is finished
// also sets queryFinished to true
if (queryStatus === 100) {
queryResultsDeterminateElement.parentNode.parentNode.classList.add("hide");
exportQueryResultsElement.classList.remove("disabled");
let inspectBtnElements = document.getElementsByClassName("inspect");
for (let inspectBtn of inspectBtnElements) {
inspectBtn.classList.remove("disabled");
queryFinished = true; // global declaration to set downlaod button and inspects buttons back to disabled for new queries
}
}
}
// Function to inspect one match, to show more details
// ### Functions to inspect one match, to show more details ###
// activate inspect buttons if queryFinished is true
function activateInspect() {
if (queryFinished) {
let inspectBtnElements = document.getElementsByClassName("inspect");
for (let inspectBtn of inspectBtnElements) {
inspectBtn.classList.remove("disabled");
}
}
}
//gets result cpos infos for one dataIndex to send back to the server
function inspect(dataIndex) {
console.log("Inspect!");
console.log(result["matches"][dataIndex]["hit"]);
@ -127,6 +168,38 @@ function inspect(dataIndex) {
nopaque.socket.emit("inspect_match", {"cpos": result["matches"][dataIndex]["hit"]});
}
function showMatchContext(message) {
console.log("### match_context ###");
console.log("Incoming data:", message);
contextResultsElement.innerHTML = "<p>&nbsp;</p>";
document.getElementById("context-modal-loading").classList.add("hide");
document.getElementById("context-modal-ready").classList.remove("hide");
let sentenceElement, token, tokenElement;
for (let [key, value] of Object.entries(message['context_s_cpos'])) {
sentenceElement = document.createElement("p");
for (cpos of value) {
token = message["cpos_lookup"][cpos];
tokenElement = document.createElement("span");
tokenElement.classList.add("token");
if (message["match_cpos_list"].includes(cpos)) {
tokenElement.classList.add("bold");
tokenElement.classList.add("light-green");
}
tokenElement.dataset.cpos = cpos;
tokenElement.innerText = token["word"];
var expertModeSwitchElement = document.getElementById("expert-mode-switch");
if (expertModeSwitchElement.checked) {
expertModeOn([tokenElement], message);
}
sentenceElement.append(tokenElement);
sentenceElement.append(document.createTextNode(" "));
}
contextResultsElement.append(sentenceElement);
}
}
// ### Display options changing live how the matches are being displayed ###
// Event function that changes the shown hits per page.
@ -151,6 +224,7 @@ function changeContext(event) {
}
} catch (e) {
console.log(e);
console.log("This error is expected.");
} finally {
var contextPerItemElement = document.getElementById("context");
newValue = contextPerItemElement.value;

View File

@ -188,39 +188,6 @@ nopaque.socket.on("foreign_jobs_update", function(msg) {
for (let subscriber of nopaque.foreignJobsSubscribers) {subscriber._update(patch);}
});
// get context of one match if inspected
nopaque.socket.on("match_context", function(message) {
console.log("### match_context ###");
console.log("Incoming data:", message);
contextResultsElement.innerHTML = "<p>&nbsp;</p>";
document.getElementById("context-modal-loading").classList.add("hide");
document.getElementById("context-modal-ready").classList.remove("hide");
let sentenceElement, token, tokenElement;
for (let [key, value] of Object.entries(message['context_s_cpos'])) {
sentenceElement = document.createElement("p");
for (cpos of value) {
token = message["cpos_lookup"][cpos];
tokenElement = document.createElement("span");
tokenElement.classList.add("token");
if (message["match_cpos_list"].includes(cpos)) {
tokenElement.classList.add("bold");
tokenElement.classList.add("light-green");
}
tokenElement.dataset.cpos = cpos;
tokenElement.innerText = token["word"];
var expertModeSwitchElement = document.getElementById("expert-mode-switch");
if (expertModeSwitchElement.checked) {
expertModeOn([tokenElement], message);
}
sentenceElement.append(tokenElement);
sentenceElement.append(document.createTextNode(" "));
}
contextResultsElement.append(sentenceElement);
}
});
document.addEventListener("DOMContentLoaded", function() {
nopaque.Workarounds.apply();
M.AutoInit();

View File

@ -152,7 +152,7 @@ class ResultList extends List {
textTitles.add(chunk["text_lookup"][token["text"]]["title"]);
// add button to trigger more context to every match td
var inspectBtn = document.createElement("a");
inspectBtn.setAttribute("class", "btn-floating btn-flat waves-effect waves-light grey right inspect");
inspectBtn.setAttribute("class", "btn-floating btn-flat waves-effect waves-light grey right inspect disabled");
inspectBtn.innerHTML = '<i class="material-icons">search</i>';
inspectBtn.onclick = function() {inspect(values["index"])};
}

View File

@ -157,18 +157,25 @@ server side -->
<div class="card">
<div class="card-content" id="result-list" style="overflow: hidden;">
<span class="card-title">Query Results</span>
<div class="row">
<div class="col s12" id="query-results-metadata">
<div class="hide" id="query-results-head">
<div class="col s12 m6 l6">
<div class="row">
<div class="col s10" id="query-results-metadata"></div>
</div>
<div class="col s12">
<div class="row">
<div class="progress">
<div class="determinate" style="width: 70%"></div>
<div class="determinate"></div>
</div>
<p>&nbsp;</p>
<button id="export-query-results" class="waves-effect waves-light btn-small right hide" type="submit">Export Results<i class="material-icons right">file_download</i></button>
</div>
</div>
<div class="col s12 m6 l6">
<div class="row" id="interaction-elements">
<button id="export-query-results" class="waves-effect waves-light btn-small right disabled" type="submit">Export Results<i class="material-icons right">file_download</i></button>
</div>
</div>
</div>
<!-- table showing the query results -->
<div class="col s12">
<ul class="pagination paginationTop"></ul>
<table class="responsive-table highlight">
<thead>
@ -184,6 +191,8 @@ server side -->
</tbody>
</table>
<ul class="pagination paginationBottom"></ul>
</div>
</div>
</div>
</div>
@ -222,10 +231,24 @@ server side -->
<script src="{{ url_for('static', filename='js/nopaque.analyse_corpus.js') }}"></script>
<script>
// Initialising some modals for later usage
// ### Initiating global variables ###
// create some globa modals for later usage
var contextModal;
var loadingModal;
var exportModal;
// create some global variables
var hitsPerPage;
var result;
var resultList;
var queryFinished;
// create some global elements
var exportQueryResultsElement;
var queryResultsDeterminateElement;
var queryResultsTableElement;
var queryLoadingElement;
var contextResultsElement;
document.addEventListener("DOMContentLoaded", function() {
contextModal = M.Modal.init(document.getElementById("context-modal"),
{"onCloseEnd": function() {
@ -250,26 +273,24 @@ server side -->
}
});
// getting some HTML-elements to use/hide/remove/show or add some other elements to them
var queryResultsElement = document.getElementById("query-results");
var queryResultsMetadataElement = document.getElementById("query-results-metadata");
var exportQueryResults = document.getElementById("export-query-results");
exportQueryResults.onclick = function() {
exportModal.open();
};
var contextResultsElement = document.getElementById("context-results");
var queryLoadingElement = document.getElementById("getting-query-results");
// getting some HTML-elements to use/hide/remove/show or add some other
// elements to them.
// These elements will be used inside functions in nopaque.analyse_corpus.js
var queryResultsDeterminateElement = document.getElementsByClassName("determinate")[0];
var queryResultsTableElement = document.getElementById("recieved-query-results");
;
// create some global variables
var hitsPerPage;
var result;
var resultList;
var queryLoadingElement = document.getElementById("getting-query-results");
var exportQueryResultsElement = document.getElementById("export-query-results");
var contextResultsElement = document.getElementById("context-results");
// socket.io analysis submit to the CQP server
let queryFormElement = document.getElementById("query-form");
queryFormElement.addEventListener("submit", sendQuery);
// get context of one match if inspected
nopaque.socket.on("match_context", showMatchContext);
// live update of hits per page
var hitsPerPageInputElement = document.getElementById("hits-per-page");
hitsPerPageInputElement.onchange = changeHitsPerPage;
@ -282,11 +303,17 @@ server side -->
var paginationElements = document.getElementsByClassName("pagination");
for (element of paginationElements) {
element.addEventListener("click", changeContext);
element.addEventListener("click", activateInspect);
}
// socket.on triggered when result chunks are recieved
nopaque.socket.on("corpus_analysis_query", recieveResults);
// Add onclick to open download modal
exportQueryResultsElement.onclick = function() {
exportModal.open();
}
// add onclick to download JSON button and download the file
var downloadResultsJSONElement = document.getElementById("download-results-json")
downloadResultsJSONElement.onclick = function() {