diff --git a/app/static/js/nopaque.Results.js b/app/static/js/nopaque.Results.js index 064fafcf..3f4c7473 100644 --- a/app/static/js/nopaque.Results.js +++ b/app/static/js/nopaque.Results.js @@ -1,8 +1,77 @@ class Results { - constructor(results, resultsList) { - this.resultsJSON = results; + constructor(resultsJSON, resultsList) { + this.resultsJSON = resultsJSON; this.resultsList = resultsList; } + clear_all() { + this.resultsList.clear(); + this.resultsList.update(); + this.resultsJSON.init(); + } +} + +class ResultsJSON { + // Sets empty object structure. Also usefull to delete old results. + init(matchCount = 0) { + this["matches"] = []; // list of all c with lc and rc + this["cpos_lookup"] = {}; // object contains all this key value pair + this["text_lookup"] = {}; // same as above for all text ids + this["match_count"] = matchCount; + } + + // get query as string from form Element + getQueryStr(queryFormElement) { + // gets query + let queryFormData; + let queryStr; + queryFormData = new FormData(queryFormElement); + queryStr = queryFormData.get("query-form-query"); + this["query"] = queryStr; + } + + // function creates a unique and safe filename for the download + createDownloadFilename() { + let today; + let currentDate; + let currentTime; + let safeFilename; + let resultFilename; + // get and create metadata + today = new Date(); + currentDate = today.getUTCFullYear() + '-' + (today.getUTCMonth() +1) + '-' + today.getUTCDate(); + currentTime = today.getUTCHours() + ":" + today.getUTCMinutes() + ":" + today.getUTCSeconds(); + safeFilename = this.query.replace(/[^a-z0-9_-]/gi, "_"); + resultFilename = "UTC-" + currentDate + "_" + currentTime + "_" + safeFilename; + return resultFilename + } + + // Function to download data as a Blob created from a string, should be multi purpose + 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; + } + } + + // function to download the results as JSON + downloadJSONRessource(resultFilename) { + let dataStr; + let downloadElement; + // stringify JSON object for json download + dataStr = JSON.stringify(results.resultsJSON, undefined, "\t"); // use tabs to save some space + // get downloadResultsElement + downloadElement = document.getElementById("download-results-json"); + // start actual download + this.download(downloadElement, dataStr, resultFilename, "text/json", ".json") + } } \ No newline at end of file diff --git a/app/static/js/nopaque.analyse_corpus.js b/app/static/js/nopaque.analyse_corpus.js deleted file mode 100644 index 71ecaf06..00000000 --- a/app/static/js/nopaque.analyse_corpus.js +++ /dev/null @@ -1,279 +0,0 @@ -// ###### Helper functions ###### - -// get query as string from form Element -function getQueryStr(queryFormElement) { - // gets query - let queryFormData; - let queryStr; - queryFormData = new FormData(queryFormElement); - queryStr = queryFormData.get("query-form-query"); - return queryStr -} - -// get display options from display options form element -function getDisplayOptions(displayOptionsFormElement) { - // gets display options parameters - let displayOptionsFormData - let displayOptionsData; - displayOptionsFormData = new FormData(displayOptionsFormElement); - displayOptionsData = {"resultsPerPage": displayOptionsFormData.get("display-options-form-results_per_page"), - "resultsContex": displayOptionsFormData.get("display-options-form-result_context"), - "expertMode": displayOptionsFormData.get("display-options-form-expert_mode")}; - console.log(displayOptionsData); - return displayOptionsData -} - -// ###### Download results functions ###### -// TODO: Maybe write these as class functions? For this maybe create a result class - -// 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 = results.resultsJSON["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(results.resultsJSON, 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; - } -} - -// ###### Functions to inspect one match, to show more details ###### - -// activate inspect buttons if queryFinished is true -function activateInspect() { - console.log("activation progress", progress); - if (progress === 100) { - let inspectBtnElements; - inspectBtnElements = document.getElementsByClassName("inspect"); - for (let inspectBtn of inspectBtnElements) { - inspectBtn.classList.remove("disabled"); - } - } else { - return - } -} - -//gets result cpos infos for one dataIndex to send back to the server -function inspect(dataIndex) { - // This function should be in the AnalysisClient class as a method. - console.log("Inspect!"); - console.log(results.resultsJSON.matches[dataIndex].c); - contextResultsElement = document.getElementById("context-results"); - contextResultsElement.innerHTML = ""; // clear it from old inspects - contextModal.open(); - nopaque.socket.emit("corpus_analysis_inspect_match", - {payload: { - first_cpos: results.resultsJSON.matches[dataIndex].c[0], - last_cpos: results.resultsJSON.matches[dataIndex].c[1] - } - }); -} - -function showMatchContext(response) { - let contextData = response.payload - let contextResultsElement; - let contextModalLoading; - let contextModalReady; - let expertModeSwitchElement - let partElement - let token; - let tokenElement; - let tokenElements; - console.log("###### match_context ######"); - console.log("Incoming data:", contextData); - expertModeSwitchElement = document.getElementById("display-options-form-expert_mode"); - contextResultsElement = document.getElementById("context-results"); - - if (contextData.cpos_ranges == true) { - // python range like function from MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Sequence_generator_(range) - const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step)); - lc = range(contextData.match.lc[0], contextData.match.lc[1], 1) - c = range(contextData.match.c[0], contextData.match.c[1], 1) - rc = range(contextData.match.rc[0], contextData.match.rc[1], 1) - } else { - lc = contextData.match.lc; - c = contextData.match.c; - rc = contextData.match.rc; - } - - partElement = document.createElement("p"); - for (let cpos of lc) { - token = contextData["cpos_lookup"][cpos]; - partElement.insertAdjacentHTML("beforeend", `${token["word"]} `); - contextResultsElement.append(partElement); - } - for (let cpos of c) { - token = contextData["cpos_lookup"][cpos]; - partElement.insertAdjacentHTML("beforeend", `${token["word"]} `); - contextResultsElement.append(partElement); - } - for (let cpos of rc) { - token = contextData["cpos_lookup"][cpos]; - partElement.insertAdjacentHTML("beforeend", `${token["word"]} `); - contextResultsElement.append(partElement); - } - if (expertModeSwitchElement.checked) { - tokenElements = partElement.getElementsByClassName("token"); - expertModeOn(tokenElements, contextData); - } -} - -// ###### Display options changing live how the matches are being displayed ###### - -// Event function that changes the shown hits per page. -// Just alters the resultsList.page property -function changeHitsPerPage(event) { - try { - resultsList.page = event.target.value; - resultsList.update(); - nopaque.flash("Updated matches per page.") - } catch (e) { - console.log("resultsList 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("display-options-form-result_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, resultsJSON); - } 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, results) { - let token; - - console.log("expertModeOn!"); - for (let tokenElement of tokenElements) { - tokenElement.classList.add("chip"); - tokenElement.classList.add("hoverable"); - tokenElement.classList.add("expert-view"); - token = results["cpos_lookup"][tokenElement.dataset.cpos]; - tokenElement.addEventListener("mouseover", function(event) { - console.log("Mouseover!"); - console.log(event.target); - token = results["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": `
Token information | -Source information | -
---|---|
- Word: ${token["word"]} - Lemma: ${token["lemma"]} - POS: ${token["pos"]} - Simple POS: ${token["simple_pos"]} - NER: ${token["ner"]} - |
-
- Title: ${resultsJSON["text_lookup"][token["text"]]["title"]} - Author: ${resultsJSON["text_lookup"][token["text"]]["author"]} - Publishing year: ${resultsJSON["text_lookup"][token["text"]]["publishing_year"]} - |
-
Token information | +Source information | +
---|---|
+ Word: ${token["word"]} + Lemma: ${token["lemma"]} + POS: ${token["pos"]} + Simple POS: ${token["simple_pos"]} + NER: ${token["ner"]} + |
+
+ Title: ${resultsJSON["text_lookup"][token["text"]]["title"]} + Author: ${resultsJSON["text_lookup"][token["text"]]["author"]} + Publishing year: ${resultsJSON["text_lookup"][token["text"]]["publishing_year"]} + |
+