mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 12:22:47 +00:00 
			
		
		
		
	First feature complete rebuilt of analysis interface
This commit is contained in:
		@@ -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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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> </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;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  partElement = document.createElement("p");
 | 
				
			||||||
 | 
					  for (let cpos of lc) {
 | 
				
			||||||
 | 
					    token = contextData["cpos_lookup"][cpos];
 | 
				
			||||||
 | 
					    partElement.insertAdjacentHTML("beforeend", `<span class="token" data-cpos="${cpos}">${token["word"]} </span>`);
 | 
				
			||||||
 | 
					    contextResultsElement.append(partElement);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  for (let cpos of c) {
 | 
				
			||||||
 | 
					    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);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
      tokenElement.dataset.cpos = cpos;
 | 
					 | 
				
			||||||
      tokenElement.innerText = token["word"];
 | 
					 | 
				
			||||||
      var expertModeSwitchElement = document.getElementById("expert-mode-switch");
 | 
					 | 
				
			||||||
  if (expertModeSwitchElement.checked) {
 | 
					  if (expertModeSwitchElement.checked) {
 | 
				
			||||||
        expertModeOn([tokenElement], payload);
 | 
					    let tokenElements = partElement.getElementsByClassName("token");
 | 
				
			||||||
      }
 | 
					    expertModeOn(tokenElements, contextData);
 | 
				
			||||||
      sentenceElement.append(tokenElement);
 | 
					 | 
				
			||||||
      sentenceElement.append(document.createTextNode(" "));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    contextResultsElement.append(sentenceElement);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ###### 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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user