import ScheduleSendIcon from '@mui/icons-material/ScheduleSend'; import { Backdrop, // Import Backdrop component Box, Button, CircularProgress, // Import CircularProgress component Container, FormControl, InputLabel, MenuItem, Paper, Select, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, RadioGroup, Radio, FormControlLabel, FormLabel, Alert } from "@mui/material"; import { styled } from "@mui/material/styles"; import Papa from "papaparse"; import React, { useContext, useState, useCallback } from "react"; import { TopicsContext } from "./UploadFileContext"; const VisuallyHiddenInput = styled("input")({ clip: "rect(0 0 0 0)", clipPath: "inset(50%)", height: 1, overflow: "hidden", position: "absolute", bottom: 0, left: 0, whiteSpace: "nowrap", width: 1, }); function QueryView() { const [fileData, setFileData] = useState([]); const [selectedColumn, setSelectedColumn] = useState(""); const [selectedFile, setSelectedFile] = useState(null); const [selectedColumnData, setSelectedColumnData] = useState([]); const [openSelector, setOpenSelector] = React.useState(false); const [xLeftWord, setXLeftWord] = useState("past"); const [xRightWord, setXRightWord] = useState("future"); const [yTopWord, setYTopWord] = useState("positive"); const [yBottomWord, setYBottomWord] = useState("negative"); const [radiusSize, setRadiusSize] = useState(0.5); const [nClusters, setNClusters] = useState(15); const [minCountTerms, setMinCountTerms] = useState(1); const [nameLength, setNameLength] = useState(3); const [cleanTopics, setCleanTopics] = useState(false); const [language, setLanguage] = useState("english"); const { uploadFile, isLoading, selectedView, refreshBourdieuQuery } = useContext(TopicsContext); const [fileDataTooLong, setFileDataTooLong] = useState(false); const [fileDataError, setFileDataError] = useState(null); /** * Column name selector handler */ const handleClose = () => { setOpenSelector(false); }; const handleOpen = () => { setOpenSelector(true); }; /** * Parse the CSV and take a sample to display the preview * @param {*} file * @param {*} sampleSize * @returns */ const parseCSVFile = (file, sampleSize = 100) => new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { const csvData = e.target.result; const lines = csvData.split("\n"); setFileDataTooLong(lines.length > 10000); // Take a sample of the first 500 lines to display preview const sampleLines = lines.slice(0, sampleSize).join("\n"); Papa.parse(sampleLines, { complete: (result) => { resolve(result.data); }, error: (parseError) => { reject(parseError.message); }, }); }; reader.readAsText(file); }); /** * Handler the file selection ui workflow * @param {Event} e * @returns */ const handleFileChange = async (e) => { const file = e.target.files[0]; setSelectedFile(file); if (!file) return; // prepare data for the preview Table try { const parsedData = await parseCSVFile(file); setFileData(parsedData); setSelectedColumn(""); // Clear the selected column when a new file is uploaded if (fileDataTooLong === false) { handleOpen(); } else { handleClose(); } } catch (exc) { setFileDataError("Error parsing the CSV file, please check your file before uploading"); console.error("Error parsing CSV:", exc); } }; const handleColumnSelect = (e) => { const columnName = e.target.value; setSelectedColumn(columnName); // Extract the content of the selected column const columnIndex = fileData[0].indexOf(columnName); const columnData = fileData.slice(1).map((row) => row[columnIndex]); setSelectedColumnData(columnData); }; /** * Launch the upload and processing */ const handleProcessTopics = async () => { // Return if no column selected if (selectedColumnData.length === 0) return; if (selectedFile && !isLoading) { uploadFile(selectedFile, { nClusters, selectedColumn, selectedView, xLeftWord, xRightWord, yTopWord, yBottomWord, radiusSize, nameLength, minCountTerms, language, cleanTopics }); } }; const handleRefreshQuery = useCallback(async () => { if (!isLoading) { await refreshBourdieuQuery({ topic_param: { n_clusters: nClusters, name_lenght: nameLength, min_count_terms: minCountTerms, language: language, clean_topics: cleanTopics }, bourdieu_query: { x_left_words: xLeftWord.split(","), x_right_words: xRightWord.split(","), y_top_words: yTopWord.split(","), y_bottom_words: yBottomWord.split(","), radius_size: radiusSize, } }); } }); const openTableContainer = selectedColumnData.length > 0 && fileData.length > 0 && fileData.length <= 10000 && fileDataTooLong === false && fileDataError == null; return ( {selectedView === "map" && ( <> Select a Column )} {isLoading ? ( ) : ( // Content when not loading
{openTableContainer && ( {selectedColumn} {selectedColumnData.map((cell, index) => ( {cell} ))}
)} {fileDataTooLong && ( CSV must have less than 10 000 lines (this is a demo) )} {fileDataError && ( CSV must have less than 10 000 lines (this is a demo) )} {selectedView === "bourdieu" && ( setXLeftWord(e.target.value)} value={xLeftWord} /> setXRightWord(e.target.value)} value={xRightWord} /> setYTopWord(e.target.value)} value={yTopWord} /> setYBottomWord(e.target.value)} value={yBottomWord} /> setRadiusSize(e.target.value)} value={radiusSize} /> setNClusters(e.target.value)} value={nClusters} /> setNameLength(e.target.value)} value={nameLength} /> setMinCountTerms(e.target.value)} value={minCountTerms} /> setCleanTopics(e.target.value)} variant="outlined" sx={{ marginBottom: "1em" }} disabled> Clean Topics } disabled /> } disabled /> )} {selectedView === "map" && ( setNClusters(e.target.value)} value={nClusters} /> setNameLength(e.target.value)} value={nameLength} /> setMinCountTerms(e.target.value)} value={minCountTerms} /> setCleanTopics(e.target.value)} variant="outlined" sx={{ marginBottom: "1em" }} disabled> Clean Topics } disabled /> } disabled /> setLanguage(e.target.value)} variant="outlined" sx={{ marginBottom: "1em" }}> Language } /> } /> )}
)}
); } export default QueryView;