From 92d3f5a57c8d5476cd4a1f2ea3a05f72fc70b088 Mon Sep 17 00:00:00 2001 From: pverkind Date: Thu, 3 Apr 2025 10:39:52 +0200 Subject: [PATCH 1/7] capitalization --- src/components/DiffViewer/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DiffViewer/index.js b/src/components/DiffViewer/index.js index 75e16ad..1fad3ae 100644 --- a/src/components/DiffViewer/index.js +++ b/src/components/DiffViewer/index.js @@ -43,7 +43,7 @@ const DiffViewerComponent = () => { alignItems={"center"} mb={"20px"} > - Diff viewer + Diff Viewer View code on{" "} Date: Wed, 23 Jul 2025 00:39:51 +0100 Subject: [PATCH 2/7] Add download options panel --- src/App.js | 15 +- src/components/Visualisation/Chart/index.jsx | 5 - .../SectionHeader/SectionHeaderLayout.js | 23 ++- .../VisualizationHeader/DownloadPanel.js | 180 ++++++++++++++++++ .../{ => VisualizationHeader}/FlipButton.js | 2 +- .../TickFontSizeControl.js | 2 +- .../index.js} | 26 +-- 7 files changed, 226 insertions(+), 27 deletions(-) create mode 100644 src/components/Visualisation/SectionHeader/VisualizationHeader/DownloadPanel.js rename src/components/Visualisation/SectionHeader/{ => VisualizationHeader}/FlipButton.js (96%) rename src/components/Visualisation/SectionHeader/{ => VisualizationHeader}/TickFontSizeControl.js (98%) rename src/components/Visualisation/SectionHeader/{VisualizationHeader.js => VisualizationHeader/index.js} (77%) diff --git a/src/App.js b/src/App.js index 332a766..dcc86cc 100644 --- a/src/App.js +++ b/src/App.js @@ -136,6 +136,8 @@ function App() { const [isFileUploaded, setIsFileUploaded] = useState(false); const [showTickSizeInput, setShowTickSizeInput] = useState(false); const [tickFontSize, setTickFontSize] = useState(12); + const [outputImageWidth, setOutputImageWidth] = useState(120); + const [dpi, setDpi] = useState(300); const [isFlipped, setIsFlipped] = useState(false); const [flipTimeLoading, setFlipTimeLoading] = useState(false); const focusMilestone1 = useRef(); @@ -169,6 +171,8 @@ function App() { const [showWikiEdDiff, setWikiEdDiff] = useState(false); const [isError, setIsError] = useState(false); const [showOptions, setShowOptions] = useState(false); + const [showDownloadOptions, setShowDownloadOptions] = useState(false); + const [includeURL, setIncludeURL] = useState(true); const [url, setUrl] = useState(""); const [highlightMode, setHighlightMode] = useState("diff"); const [nSharedChars, setNSharedChars] = useState(50); @@ -256,7 +260,8 @@ function App() { // save the png: saveSvgAsPng.saveSvgAsPng(newSvg, downloadFileName, { - scale: 3, // 300 % + // TODO: set the scale based on the output size and dpi values: + scale: 3, // 300 % backgroundColor: "white", }); }; @@ -319,6 +324,10 @@ function App() { setShowTickSizeInput, tickFontSize, setTickFontSize, + outputImageWidth, + setOutputImageWidth, + dpi, + setDpi, isFlipped, setIsFlipped, flipTimeLoading, @@ -346,6 +355,10 @@ function App() { setIsError, showOptions, setShowOptions, + showDownloadOptions, + setShowDownloadOptions, + includeURL, + setIncludeURL, url, setUrl, highlightMode, diff --git a/src/components/Visualisation/Chart/index.jsx b/src/components/Visualisation/Chart/index.jsx index bc83fa6..ba3cccb 100644 --- a/src/components/Visualisation/Chart/index.jsx +++ b/src/components/Visualisation/Chart/index.jsx @@ -855,11 +855,6 @@ const Visual = (props) => { { - const { showOptions } = useContext(Context); + const { + showOptions, + showDownloadOptions, + isFlipped, + releaseCode, + metaData, + } = useContext(Context); return ( { {item.title === "Books" && showOptions && } + {item.title === "Pairwise Visualization" && showDownloadOptions && } + {item.title === "One-to-Many Visualization" && showDownloadOptions && } ); }; diff --git a/src/components/Visualisation/SectionHeader/VisualizationHeader/DownloadPanel.js b/src/components/Visualisation/SectionHeader/VisualizationHeader/DownloadPanel.js new file mode 100644 index 0000000..3c8ea5d --- /dev/null +++ b/src/components/Visualisation/SectionHeader/VisualizationHeader/DownloadPanel.js @@ -0,0 +1,180 @@ +import React from "react"; +import { useContext, useRef, useEffect } from "react"; +import { Context } from "../../../../App"; +import { Box } from "@mui/material"; +import { Button, TextField, Typography, Tooltip } from "@mui/material"; +import * as d3 from "d3"; +//import TickFontSizeControl from "./TickFontSizeControl"; + + +const DownloadPanel = ( {isPairwiseViz, downloadFileName} ) => { + const { + downloadPNG, + tickFontSize, + setTickFontSize, + outputImageWidth, + setOutputImageWidth, + dpi, + setDpi, + includeURL, + setIncludeURL + } = useContext(Context); + const tickInputRef = useRef(null); + const widthInputRef = useRef(null); + const dpiInputRef = useRef(null); + const svgSelector = isPairwiseViz ? '#svgChart' : '#scatter-chart'; + + const handleInputChange = (e) => { + setTickFontSize(parseInt(e.target.value) || 12); + }; + + const handleWidthInputChange = (e) => { + setOutputImageWidth(parseInt(e.target.value) || 120); + } + + const handleDpiInputChange = (e) => { + setDpi(parseInt(e.target.value) || 300); + } + + const handleIncludeURL = () => { + setIncludeURL((prev) => !prev); + } + + // Apply font size when it changes + useEffect(() => { + // TODO: fix the font size for one-to-many chart! + console.log(`${svgSelector} .tick text`); + d3.selectAll(`${svgSelector} .tick text`).style("font-size", `${tickFontSize}px`); + }, [tickFontSize, svgSelector]); + + const handleDownload = () => { + if (isPairwiseViz) { + downloadPNG(downloadFileName, "svgChart", includeURL); + } else { + downloadPNG(downloadFileName, "scatter-chart", includeURL); + } + }; + console.log("downloadFileName: "+downloadFileName); + console.log("isPairwiseViz: "+isPairwiseViz); + + + return ( + <> + + Download options: + + + Width: + + mm + + + + + Resolution: + + dpi + + + + + Axis labels size: + + px + + + + + + + + + ); +}; + +export default DownloadPanel; diff --git a/src/components/Visualisation/SectionHeader/FlipButton.js b/src/components/Visualisation/SectionHeader/VisualizationHeader/FlipButton.js similarity index 96% rename from src/components/Visualisation/SectionHeader/FlipButton.js rename to src/components/Visualisation/SectionHeader/VisualizationHeader/FlipButton.js index ede08aa..7054b69 100644 --- a/src/components/Visualisation/SectionHeader/FlipButton.js +++ b/src/components/Visualisation/SectionHeader/VisualizationHeader/FlipButton.js @@ -1,6 +1,6 @@ import { Button } from "@mui/material"; import { Tooltip } from "@mui/material"; -import { Context } from "../../../App"; +import { Context } from "../../../../App"; import React, { useContext } from "react"; const FlipButton = () => { diff --git a/src/components/Visualisation/SectionHeader/TickFontSizeControl.js b/src/components/Visualisation/SectionHeader/VisualizationHeader/TickFontSizeControl.js similarity index 98% rename from src/components/Visualisation/SectionHeader/TickFontSizeControl.js rename to src/components/Visualisation/SectionHeader/VisualizationHeader/TickFontSizeControl.js index 31bb8f4..cd86dbc 100644 --- a/src/components/Visualisation/SectionHeader/TickFontSizeControl.js +++ b/src/components/Visualisation/SectionHeader/VisualizationHeader/TickFontSizeControl.js @@ -1,7 +1,7 @@ import { Button } from "@mui/material"; import { TextField, Tooltip, ClickAwayListener } from "@mui/material"; import * as d3 from "d3"; -import { Context } from "../../../App"; +import { Context } from "../../../../App"; import React, { useContext, useEffect, useRef } from "react"; diff --git a/src/components/Visualisation/SectionHeader/VisualizationHeader.js b/src/components/Visualisation/SectionHeader/VisualizationHeader/index.js similarity index 77% rename from src/components/Visualisation/SectionHeader/VisualizationHeader.js rename to src/components/Visualisation/SectionHeader/VisualizationHeader/index.js index 0973605..646a5b5 100644 --- a/src/components/Visualisation/SectionHeader/VisualizationHeader.js +++ b/src/components/Visualisation/SectionHeader/VisualizationHeader/index.js @@ -1,20 +1,13 @@ import { Box, Button, IconButton, Link, Tooltip } from "@mui/material"; import React, { useContext } from "react"; -import { Context } from "../../../App"; +import { Context } from "../../../../App"; import FlipButton from "./FlipButton"; -import TickFontSizeControl from "./TickFontSizeControl"; -import ScatterLegend from "../MultiChart/ScatterLegend"; +import ScatterLegend from "../../MultiChart/ScatterLegend"; -const VisualizationHeader = ({ restoreCanvas, isPairwiseViz, downloadFileName, colorScale, width }) => { - const { downloadPNG } = useContext(Context); - const handleDownload = () => { - if (isPairwiseViz) { - downloadPNG(downloadFileName, "svgChart"); - } else { - downloadPNG(downloadFileName, "scatter-chart"); - } - }; +const VisualizationHeader = ({ restoreCanvas, isPairwiseViz, colorScale, width }) => { + const { showDownloadOptions, setShowDownloadOptions } = useContext(Context); + return ( @@ -26,9 +19,7 @@ const VisualizationHeader = ({ restoreCanvas, isPairwiseViz, downloadFileName, c target="_blank" > {isPairwiseViz ? : ""} - + - {isPairwiseViz ? : ""} From 455a3e82e007adee3b1f81db2ee5ca3cfd0b0ad2 Mon Sep 17 00:00:00 2001 From: Peter Verkinderen Date: Wed, 23 Jul 2025 13:56:52 +0100 Subject: [PATCH 3/7] Add helper functions to extract IDs from URIs and build pairwise csv urls --- src/utility/Helper.js | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/utility/Helper.js b/src/utility/Helper.js index 1a46862..306e683 100644 --- a/src/utility/Helper.js +++ b/src/utility/Helper.js @@ -1,12 +1,48 @@ +import { srtFolders, lightSrtFolders} from "../assets/srtFolders" import { config } from "../config"; const { GITHUB_BASE_URL, GITHUB_BASE_RAW_URL } = config; + + + const pad = (n, width, z) => { z = z || "0"; n = n + ""; return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; }; +const getVersionIDfromURI = (versionURI, includeExt=true) => { + /* eslint-disable no-unused-vars */ + const [author, book, ...version] = versionURI.split("."); + /* eslint-enable no-unused-vars */ + return version.join("."); +} + +const getVersionIDfromURL = (versionURL, includeExt=true) => { + const versionURI = versionURL.split("/").pop(); + return getVersionIDfromURI(versionURI, includeExt); +} + +/** + * build the URL to the pairwise CSV file on the KITAB webserver: + * based on the metadata for both books: + * + * @param {String} releaseCode OpenITI release version code + * @param {Object} b1Data full metadata for book 1 + * @param {Object} b2Data full metadata for book 2 + * @param {Boolean} light Download the light or full text reuse data csv + * + * @returns String (URL of the pairwise CSV file) + */ + const buildPairwiseCsvURL = async (releaseCode, b1Data, b2Data, light=false) => { + // get the IDs (incl. extension) for both books: + const b1ID = getVersionIDfromURL(b1Data.release_version.url, true); + const b2ID = getVersionIDfromURL(b2Data.release_version.url, true); + const baseURL = light ? lightSrtFolders[releaseCode] : srtFolders[releaseCode]; + // build the URL: + return `${baseURL}/${b1ID}/${b1ID}_${b2ID}.csv`; + } + /** * Remove the page parameter from a querystring * @param {Object} searchParams querystring object @@ -319,5 +355,8 @@ export { cleanImech, parseImech, cleanBeforeDiff, - bisectLeft + bisectLeft, + getVersionIDfromURI, + getVersionIDfromURL, + buildPairwiseCsvURL }; From 730759cf2cd901addbf51404d55e5475618a7bd5 Mon Sep 17 00:00:00 2001 From: mabarber92 Date: Wed, 23 Jul 2025 14:04:23 +0100 Subject: [PATCH 4/7] start fixes to NavigationAndStats --- package-lock.json | 18 ++--- .../NavigationAndStats/index.js | 66 ++++++++++++++++++- 2 files changed, 75 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 60e8458..246af98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5143,12 +5143,13 @@ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/react": { - "version": "18.2.48", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.48.tgz", - "integrity": "sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==", + "version": "17.0.87", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.87.tgz", + "integrity": "sha512-wpg9AbtJ6agjA+BKYmhG6dRWEU/2DHYwMzCaBzsz137ft6IyuqZ5fI4ic1DWL4DrI03Zy78IyVE6ucrXl0mu4g==", + "license": "MIT", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", + "@types/scheduler": "^0.16", "csstype": "^3.0.2" } }, @@ -19135,16 +19136,17 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "license": "Apache-2.0", "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=14.17" + "node": ">=4.2.0" } }, "node_modules/unbox-primitive": { diff --git a/src/components/CorpusMetadata/NavigationAndStats/index.js b/src/components/CorpusMetadata/NavigationAndStats/index.js index e49d06e..e255266 100644 --- a/src/components/CorpusMetadata/NavigationAndStats/index.js +++ b/src/components/CorpusMetadata/NavigationAndStats/index.js @@ -11,7 +11,7 @@ import { import { useNavigate } from "react-router-dom"; import { Checkbox } from "@mui/material"; import { useState } from "react"; -import { lightSrtFolders, srtFoldersGitHub } from "../../../assets/srtFolders"; +import { lightSrtFolders, srtFoldersGitHub, srtFolders } from "../../../assets/srtFolders"; import { setInitialValues } from "../../../functions/setInitialValues"; import { getMetadataObject } from "../../../functions/getMetadataObject"; @@ -45,6 +45,37 @@ const NavigationAndStats = () => { const navigate = useNavigate(); const [displaySelected, setDisplaySelected] = useState(false); + // Download the text reuse data from the server - getting the full data file: + const downloadTextReuseData = async () => { + // prepare the metadata for both book versions: + const book1 = checkedBooks[0]; + const book2 = checkedBooks[1]; + + // build the link to the text reuse pair: + const book1Filename = book1?.release_version?.url.split("/").slice(-1)[0]; + const book1Code = book1Filename.split(".").slice(2).join("."); + const book2Filename = book2?.release_version?.url.split("/").slice(-1)[0]; + const book2Code = book2Filename.split(".").slice(2).join("."); + let srtFolder = srtFolders[releaseCode]; + const csvFileName = `${book1Code}_${book2Code}.csv`; + let csvUrl = `${srtFolder}/${book1Code}/${csvFileName}`; + try { + const response = await fetch(csvUrl, { method: 'HEAD' }); + if (response.ok) { + const link = document.createElement("a"); + link.href = csvUrl; + link.download = csvFileName; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } else { + alert("No pairwise file for selected pair."); + } + } catch (error) { + alert("Download failed due to network error."); + } + } + // Load the book visualisation from the checked versions in metadata table: const loadChartFromSelected = async () => { // reset context values: @@ -215,6 +246,7 @@ const NavigationAndStats = () => { Select a second book to visualise pairwise text reuse ) : ( + <> { + + + + + downloadTextReuseData()} + > + {checkedBooks.length < 3 ? ( + + ) : ( + + )} + + + + + + )} {checkedNotification ? ( From 3d8645c62f119aa96d6fa22a92042592a3764525 Mon Sep 17 00:00:00 2001 From: mabarber92 Date: Thu, 24 Jul 2025 09:08:10 +0100 Subject: [PATCH 5/7] added check for pairwise urls on selection, ability to download --- package-lock.json | 5 +- .../NavigationAndStats/DownloadData.js | 2 +- .../NavigationAndStats/index.js | 166 ++++++++++++++---- 3 files changed, 135 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index e1da396..5fdab07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4962,13 +4962,10 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/react": { - "version": "17.0.87", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.87.tgz", - "integrity": "sha512-wpg9AbtJ6agjA+BKYmhG6dRWEU/2DHYwMzCaBzsz137ft6IyuqZ5fI4ic1DWL4DrI03Zy78IyVE6ucrXl0mu4g==", - "license": "MIT", "version": "17.0.60", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.60.tgz", "integrity": "sha512-pCH7bqWIfzHs3D+PDs3O/COCQJka+Kcw3RnO9rFA2zalqoXg7cNjJDh6mZ7oRtY1wmY4LVwDdAbA1F7Z8tv3BQ==", + "license": "MIT", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "^0.16", diff --git a/src/components/CorpusMetadata/NavigationAndStats/DownloadData.js b/src/components/CorpusMetadata/NavigationAndStats/DownloadData.js index 6631b35..b9b2b7a 100644 --- a/src/components/CorpusMetadata/NavigationAndStats/DownloadData.js +++ b/src/components/CorpusMetadata/NavigationAndStats/DownloadData.js @@ -66,7 +66,7 @@ const DownloadData = ({ data, status }) => { > diff --git a/src/components/CorpusMetadata/NavigationAndStats/index.js b/src/components/CorpusMetadata/NavigationAndStats/index.js index e255266..052052f 100644 --- a/src/components/CorpusMetadata/NavigationAndStats/index.js +++ b/src/components/CorpusMetadata/NavigationAndStats/index.js @@ -10,12 +10,14 @@ import { } from "../../../services/TextReuseData"; import { useNavigate } from "react-router-dom"; import { Checkbox } from "@mui/material"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import { lightSrtFolders, srtFoldersGitHub, srtFolders } from "../../../assets/srtFolders"; +import { buildPairwiseCsvURL } from "../../../utility/Helper" import { setInitialValues } from "../../../functions/setInitialValues"; import { getMetadataObject } from "../../../functions/getMetadataObject"; import { setPairwiseVizData } from "../../../functions/setVisualizationData"; +// import { csv } from "d3"; const NavigationAndStats = () => { const { @@ -45,36 +47,97 @@ const NavigationAndStats = () => { const navigate = useNavigate(); const [displaySelected, setDisplaySelected] = useState(false); + // Default the URLs to null - if null, no download or visualisation will be possible (and we can show a message): + const [pairwiseLiteUrl, setPairwiseLiteUrl] = useState(null); + const [pairwiseUrl, setPairwiseUrl] = useState(null); + const [pairwiseFileName, setPairwiseFileName] = useState(null); + + // Check if relevant parts have been loaded before we try to build the URLs and check them + // If the lite url is + const booksReady = + checkedBooks[0]?.release_version?.url && + checkedBooks[1]?.release_version?.url && + releaseCode && + srtFolders[releaseCode]; + + useEffect(() => { + if (!booksReady) return; + const checkSelectedUrls = async () => { + console.log(checkedBooks); + if (checkedBooks.length !== 2) { + // If we have not selected two books, then set these pairwise parameters to null + setPairwiseLiteUrl(null); + setPairwiseUrl(null); + setPairwiseFileName(null); + return; + + } + else { + + const book1 = checkedBooks[0]; + const book2 = checkedBooks[1]; + const book1Filename = book1?.release_version?.url.split("/").slice(-1)[0]; + const book1Code = book1Filename.split(".").slice(2).join("."); + const book2Filename = book2?.release_version?.url.split("/").slice(-1)[0]; + const book2Code = book2Filename.split(".").slice(2).join("."); + + // Create URLs for the selected books - if URL returns a response, then we set the variable + const LiteUrl = await buildPairwiseCsvURL(releaseCode, book1, book2, true); + const fullUrl = await buildPairwiseCsvURL(releaseCode, book1, book2, false); + const csvFileName = `${book1Code}_${book2Code}.csv`; + setPairwiseFileName(csvFileName); + + // Check the URLs - if they are valid then set the state variables + // If the URL is not valid, then set the state variable to null + try { + const responseLite = await fetch(LiteUrl, { method: 'HEAD' }); + if (responseLite.ok) { + setPairwiseLiteUrl(LiteUrl); + } else { + setPairwiseLiteUrl(null); + } + } catch (error) { + + const srtFolder = srtFoldersGitHub[releaseCode]; + const csvUrl = `${srtFolder}/${book1Code}/${csvFileName}`; + const responseGitHub = await fetch(csvUrl, { method: 'HEAD' }); + if (responseGitHub.ok) { + setPairwiseLiteUrl(csvUrl); + } else { + setPairwiseLiteUrl(null); + console.log("No URL found for pairwise Lite data"); + } + }; + try { + const responseFull = await fetch(fullUrl, { method: 'HEAD' }); + if (responseFull.ok) { + setPairwiseUrl(fullUrl); + } else { + setPairwiseUrl(null); + } + } catch (error) { + console.log("No URL found for pairwise Full data"); + setPairwiseUrl(null); + } + } + }; + checkSelectedUrls(); + }, [checkedBooks, releaseCode, booksReady, pairwiseFileName, pairwiseUrl, pairwiseLiteUrl]); + // Download the text reuse data from the server - getting the full data file: - const downloadTextReuseData = async () => { - // prepare the metadata for both book versions: - const book1 = checkedBooks[0]; - const book2 = checkedBooks[1]; + const downloadTextReuseData = async (downloadUrl) => { + + if (downloadUrl !== null) { - // build the link to the text reuse pair: - const book1Filename = book1?.release_version?.url.split("/").slice(-1)[0]; - const book1Code = book1Filename.split(".").slice(2).join("."); - const book2Filename = book2?.release_version?.url.split("/").slice(-1)[0]; - const book2Code = book2Filename.split(".").slice(2).join("."); - let srtFolder = srtFolders[releaseCode]; - const csvFileName = `${book1Code}_${book2Code}.csv`; - let csvUrl = `${srtFolder}/${book1Code}/${csvFileName}`; - try { - const response = await fetch(csvUrl, { method: 'HEAD' }); - if (response.ok) { const link = document.createElement("a"); - link.href = csvUrl; - link.download = csvFileName; + link.href = downloadUrl; + link.download = pairwiseFileName; document.body.appendChild(link); link.click(); document.body.removeChild(link); - } else { - alert("No pairwise file for selected pair."); - } - } catch (error) { - alert("Download failed due to network error."); - } + } } + // Load the book visualisation from the checked versions in metadata table: const loadChartFromSelected = async () => { @@ -104,8 +167,10 @@ const NavigationAndStats = () => { const csvFileName = `${book1Code}_${book2Code}.csv`; let csvUrl = `${srtFolder}/${book1Code}/${csvFileName}`; + console.log("PairwiseLitUrl: ", pairwiseLiteUrl); + // Download the pairwise text reuse data from the KITAB webserver: - let CSVFile = await downloadCsvData(csvUrl); + let CSVFile = await downloadCsvData(pairwiseLiteUrl); setLoadedCsvFile(CSVFile); // if this fails: try to download it from GitHub: @@ -245,6 +310,10 @@ const NavigationAndStats = () => { Select a second book to visualise pairwise text reuse + ) : checkedBooks.length < 3 && pairwiseLiteUrl == null ? ( + + No text reuse data available for selected books + ) : ( <> @@ -280,8 +349,9 @@ const NavigationAndStats = () => { { variant="text" sx={{ fontSize: "15px" }} disabled={checkedBooks.length < 3 ? false : true} - onClick={() => downloadTextReuseData()} + onClick={() => downloadTextReuseData(pairwiseUrl)} > - {checkedBooks.length < 3 ? ( + {checkedBooks.length < 3 && pairwiseUrl !== null ? ( ) : ( - + )} - + + + + downloadTextReuseData(pairwiseLiteUrl)} + > + {checkedBooks.length < 3 && pairwiseLiteUrl !== null ? ( + + ) : ( + + )} + + + + + )} @@ -369,7 +469,7 @@ const NavigationAndStats = () => { {displaySelected && ( {checkedBooks.map((item, i) => ( - + Date: Thu, 24 Jul 2025 09:13:01 +0100 Subject: [PATCH 6/7] updated font awesome to 7.0.0 updated NavigationAndStats icons --- public/index.html | 2 +- src/components/CorpusMetadata/NavigationAndStats/index.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/public/index.html b/public/index.html index 98d4e90..782e8a0 100644 --- a/public/index.html +++ b/public/index.html @@ -25,7 +25,7 @@ />