mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-12-24 18:34:18 +00:00
Remove old analyse_corpus.js
This commit is contained in:
parent
a09f3d79a8
commit
52efa0e821
@ -1,453 +0,0 @@
|
||||
// ### corpus analysis client status functions
|
||||
|
||||
function sendAbortSignal() {
|
||||
console.log(`Sending status "abort signal" from client side.`);
|
||||
message = {'status': "abort"};
|
||||
nopaque.socket.emit("send_analysis_status_cli", message);
|
||||
setAnalysisStatus("abort");
|
||||
}
|
||||
|
||||
function setAnalysisStatus(statusStr) {
|
||||
analysisClientStatus[sessionId] = statusStr;
|
||||
console.log(`Set new status "${statusStr}" for "${sessionId}" on client side.`);
|
||||
console.log("Object with status is:", analysisClientStatus);
|
||||
}
|
||||
|
||||
function checkAnalysisStatus(sessionId) {
|
||||
let status = analysisClientStatus[sessionId];
|
||||
console.log(`Check status on client side for ${sessionId}.`, analysisClientStatus);
|
||||
return status;
|
||||
}
|
||||
|
||||
// ### Send query functions ###
|
||||
|
||||
//function to get current queryData from a given queryFormElement
|
||||
function getQueryData(queryFormElement) {
|
||||
let formData
|
||||
let queryData
|
||||
formData = new FormData(queryFormElement);
|
||||
queryData = {"context": formData.get("context"), // global declaration
|
||||
"hits_per_page": formData.get("hits_per_page"),
|
||||
"query": formData.get("query")};
|
||||
return queryData
|
||||
}
|
||||
|
||||
// Function to send a query to the CQP server using queryData gatherd with getQueryData
|
||||
async function sendQuery(event) {
|
||||
const delay = ms => new Promise(res => setTimeout(res, ms));
|
||||
result; // global declaration, holds query results as JSON
|
||||
resultList; // global declaration, list.js object displaying the results
|
||||
let queryData; // holds data of query form
|
||||
let resultListOptions; // holding the options for the ResultList object
|
||||
let analysisStatus;
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
console.log("Sending query.");
|
||||
console.log("Session status are: ", analysisClientStatus);
|
||||
event.preventDefault();
|
||||
analysisStatus = checkAnalysisStatus(sessionId);
|
||||
queryData = getQueryData(queryFormElement);
|
||||
|
||||
if (analysisStatus === "idle") {
|
||||
nopaque.flash("Query has been sent!");
|
||||
nopaque.socket.emit("corpus_analysis_query", queryData.query);
|
||||
helperSendQuery(queryData);
|
||||
analysisStatus = checkAnalysisStatus(sessionId);
|
||||
} else if (analysisStatus === "running" ) {
|
||||
sendAbortSignal();
|
||||
analysisStatus = checkAnalysisStatus(sessionId);
|
||||
while (analysisStatus === "abort") {
|
||||
queryResultsTableElement.classList.add("hide");
|
||||
queryLoadingElement.classList.remove("hide");
|
||||
analysisStatus = checkAnalysisStatus(sessionId);
|
||||
await delay(100);
|
||||
}
|
||||
sendQuery(event)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function helperSendQuery(queryData) {
|
||||
// full results object declaration, global declaration!
|
||||
// will always be reset if a query is sent, so that only the chunks of the
|
||||
// current query will be saved in it
|
||||
result = {}; // full JSON object holding match results
|
||||
result["matches"] = []; // list of all amtches with lc and rc
|
||||
result["cpos_lookup"] = {}; // object contains all cpos as key value pair
|
||||
result["text_lookup"] = {}; // same as above for all text ids
|
||||
result["loaded_match_count"] = 0; // how many matches have been recieved
|
||||
result["num_matches_total"]; // how many should have been recieved/total nr
|
||||
result["query"] = ""; // the query as a string
|
||||
// some hiding/showing for loading animation
|
||||
queryLoadingElement.classList.remove("hide");
|
||||
queryResultsTableElement.classList.add("hide");
|
||||
|
||||
resultListOptions = {page: queryData["hits_per_page"],
|
||||
pagination: [{
|
||||
name: "paginationTop",
|
||||
paginationClass: "paginationTop",
|
||||
innerWindow: 8,
|
||||
outerWindow: 1
|
||||
}, {
|
||||
paginationClass: "paginationBottom",
|
||||
innerWindow: 8,
|
||||
outerWindow: 1
|
||||
}],
|
||||
valueNames: ["titles", "lc", "c", "rc", {data: ["index"]}],
|
||||
item: `<span></span>`};
|
||||
resultList = new ResultsList('result-list', resultListOptions);
|
||||
resultList.clear(); // empty list for new query
|
||||
}
|
||||
|
||||
// ### Recieve results from sent query and display them in a list etc. ###
|
||||
|
||||
// Function used when CQP server sends back the query results using socketio
|
||||
function recieveResults(response) {
|
||||
let toolTipInfoElement;
|
||||
let chunk;
|
||||
let countCorpusFiles;
|
||||
let queryData;
|
||||
let queryResultsElement;
|
||||
let resultItems;
|
||||
let queryResultsMetadataElement;
|
||||
let queryResultsInteractionElement;
|
||||
let queryResultsHeadElement;
|
||||
let queryStatus;
|
||||
queryFinished = false;
|
||||
|
||||
console.log(response);
|
||||
|
||||
// ERROR code checking
|
||||
if (response["code"] === 0) {
|
||||
console.log("[SUCCESS] corpus_analysis_init");
|
||||
console.log("Code:" + response["code"]);
|
||||
// further code execution of this code block starting in line 342
|
||||
} else if (response["code"] === 1) {
|
||||
queryResultsTableElement.classList.add("hide");
|
||||
queryLoadingElement.classList.add("hide");
|
||||
nopaque.flash("error", "Invalid query entered!");
|
||||
console.log("[ERROR] corpus_analysis_init");
|
||||
console.log("Code:" + response["code"]);
|
||||
return; // no further code execution of this code block
|
||||
} else {
|
||||
console.log("[ERROR] corpus_analysis_init");
|
||||
console.log("Code:" + response["code"]);
|
||||
return; // no further code execution of this code block
|
||||
}
|
||||
// logs the current recieved chunk
|
||||
chunk = response["chunk"];
|
||||
//chunk = response["chunk"];
|
||||
console.log("### corpus_analysis chunk ###");
|
||||
console.log(chunk);
|
||||
// logs and extends/push/update the current recieved chunk to the
|
||||
// result Object
|
||||
console.log("### corpus analysis updated result json ###");
|
||||
result["matches"].push(...chunk["matches"]);
|
||||
Object.assign(result["cpos_lookup"], chunk["cpos_lookup"]);
|
||||
Object.assign(result["text_lookup"], chunk["text_lookup"]);
|
||||
result["num_matches_total"] = response["num_matches_total"];
|
||||
//result["match_count"] = response["match_count"];
|
||||
console.log("Before Current match count", result["loaded_match_count"]);
|
||||
queryData = getQueryData(queryFormElement);
|
||||
result["query"] = queryData["query"];
|
||||
console.log(result);
|
||||
// Some hiding and showing of loading animations
|
||||
analysisStatus = checkAnalysisStatus();
|
||||
if (analysisStatus === "abort") {
|
||||
queryResultsTableElement.classList.add("hide");
|
||||
queryLoadingElement.classList.remove("hide");
|
||||
} else {
|
||||
queryResultsTableElement.classList.remove("hide");
|
||||
queryLoadingElement.classList.add("hide");
|
||||
queryResultsElement = document.getElementById("query-results");
|
||||
queryResultsElement.innerHTML = "";
|
||||
}
|
||||
|
||||
// check if query has any results
|
||||
if (chunk["matches"].length === 0) {
|
||||
queryResultsTableElement.classList.add("hide");
|
||||
nopaque.flash("No results for this query!");
|
||||
return;
|
||||
}
|
||||
|
||||
// List building/appending the chunks when query had results
|
||||
countCorpusFiles = Object.keys(result["text_lookup"]).length;
|
||||
|
||||
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"]}});
|
||||
}
|
||||
resultList.add(resultItems, items => {
|
||||
for (let item of items) {
|
||||
item.elm = resultList.createResultRowElement(item, chunk);
|
||||
}
|
||||
resultList.update();
|
||||
changeContext(); // sets lr context on first result load
|
||||
});
|
||||
result["loaded_match_count"] += Object.keys(chunk["matches"]).length;
|
||||
console.log("After current match count", result["loaded_match_count"]);
|
||||
queryResultsMetadataElement = document.getElementById("query-results-metadata");
|
||||
queryResultsMetadataElement.innerHTML = `<p>The query resulted in a total of ${result["num_matches_total"]} matches. </p> <p> ${result["loaded_match_count"]} of ${result["num_matches_total"]} matches in ${countCorpusFiles} corpus files have been loaded.</p><p><i class="material-icons" id="tooltip-info">help</i>The Server is still sending your results. Functions like "Export Results" and "Match Inspect" will be available after all matches have been loaded.</p>`;
|
||||
queryResultsInteractionElement = document.getElementById("interaction-elements");
|
||||
queryResultsInteractionElement.appendChild(exportQueryResultsElement);
|
||||
queryResultsHeadElement = document.getElementById("query-results-head");
|
||||
queryResultsHeadElement.classList.remove("hide");
|
||||
queryStatus = response["progress"];
|
||||
console.log("QUERY STATUS:", 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) {
|
||||
queryFinished = true; // global declaration to set downlaod button and inspects buttons back to disabled for new queries
|
||||
queryResultsDeterminateElement.parentNode.parentNode.classList.add("hide");
|
||||
exportQueryResultsElement.classList.remove("disabled");
|
||||
queryResultsMetadataElement.innerHTML = `<p>The query resulted in a total of ${result["num_matches_total"]} matches. </p> <p> ${result["loaded_match_count"]} of ${result["num_matches_total"]} matches in ${countCorpusFiles} corpus files have been loaded.<i class="material-icons">check_circle</i></p>`;
|
||||
activateInspect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ### Functions to inspect one match, to show more details ###
|
||||
|
||||
// activate inspect buttons if queryFinished is true
|
||||
function activateInspect() {
|
||||
let inspectBtnElements;
|
||||
|
||||
if (queryFinished) {
|
||||
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]["c"]);
|
||||
contextModal.open();
|
||||
nopaque.socket.emit("inspect_match", {"cpos": result["matches"][dataIndex]["c"]});
|
||||
}
|
||||
|
||||
function showMatchContext(message) {
|
||||
let contextResultsElement;
|
||||
let sentenceElement
|
||||
let token;
|
||||
let tokenElement;
|
||||
console.log("### match_context ###");
|
||||
console.log("Incoming data:", message);
|
||||
contextResultsElement = document.getElementById("context-results");
|
||||
contextResultsElement.innerHTML = "<p> </p>";
|
||||
document.getElementById("context-modal-loading").classList.add("hide");
|
||||
document.getElementById("context-modal-ready").classList.remove("hide");
|
||||
|
||||
for (let [key, value] of Object.entries(message['context_s_cpos'])) {
|
||||
sentenceElement = document.createElement("p");
|
||||
for (let 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.
|
||||
// Just alters the resultList.page property
|
||||
function changeHitsPerPage(event) {
|
||||
try {
|
||||
resultList.page = event.target.value;
|
||||
resultList.update();
|
||||
nopaque.flash("Updated matches per page.")
|
||||
} catch (e) {
|
||||
console.log("resultList has no results right now. Live update of items per page is useless for now.");
|
||||
}
|
||||
}
|
||||
|
||||
// Event function triggered on context select change and also if pagination is clicked
|
||||
function changeContext(event) {
|
||||
let newContextValue;
|
||||
let lc;
|
||||
let rc;
|
||||
let array;
|
||||
try {
|
||||
if (event.type === "change") {
|
||||
nopaque.flash("Updated context per match!");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
console.log("This error is expected.");
|
||||
} finally {
|
||||
newContextValue = document.getElementById("context").value;
|
||||
console.log("Context value is:", newContextValue);
|
||||
lc = document.getElementsByClassName("left-context");
|
||||
rc = document.getElementsByClassName("right-context");
|
||||
for (let element of lc) {
|
||||
array = Array.from(element.childNodes);
|
||||
for (let element of array.slice(newContextValue)) {
|
||||
element.classList.add("hide");
|
||||
}
|
||||
for (let element of array.slice(0, newContextValue)) {
|
||||
element.classList.remove("hide");
|
||||
}
|
||||
}
|
||||
for (let element of rc) {
|
||||
array = Array.from(element.childNodes);
|
||||
for (let element of array.slice(newContextValue)) {
|
||||
element.classList.add("hide");
|
||||
}
|
||||
for (let element of array.slice(0, newContextValue)) {
|
||||
element.classList.remove("hide");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ### Expert view event functions ###
|
||||
|
||||
// Event function to check if pagination is used and then look if
|
||||
// expertModeSwitchElement is checked
|
||||
// if checked than expertModeOn is executed
|
||||
// if unchecked expertModeOff is executed
|
||||
function eventHandlerCheck(event) {
|
||||
console.log("pagination used!");
|
||||
console.log(expertModeSwitchElement.checked);
|
||||
if (expertModeSwitchElement.checked) {
|
||||
expertModeOn(event.currentTarget.tokenElements, result);
|
||||
} else if (!expertModeSwitchElement.checked) {
|
||||
event.preventDefault();
|
||||
console.log("prevented! Destroy");
|
||||
expertModeOff(event.currentTarget.tokenElements);
|
||||
}
|
||||
}
|
||||
|
||||
// function to apply extra information and animation to every token
|
||||
function expertModeOn(tokenElements, result_lookup) {
|
||||
let token;
|
||||
|
||||
console.log("expertModeOn!");
|
||||
for (let tokenElement of tokenElements) {
|
||||
tokenElement.classList.add("chip");
|
||||
tokenElement.classList.add("hoverable");
|
||||
tokenElement.classList.add("expert-view");
|
||||
token = result_lookup["cpos_lookup"][tokenElement.dataset.cpos];
|
||||
tokenElement.addEventListener("mouseover", function(event) {
|
||||
console.log("Mouseover!");
|
||||
console.log(event.target);
|
||||
token = result_lookup["cpos_lookup"][event.target.dataset.cpos];
|
||||
addToolTipToTokenElement(event.target, token);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// fuction that creates Tooltip for one token and extracts the corresponding
|
||||
// infos from the result JSON
|
||||
function addToolTipToTokenElement(tokenElement, token) {
|
||||
M.Tooltip.init(tokenElement,
|
||||
{"html": `<table>
|
||||
<tr>
|
||||
<th>Token information</th>
|
||||
<th>Source information</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left-align">
|
||||
Word: ${token["word"]}<br>
|
||||
Lemma: ${token["lemma"]}<br>
|
||||
POS: ${token["pos"]}<br>
|
||||
Simple POS: ${token["simple_pos"]}<br>
|
||||
NER: ${token["ner"]}
|
||||
</td>
|
||||
<td class="left-align">
|
||||
Title: ${result["text_lookup"][token["text"]]["title"]}<br>
|
||||
Author: ${result["text_lookup"][token["text"]]["author"]}<br>
|
||||
Publishing year: ${result["text_lookup"][token["text"]]["publishing_year"]}
|
||||
</td>
|
||||
</tr>
|
||||
</table>`,
|
||||
"inDuration": 1500,
|
||||
"margin": 15,
|
||||
"position": "top",
|
||||
"transitionMovement": 0});
|
||||
}
|
||||
|
||||
// function to remove extra informations and animations from tokens
|
||||
function expertModeOff(tokenElements) {
|
||||
console.log("expertModeOff!");
|
||||
for (let tokenElement of tokenElements) {
|
||||
tokenElement.classList.remove("chip");
|
||||
tokenElement.classList.remove("hoverable");
|
||||
tokenElement.classList.remove("expert-view");
|
||||
tokenElement.outerHTML = tokenElement.outerHTML; // this is actually a workaround, but it works pretty fast
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ### Download results functions ###
|
||||
|
||||
// function creates a unique and safe filename for the download
|
||||
function createDownloadFilename() {
|
||||
let today;
|
||||
let currentDate;
|
||||
let currentTime;
|
||||
let safeFilename;
|
||||
let resultFilename;
|
||||
// get and create metadata
|
||||
console.log("Create Metadata!");
|
||||
today = new Date();
|
||||
currentDate = today.getUTCFullYear() + '-' + (today.getUTCMonth() +1) + '-' + today.getUTCDate();
|
||||
currentTime = today.getUTCHours() + ":" + today.getUTCMinutes() + ":" + today.getUTCSeconds();
|
||||
safeFilename = result['query'].replace(/[^a-z0-9_-]/gi, "_");
|
||||
resultFilename = "UTC-" + currentDate + "_" + currentTime + "_" + safeFilename;
|
||||
return resultFilename
|
||||
}
|
||||
|
||||
// function to download the results as JSON
|
||||
function downloadJSONRessource(resultFilename) {
|
||||
let dataStr;
|
||||
let downloadElement;
|
||||
// stringify JSON object for json download
|
||||
dataStr = JSON.stringify(result, undefined, "\t"); // use tabs to save some space
|
||||
// get downloadResultsElement
|
||||
downloadElement = document.getElementById("download-results-json");
|
||||
// start actual download
|
||||
download(downloadElement, dataStr, resultFilename, "text/json", ".json")
|
||||
}
|
||||
|
||||
// Function to download data as a Blob created from a string, should be multi purpose
|
||||
function download(downloadElem, dataStr, filename, type, filenameSlug) {
|
||||
let file;
|
||||
console.log("Start Download!");
|
||||
filename += filenameSlug;
|
||||
file = new Blob([dataStr], {type: type});
|
||||
if (window.navigator.msSaveOrOpenBlob) // IE10+
|
||||
window.navigator.msSaveOrOpenBlob(file, filename);
|
||||
else { // Others
|
||||
var url = URL.createObjectURL(file);
|
||||
downloadElem.href = url;
|
||||
downloadElem.download = filename;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user