alessandro trinca tornidor
commited on
Commit
·
1b77e8d
1
Parent(s):
87def91
feeat: new layout separating the list of prefix frequencies from the table of word positions
Browse files- static/index.css +2 -2
- static/index.html +7 -4
- static/index.js +57 -26
static/index.css
CHANGED
|
@@ -31,12 +31,12 @@
|
|
| 31 |
text-decoration-color: darkturquoise;
|
| 32 |
text-decoration-style: wavy;
|
| 33 |
}
|
| 34 |
-
.underlinedBlue {
|
| 35 |
color: blue;
|
| 36 |
text-decoration: underline;
|
| 37 |
text-decoration-color: blue;
|
| 38 |
}
|
| 39 |
-
.underlinedDarkViolet {
|
| 40 |
color: violet;
|
| 41 |
text-decoration: underline;
|
| 42 |
text-decoration-color: violet;
|
|
|
|
| 31 |
text-decoration-color: darkturquoise;
|
| 32 |
text-decoration-style: wavy;
|
| 33 |
}
|
| 34 |
+
.underlinedBlue, .underlinedBlueTable {
|
| 35 |
color: blue;
|
| 36 |
text-decoration: underline;
|
| 37 |
text-decoration-color: blue;
|
| 38 |
}
|
| 39 |
+
.underlinedDarkViolet, .underlinedDarkVioletTable {
|
| 40 |
color: violet;
|
| 41 |
text-decoration: underline;
|
| 42 |
text-decoration-color: violet;
|
static/index.html
CHANGED
|
@@ -7,7 +7,7 @@
|
|
| 7 |
<link rel="stylesheet" href="/static/index.css">
|
| 8 |
<script src="/static/index.js"></script>
|
| 9 |
</head>
|
| 10 |
-
<body>
|
| 11 |
<h1 id="id-title" class="h1">Words Frequency Statistics in text</h1>
|
| 12 |
<div id="id-orientation-message" class="id-orientation-message" aria-hidden="true"><!-- ::before (Mobile users: use this project in landscape mode!) --></div>
|
| 13 |
<div class="margin10px">
|
|
@@ -60,9 +60,9 @@
|
|
| 60 |
<legend>Order:</legend>
|
| 61 |
<div>
|
| 62 |
<input type="radio" id="order-by-asc" aria-label="order-by-asc" name="order" value="asc" />
|
| 63 |
-
<label for="order-by-asc" id="order-by-asc-label" aria-label="order-by-asc-label">
|
| 64 |
<input type="radio" id="order-by-desc" aria-label="order-by-desc" name="order" value="desc" checked/>
|
| 65 |
-
<label for="order-by-desc" id="order-by-desc-label" aria-label="order-by-desc-label">
|
| 66 |
</div>
|
| 67 |
</fieldset>
|
| 68 |
</form>
|
|
@@ -71,7 +71,10 @@
|
|
| 71 |
<span id="id-n-total-rows" aria-label="id-n-total-rows" class="display-none"></span>
|
| 72 |
<span id="waiting-for-be" class="display-none">waiting for backend response...</span>
|
| 73 |
<span id="waiting-for-be-error" class="display-none">Error!</span>
|
| 74 |
-
<div id="words-frequency" class="max-height-80vh overflow-
|
|
|
|
|
|
|
|
|
|
| 75 |
</div>
|
| 76 |
|
| 77 |
</div>
|
|
|
|
| 7 |
<link rel="stylesheet" href="/static/index.css">
|
| 8 |
<script src="/static/index.js"></script>
|
| 9 |
</head>
|
| 10 |
+
<body class="overflow-hidden">
|
| 11 |
<h1 id="id-title" class="h1">Words Frequency Statistics in text</h1>
|
| 12 |
<div id="id-orientation-message" class="id-orientation-message" aria-hidden="true"><!-- ::before (Mobile users: use this project in landscape mode!) --></div>
|
| 13 |
<div class="margin10px">
|
|
|
|
| 60 |
<legend>Order:</legend>
|
| 61 |
<div>
|
| 62 |
<input type="radio" id="order-by-asc" aria-label="order-by-asc" name="order" value="asc" />
|
| 63 |
+
<label for="order-by-asc" id="order-by-asc-label" aria-label="order-by-asc-label">Ascend</label>
|
| 64 |
<input type="radio" id="order-by-desc" aria-label="order-by-desc" name="order" value="desc" checked/>
|
| 65 |
+
<label for="order-by-desc" id="order-by-desc-label" aria-label="order-by-desc-label">Descend</label>
|
| 66 |
</div>
|
| 67 |
</fieldset>
|
| 68 |
</form>
|
|
|
|
| 71 |
<span id="id-n-total-rows" aria-label="id-n-total-rows" class="display-none"></span>
|
| 72 |
<span id="waiting-for-be" class="display-none">waiting for backend response...</span>
|
| 73 |
<span id="waiting-for-be-error" class="display-none">Error!</span>
|
| 74 |
+
<div id="words-frequency" class="max-height-80vh overflow-hidden background-color-whitesmoke display-flex" aria-label="words-frequency">
|
| 75 |
+
<div id="id-list-of-words" class="margin10px overflow-auto" aria-label="id-list-of-words"></div>
|
| 76 |
+
<div id="id-current-table-of-words" class="margin10px overflow-auto" aria-label="id-current-table-of-words"></div>
|
| 77 |
+
</div>
|
| 78 |
</div>
|
| 79 |
|
| 80 |
</div>
|
static/index.js
CHANGED
|
@@ -7,6 +7,8 @@ const editorFieldLabel = "editor"
|
|
| 7 |
const remoteWebServer = "http://localhost:7860"
|
| 8 |
const underlinedPrimary = "underlinedBlue"
|
| 9 |
const underlinedClicked = "underlinedDarkViolet"
|
|
|
|
|
|
|
| 10 |
|
| 11 |
/**
|
| 12 |
* Object containing functions for word frequency analysis.
|
|
@@ -32,7 +34,7 @@ const wordsFrequencyAnalyzers = {
|
|
| 32 |
})
|
| 33 |
console.assert(response.status === 200, `response.status: ${response.status}!`)
|
| 34 |
let bodyResponseJson = await response.json()
|
| 35 |
-
|
| 36 |
let freq = bodyResponseJson["words_frequency"]
|
| 37 |
let nTotalRows = bodyResponseJson["n_total_rows"]
|
| 38 |
console.log(`getWordsFreq::nTotalRows: '${nTotalRows}'`)
|
|
@@ -40,8 +42,8 @@ const wordsFrequencyAnalyzers = {
|
|
| 40 |
} catch (err) {
|
| 41 |
console.error("getWordsFrequency::err on webserver request/response:", err, "#")
|
| 42 |
console.log(`wordsFrequencyURL:`, typeof wordsFrequency, "=>", wordsFrequencyURL, "#")
|
| 43 |
-
|
| 44 |
-
|
| 45 |
}
|
| 46 |
},
|
| 47 |
/**
|
|
@@ -54,15 +56,15 @@ const wordsFrequencyAnalyzers = {
|
|
| 54 |
console.log("use the embedded functionality for word freq analysis...")
|
| 55 |
try {
|
| 56 |
const bodyResponseJson = textStemming(inputText)
|
| 57 |
-
|
| 58 |
let freq = bodyResponseJson["wordsStemsDict"]
|
| 59 |
let nTotalRows = bodyResponseJson["nTotalRows"]
|
| 60 |
console.log(`getWordsFreq::nTotalRows: '${nTotalRows}', populateWordsFrequencyTables...`)
|
| 61 |
populateWordsFrequencyTables(freq, nTotalRows)
|
| 62 |
} catch (err) {
|
| 63 |
console.error("getWordsFrequency::err on useWordfreqWebserver:", err, "#")
|
| 64 |
-
|
| 65 |
-
|
| 66 |
}
|
| 67 |
}
|
| 68 |
}
|
|
@@ -470,9 +472,18 @@ function setCaret(line, offsetColumn, nTotalRows, negativeOffsetPerc=0.12) {
|
|
| 470 |
* @param {string} elementId - The ID of the HTML element to update.
|
| 471 |
* @param {string} currentClass - The new CSS class to apply to the element.
|
| 472 |
*/
|
| 473 |
-
|
| 474 |
-
let
|
| 475 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 476 |
}
|
| 477 |
|
| 478 |
function parseWebserverDomain () {
|
|
@@ -494,12 +505,14 @@ async function getWordsFrequency() {
|
|
| 494 |
let text = document.getElementById(editorFieldLabel)
|
| 495 |
// replace repeated newlines to prepare setCaret() use
|
| 496 |
text.innerText = text.innerText.replace(/[\r\n]+/g, '\n')
|
| 497 |
-
|
| 498 |
-
|
| 499 |
let wordsFrequencyTableTitleEl = document.getElementById("id-words-frequency-table-title")
|
| 500 |
wordsFrequencyTableTitleEl.innerText = wordsFrequencyTableTitleText
|
| 501 |
-
let
|
| 502 |
-
|
|
|
|
|
|
|
| 503 |
const choiceWordFreqAnalyzerEl = document.getElementById('id-input-webserver-wordfreq-checkbox')
|
| 504 |
console.log("choiceWordFreqAnalyzerEl checked:", choiceWordFreqAnalyzerEl.checked, "#")
|
| 505 |
switch (choiceWordFreqAnalyzerEl.checked) {
|
|
@@ -589,13 +602,18 @@ async function updateWordsFrequencyTables() {
|
|
| 589 |
reduced = arrayFilter(reduced, "word_prefix", inputFilterValue)
|
| 590 |
}
|
| 591 |
|
| 592 |
-
let
|
| 593 |
-
|
|
|
|
|
|
|
|
|
|
| 594 |
let wordsFrequencyTableTitleEl = document.getElementById("id-words-frequency-table-title")
|
| 595 |
wordsFrequencyTableTitleEl.innerText = `${wordsFrequencyTableTitleText} (${reduced.length} word groups, ${nTotalRows} rows)`
|
|
|
|
| 596 |
for (let i=0; i<reduced.length; i++ ) {
|
| 597 |
-
|
| 598 |
}
|
|
|
|
| 599 |
}
|
| 600 |
|
| 601 |
/**
|
|
@@ -619,9 +637,9 @@ function populateWordsFrequencyTables(wordsFrequencyObj, nTotalRows) {
|
|
| 619 |
* @param {number} i - The current index being processed (needed for adding unique HTML id/aria-labels).
|
| 620 |
* @param {object} iReduced - An object containing the reduced data for the current index, including word prefix, count, and offsets array.
|
| 621 |
* @param {number} nTotalRows - The total number of lines/rows in the table.
|
| 622 |
-
* @param {object}
|
| 623 |
*/
|
| 624 |
-
function insertCurrentTable(i, iReduced, nTotalRows,
|
| 625 |
let currentTableWordsFreq = document.createElement("table")
|
| 626 |
currentTableWordsFreq.setAttribute("class", "border-black")
|
| 627 |
currentTableWordsFreq.setAttribute("id", `id-table-${i}-nth`)
|
|
@@ -644,7 +662,25 @@ function insertCurrentTable(i, iReduced, nTotalRows, wordsFrequency) {
|
|
| 644 |
}
|
| 645 |
currentTableWordsFreq.appendChild(currentTHead)
|
| 646 |
currentTableWordsFreq.appendChild(currentTBody)
|
| 647 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 648 |
}
|
| 649 |
|
| 650 |
/**
|
|
@@ -666,13 +702,8 @@ function insertCellIntoTRow(currentTBody, i, ii, nthOffset, nTotalRows) {
|
|
| 666 |
let nRow = nthOffset["n_row"]
|
| 667 |
let offsetWord = nthOffset["offsets"]
|
| 668 |
setCaret(nRow, offsetWord, nTotalRows)
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
oldClassElement[0].className = underlinedPrimary
|
| 672 |
-
} catch {
|
| 673 |
-
console.log("first click...")
|
| 674 |
-
}
|
| 675 |
-
currentUrl.className = underlinedClicked
|
| 676 |
})
|
| 677 |
currentUrl.className = underlinedPrimary
|
| 678 |
currentUrl.innerText = nthOffset["word"]
|
|
|
|
| 7 |
const remoteWebServer = "http://localhost:7860"
|
| 8 |
const underlinedPrimary = "underlinedBlue"
|
| 9 |
const underlinedClicked = "underlinedDarkViolet"
|
| 10 |
+
const underlinedPrimaryTable = "underlinedBlueTable"
|
| 11 |
+
const underlinedClickedTable = "underlinedDarkVioletTable"
|
| 12 |
|
| 13 |
/**
|
| 14 |
* Object containing functions for word frequency analysis.
|
|
|
|
| 34 |
})
|
| 35 |
console.assert(response.status === 200, `response.status: ${response.status}!`)
|
| 36 |
let bodyResponseJson = await response.json()
|
| 37 |
+
setElementCssClassById("waiting-for-be", "display-none")
|
| 38 |
let freq = bodyResponseJson["words_frequency"]
|
| 39 |
let nTotalRows = bodyResponseJson["n_total_rows"]
|
| 40 |
console.log(`getWordsFreq::nTotalRows: '${nTotalRows}'`)
|
|
|
|
| 42 |
} catch (err) {
|
| 43 |
console.error("getWordsFrequency::err on webserver request/response:", err, "#")
|
| 44 |
console.log(`wordsFrequencyURL:`, typeof wordsFrequency, "=>", wordsFrequencyURL, "#")
|
| 45 |
+
setElementCssClassById("waiting-for-be", "display-none")
|
| 46 |
+
setElementCssClassById("waiting-for-be-error", "display-block")
|
| 47 |
}
|
| 48 |
},
|
| 49 |
/**
|
|
|
|
| 56 |
console.log("use the embedded functionality for word freq analysis...")
|
| 57 |
try {
|
| 58 |
const bodyResponseJson = textStemming(inputText)
|
| 59 |
+
setElementCssClassById("waiting-for-be", "display-none")
|
| 60 |
let freq = bodyResponseJson["wordsStemsDict"]
|
| 61 |
let nTotalRows = bodyResponseJson["nTotalRows"]
|
| 62 |
console.log(`getWordsFreq::nTotalRows: '${nTotalRows}', populateWordsFrequencyTables...`)
|
| 63 |
populateWordsFrequencyTables(freq, nTotalRows)
|
| 64 |
} catch (err) {
|
| 65 |
console.error("getWordsFrequency::err on useWordfreqWebserver:", err, "#")
|
| 66 |
+
setElementCssClassById("waiting-for-be", "display-none")
|
| 67 |
+
setElementCssClassById("waiting-for-be-error", "display-block")
|
| 68 |
}
|
| 69 |
}
|
| 70 |
}
|
|
|
|
| 472 |
* @param {string} elementId - The ID of the HTML element to update.
|
| 473 |
* @param {string} currentClass - The new CSS class to apply to the element.
|
| 474 |
*/
|
| 475 |
+
function setElementCssClassById(elementId, currentClass) {
|
| 476 |
+
let elementWithClassToChange = document.getElementById(elementId)
|
| 477 |
+
elementWithClassToChange.setAttribute("class", currentClass)
|
| 478 |
+
}
|
| 479 |
+
|
| 480 |
+
function setElementCssClassByOldClass(oldClassName, currentClass) {
|
| 481 |
+
try {
|
| 482 |
+
let oldClassElement = document.getElementsByClassName(oldClassName)
|
| 483 |
+
oldClassElement[0].className = currentClass
|
| 484 |
+
} catch {
|
| 485 |
+
console.log("not found...")
|
| 486 |
+
}
|
| 487 |
}
|
| 488 |
|
| 489 |
function parseWebserverDomain () {
|
|
|
|
| 505 |
let text = document.getElementById(editorFieldLabel)
|
| 506 |
// replace repeated newlines to prepare setCaret() use
|
| 507 |
text.innerText = text.innerText.replace(/[\r\n]+/g, '\n')
|
| 508 |
+
setElementCssClassById("waiting-for-be-error", "display-none")
|
| 509 |
+
setElementCssClassById("waiting-for-be", "display-block")
|
| 510 |
let wordsFrequencyTableTitleEl = document.getElementById("id-words-frequency-table-title")
|
| 511 |
wordsFrequencyTableTitleEl.innerText = wordsFrequencyTableTitleText
|
| 512 |
+
let listOfWords = document.getElementById("id-list-of-words")
|
| 513 |
+
listOfWords.innerHTML = ""
|
| 514 |
+
let currentTableOfWords = document.getElementById("id-current-table-of-words")
|
| 515 |
+
currentTableOfWords.innerHTML = ""
|
| 516 |
const choiceWordFreqAnalyzerEl = document.getElementById('id-input-webserver-wordfreq-checkbox')
|
| 517 |
console.log("choiceWordFreqAnalyzerEl checked:", choiceWordFreqAnalyzerEl.checked, "#")
|
| 518 |
switch (choiceWordFreqAnalyzerEl.checked) {
|
|
|
|
| 602 |
reduced = arrayFilter(reduced, "word_prefix", inputFilterValue)
|
| 603 |
}
|
| 604 |
|
| 605 |
+
let listOfWords = document.getElementById("id-list-of-words")
|
| 606 |
+
listOfWords.innerHTML = ""
|
| 607 |
+
let currentTableOfWords = document.getElementById("id-current-table-of-words")
|
| 608 |
+
currentTableOfWords.innerHTML = ""
|
| 609 |
+
|
| 610 |
let wordsFrequencyTableTitleEl = document.getElementById("id-words-frequency-table-title")
|
| 611 |
wordsFrequencyTableTitleEl.innerText = `${wordsFrequencyTableTitleText} (${reduced.length} word groups, ${nTotalRows} rows)`
|
| 612 |
+
const wordListElement = document.createElement("list")
|
| 613 |
for (let i=0; i<reduced.length; i++ ) {
|
| 614 |
+
insertListOfWords(i, reduced[i], nTotalRows, wordListElement, currentTableOfWords);
|
| 615 |
}
|
| 616 |
+
listOfWords.append(wordListElement)
|
| 617 |
}
|
| 618 |
|
| 619 |
/**
|
|
|
|
| 637 |
* @param {number} i - The current index being processed (needed for adding unique HTML id/aria-labels).
|
| 638 |
* @param {object} iReduced - An object containing the reduced data for the current index, including word prefix, count, and offsets array.
|
| 639 |
* @param {number} nTotalRows - The total number of lines/rows in the table.
|
| 640 |
+
* @param {object} currentTableOfWords - A container element to hold the current table representing chosen word positions.
|
| 641 |
*/
|
| 642 |
+
function insertCurrentTable(i, iReduced, nTotalRows, currentTableOfWords) {
|
| 643 |
let currentTableWordsFreq = document.createElement("table")
|
| 644 |
currentTableWordsFreq.setAttribute("class", "border-black")
|
| 645 |
currentTableWordsFreq.setAttribute("id", `id-table-${i}-nth`)
|
|
|
|
| 662 |
}
|
| 663 |
currentTableWordsFreq.appendChild(currentTHead)
|
| 664 |
currentTableWordsFreq.appendChild(currentTBody)
|
| 665 |
+
currentTableOfWords.appendChild(currentTableWordsFreq)
|
| 666 |
+
}
|
| 667 |
+
|
| 668 |
+
function insertListOfWords(i, iReduced, nTotalRows, wordListElement, currentTableOfWords) {
|
| 669 |
+
const li = document.createElement("li");
|
| 670 |
+
const a = document.createElement("a")
|
| 671 |
+
a.innerText = `${iReduced["word_prefix"]}: ${iReduced["count"]} repetitions`
|
| 672 |
+
a.addEventListener("click", function() {
|
| 673 |
+
let currentTableOfWords = document.getElementById("id-current-table-of-words")
|
| 674 |
+
console.log("currentTableOfWords:", currentTableOfWords.innerText, "#")
|
| 675 |
+
currentTableOfWords.innerHTML = ""
|
| 676 |
+
console.log("a::", `${iReduced["word_prefix"]}: ${iReduced["count"]} repetitions`, "#")
|
| 677 |
+
insertCurrentTable(i, iReduced, nTotalRows, currentTableOfWords)
|
| 678 |
+
setElementCssClassByOldClass(underlinedClicked, underlinedPrimary)
|
| 679 |
+
a.className = underlinedClicked
|
| 680 |
+
});
|
| 681 |
+
a.className = underlinedPrimary
|
| 682 |
+
li.appendChild(a);
|
| 683 |
+
wordListElement.appendChild(li);
|
| 684 |
}
|
| 685 |
|
| 686 |
/**
|
|
|
|
| 702 |
let nRow = nthOffset["n_row"]
|
| 703 |
let offsetWord = nthOffset["offsets"]
|
| 704 |
setCaret(nRow, offsetWord, nTotalRows)
|
| 705 |
+
setElementCssClassByOldClass(underlinedClickedTable, underlinedPrimaryTable)
|
| 706 |
+
currentUrl.className = underlinedClickedTable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 707 |
})
|
| 708 |
currentUrl.className = underlinedPrimary
|
| 709 |
currentUrl.innerText = nthOffset["word"]
|