Spaces:
Running
Running
add
Browse files- static/script.js +224 -159
static/script.js
CHANGED
@@ -444,12 +444,12 @@ function loadResumerPage() {
|
|
444 |
const resultElement = document.getElementById("translateResult");
|
445 |
|
446 |
if (!fileInput.files[0]) {
|
447 |
-
resultElement.innerText = "Veuillez sélectionner un fichier";
|
448 |
return;
|
449 |
}
|
450 |
|
451 |
if (!targetLang) {
|
452 |
-
resultElement.innerText = "Veuillez sélectionner une langue";
|
453 |
return;
|
454 |
}
|
455 |
|
@@ -458,7 +458,7 @@ function loadResumerPage() {
|
|
458 |
formData.append("target_lang", targetLang);
|
459 |
|
460 |
try {
|
461 |
-
resultElement.innerText = "Traduction en cours
|
462 |
const response = await fetch("/translate/", {
|
463 |
method: "POST",
|
464 |
body: formData,
|
@@ -482,7 +482,7 @@ function loadResumerPage() {
|
|
482 |
}
|
483 |
} catch (error) {
|
484 |
console.error("Erreur:", error);
|
485 |
-
resultElement.innerText = "
|
486 |
}
|
487 |
}
|
488 |
|
@@ -683,173 +683,238 @@ askBtn.addEventListener('click', async () => {
|
|
683 |
}
|
684 |
|
685 |
//quand on clique sur visualisation ----------------------
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
// 2. Création de la structure HTML
|
691 |
-
const appContainer = document.createElement("div");
|
692 |
-
appContainer.className = "app-container";
|
693 |
-
appContainer.innerHTML = `
|
694 |
-
<div class="sidebar">
|
695 |
-
<div class="logo-container">
|
696 |
-
<div class="logo-top">SMARTDOCS</div>
|
697 |
-
<div class="logo-bottom">AI</div>
|
698 |
-
</div>
|
699 |
-
|
700 |
-
<div class="menu-section">
|
701 |
-
<button class="menu-btn" id="resumerButton">RESUME</button>
|
702 |
-
<button class="menu-btn" id="traductionbutton">TRANSLATE</button>
|
703 |
-
<button class="menu-btn" id="qesdocButton">QUESTION</button>
|
704 |
-
</div>
|
705 |
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
|
|
|
|
|
|
711 |
</div>
|
712 |
-
|
713 |
-
|
714 |
-
<
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
<
|
730 |
-
<
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
<option value="barplot">Diagramme en barres</option>
|
736 |
-
<option value="boxplot">Boîte à moustaches</option>
|
737 |
-
</select>
|
738 |
-
<button type="button" id="generateGraphBtn" class="visualiser">Générer</button>
|
739 |
-
</div>
|
740 |
</div>
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
<
|
746 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
747 |
</div>
|
748 |
</div>
|
749 |
</div>
|
750 |
</div>
|
751 |
-
|
752 |
-
|
753 |
-
// 3. Nettoyage et insertion
|
754 |
-
document.body.innerHTML = "";
|
755 |
-
document.body.appendChild(appContainer);
|
756 |
-
|
757 |
-
// 4. Gestion des événements
|
758 |
-
const setupEventListeners = () => {
|
759 |
-
// Navigation
|
760 |
-
document.getElementById('resumerButton').addEventListener('click', loadResumerPage);
|
761 |
-
document.getElementById('traductionbutton').addEventListener('click', loadTraductionPage);
|
762 |
-
document.getElementById('qesdocButton').addEventListener('click', loadDocPage);
|
763 |
-
document.getElementById('interpretationButton').addEventListener('click', loadInterpretationPage);
|
764 |
-
document.getElementById('qesimgButton').addEventListener('click', loadImagePage);
|
765 |
-
|
766 |
-
// Gestion des fichiers
|
767 |
-
const fileInput = document.getElementById('graphFileInput');
|
768 |
-
const dropText = document.getElementById('dropText');
|
769 |
-
const uploadIcon = document.getElementById('uploadIcon');
|
770 |
-
|
771 |
-
dropText.addEventListener('click', (e) => {
|
772 |
-
e.preventDefault();
|
773 |
-
fileInput.click();
|
774 |
-
});
|
775 |
-
|
776 |
-
uploadIcon.addEventListener('click', (e) => {
|
777 |
-
e.preventDefault();
|
778 |
-
fileInput.click();
|
779 |
-
});
|
780 |
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
786 |
});
|
787 |
-
|
788 |
-
//
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
// 5. Fonction de génération du graphique
|
793 |
-
const generateGraph = async () => {
|
794 |
-
const fileInput = document.getElementById('graphFileInput');
|
795 |
-
const graphTypeSelect = document.getElementById('graphTypeSelect');
|
796 |
-
const resultImage = document.getElementById('graphResultImage');
|
797 |
-
const placeholderText = document.getElementById('graphPlaceholderText');
|
798 |
-
|
799 |
-
// Validation
|
800 |
-
if (!fileInput.files[0]) {
|
801 |
-
placeholderText.textContent = "Veuillez sélectionner un fichier";
|
802 |
-
return;
|
803 |
}
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
}
|
809 |
-
|
810 |
-
//
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
formData.append("query", graphTypeSelect.value);
|
819 |
-
|
820 |
-
const response = await fetch("http://localhost:8000/generate_viz/", {
|
821 |
-
method: "POST",
|
822 |
-
body: formData,
|
823 |
-
headers: { 'Accept': 'image/*' }
|
824 |
-
});
|
825 |
-
|
826 |
-
// Vérification
|
827 |
-
if (!response.ok) {
|
828 |
-
throw new Error(`Erreur ${response.status}: ${await response.text()}`);
|
829 |
-
}
|
830 |
-
|
831 |
-
const contentType = response.headers.get('Content-Type');
|
832 |
-
if (!contentType?.includes('image')) {
|
833 |
-
throw new Error("Réponse non reconnue comme image");
|
834 |
-
}
|
835 |
-
|
836 |
-
// Affichage
|
837 |
-
const imageBlob = await response.blob();
|
838 |
-
resultImage.onload = () => URL.revokeObjectURL(resultImage.src);
|
839 |
-
resultImage.src = URL.createObjectURL(imageBlob);
|
840 |
-
resultImage.style.display = "block";
|
841 |
placeholderText.textContent = "";
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
853 |
|
854 |
|
855 |
|
|
|
444 |
const resultElement = document.getElementById("translateResult");
|
445 |
|
446 |
if (!fileInput.files[0]) {
|
447 |
+
resultElement.innerText = "⚠️Veuillez sélectionner un fichier";
|
448 |
return;
|
449 |
}
|
450 |
|
451 |
if (!targetLang) {
|
452 |
+
resultElement.innerText = "⚠️Veuillez sélectionner une langue";
|
453 |
return;
|
454 |
}
|
455 |
|
|
|
458 |
formData.append("target_lang", targetLang);
|
459 |
|
460 |
try {
|
461 |
+
resultElement.innerText = "Traduction en cours...🕐";
|
462 |
const response = await fetch("/translate/", {
|
463 |
method: "POST",
|
464 |
body: formData,
|
|
|
482 |
}
|
483 |
} catch (error) {
|
484 |
console.error("Erreur:", error);
|
485 |
+
resultElement.innerText = "⚠️Échec de la traduction: " + error.message;
|
486 |
}
|
487 |
}
|
488 |
|
|
|
683 |
}
|
684 |
|
685 |
//quand on clique sur visualisation ----------------------
|
686 |
+
function loadVisualisationPage() {
|
687 |
+
// 1. Configuration de l'arrière-plan
|
688 |
+
document.body.style.setProperty('--background-image', "url('visualisation.webp')");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
689 |
|
690 |
+
// 2. Création de la structure HTML
|
691 |
+
const appContainer = document.createElement("div");
|
692 |
+
appContainer.className = "app-container";
|
693 |
+
appContainer.innerHTML = `
|
694 |
+
<div class="sidebar">
|
695 |
+
<div class="logo-container">
|
696 |
+
<div class="logo-top">SMARTDOCS</div>
|
697 |
+
<div class="logo-bottom">AI</div>
|
698 |
</div>
|
699 |
+
<div class="menu-section">
|
700 |
+
<button class="menu-btn" id="resumerButton">RESUME</button>
|
701 |
+
<button class="menu-btn" id="traductionbutton">TRANSLATE</button>
|
702 |
+
<button class="menu-btn" id="qesdocButton">QUESTION</button>
|
703 |
+
</div>
|
704 |
+
<div class="menu-section">
|
705 |
+
<div class="menu-title">IMAGES</div>
|
706 |
+
<button class="menu-btn" id="interpretationButton">INTERPRETER</button>
|
707 |
+
<button class="menu-btn" id="qesimgButton">QUESTIONS</button>
|
708 |
+
</div>
|
709 |
+
</div>
|
710 |
+
<div class="main-content-area">
|
711 |
+
<div class="document-container">
|
712 |
+
<h1 class="document-main-title">Opérations sur documents</h1>
|
713 |
+
<h2 class="document-subtitle">VISUALISATION</h2>
|
714 |
+
<div class="upload-container">
|
715 |
+
<div class="file-drop-zone" id="fileDropZone">
|
716 |
+
<label for="graphFileInput" class="file-upload-label">
|
717 |
+
<img src="up.png" id="uploadIcon" class="upload-icon" alt="Upload">
|
718 |
+
<span class="drop-text" id="dropText">Déposez votre fichier ici ou cliquez pour parcourir</span>
|
719 |
+
</label>
|
720 |
+
<input type="file" id="graphFileInput" class="file-input"
|
721 |
+
accept=".doc,.docx,.xls,.xlsx,.pdf,.ppt,.pptx" hidden>
|
|
|
|
|
|
|
|
|
|
|
722 |
</div>
|
723 |
+
|
724 |
+
<div class="graph-action-container">
|
725 |
+
<select id="graphTypeSelect" class="language-dropdown">
|
726 |
+
<option value="">Select type</option>
|
727 |
+
<option value="histplot">Histogramme</option>
|
728 |
+
<option value="scatterplot">Nuage de points</option>
|
729 |
+
<option value="lineplot">Courbe</option>
|
730 |
+
<option value="barplot">Diagramme en barres</option>
|
731 |
+
<option value="boxplot">Boîte à moustaches</option>
|
732 |
+
</select>
|
733 |
+
<button type="button" id="generateGraphBtn" class="graph-generate-btn">Générer</button>
|
734 |
+
</div>
|
735 |
+
</div>
|
736 |
+
<div class="graph-results-container">
|
737 |
+
<div class="graph-results-placeholder">
|
738 |
+
<img id="graphResultImage" class="graph-result-img">
|
739 |
+
<p class="placeholder-text" id="graphPlaceholderText">Le résultat apparaîtra ici...</p>
|
740 |
+
</div>
|
741 |
+
<div id="downloadSection" style="display: none; margin-top: 20px; text-align: center;">
|
742 |
+
<h3 style="color: white; margin-bottom: 10px;">Télécharger le graphique</h3>
|
743 |
+
<div style="display: flex; justify-content: center; gap: 10px;">
|
744 |
+
<button id="downloadPng" class="download-btn">PNG</button>
|
745 |
+
<button id="downloadJpg" class="download-btn">JPG</button>
|
746 |
</div>
|
747 |
</div>
|
748 |
</div>
|
749 |
</div>
|
750 |
+
</div>
|
751 |
+
`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
752 |
|
753 |
+
// 3. Nettoyage et insertion
|
754 |
+
document.body.innerHTML = "";
|
755 |
+
document.body.appendChild(appContainer);
|
756 |
+
|
757 |
+
// 4. Gestion des événements
|
758 |
+
const setupEventListeners = () => {
|
759 |
+
// Navigation
|
760 |
+
document.getElementById('resumerButton').addEventListener('click', loadResumerPage);
|
761 |
+
document.getElementById('traductionbutton').addEventListener('click', loadTraductionPage);
|
762 |
+
document.getElementById('qesdocButton').addEventListener('click', loadDocPage);
|
763 |
+
document.getElementById('interpretationButton').addEventListener('click', loadInterpretationPage);
|
764 |
+
document.getElementById('qesimgButton').addEventListener('click', loadImagePage);
|
765 |
+
|
766 |
+
// Gestion des fichiers
|
767 |
+
const fileInput = document.getElementById('graphFileInput');
|
768 |
+
const dropText = document.getElementById('dropText');
|
769 |
+
const uploadIcon = document.getElementById('uploadIcon');
|
770 |
+
|
771 |
+
dropText.addEventListener('click', (e) => {
|
772 |
+
e.preventDefault();
|
773 |
+
fileInput.click();
|
774 |
+
});
|
775 |
+
|
776 |
+
uploadIcon.addEventListener('click', (e) => {
|
777 |
+
e.preventDefault();
|
778 |
+
fileInput.click();
|
779 |
+
});
|
780 |
+
|
781 |
+
fileInput.addEventListener('change', (e) => {
|
782 |
+
if (e.target.files[0]) {
|
783 |
+
dropText.textContent = e.target.files[0].name;
|
784 |
+
uploadIcon.style.display = "none";
|
785 |
+
// Réinitialiser l'affichage quand un nouveau fichier est sélectionné
|
786 |
+
document.getElementById("downloadSection").style.display = "none";
|
787 |
+
document.getElementById("graphResultImage").style.display = "none";
|
788 |
+
document.getElementById("graphPlaceholderText").textContent = "Prêt à générer le graphique";
|
789 |
+
}
|
790 |
+
});
|
791 |
+
|
792 |
+
// Génération du graphique
|
793 |
+
document.getElementById('generateGraphBtn').addEventListener('click', generateGraph);
|
794 |
+
|
795 |
+
// Téléchargement du graphique
|
796 |
+
document.getElementById('downloadPng').addEventListener('click', () => downloadGraph('png'));
|
797 |
+
document.getElementById('downloadJpg').addEventListener('click', () => downloadGraph('jpg'));
|
798 |
+
};
|
799 |
+
|
800 |
+
// 5. Fonction de génération du graphique
|
801 |
+
const generateGraph = async () => {
|
802 |
+
const fileInput = document.getElementById('graphFileInput');
|
803 |
+
const graphTypeSelect = document.getElementById('graphTypeSelect');
|
804 |
+
const resultImage = document.getElementById('graphResultImage');
|
805 |
+
const placeholderText = document.getElementById('graphPlaceholderText');
|
806 |
+
const downloadSection = document.getElementById("downloadSection");
|
807 |
+
|
808 |
+
// Validation
|
809 |
+
if (!fileInput.files[0]) {
|
810 |
+
placeholderText.textContent = "⚠️Veuillez sélectionner un fichier";
|
811 |
+
downloadSection.style.display = "none";
|
812 |
+
return;
|
813 |
+
}
|
814 |
+
|
815 |
+
if (!graphTypeSelect.value) {
|
816 |
+
placeholderText.textContent = "⚠️Veuillez sélectionner un type de graphique";
|
817 |
+
downloadSection.style.display = "none";
|
818 |
+
return;
|
819 |
+
}
|
820 |
+
|
821 |
+
// Préparation de l'interface
|
822 |
+
resultImage.style.display = "none";
|
823 |
+
downloadSection.style.display = "none";
|
824 |
+
placeholderText.textContent = "Génération du graphique en cours...🕐";
|
825 |
+
|
826 |
+
try {
|
827 |
+
// Envoi des données
|
828 |
+
const formData = new FormData();
|
829 |
+
formData.append("file", fileInput.files[0]);
|
830 |
+
formData.append("query", graphTypeSelect.value);
|
831 |
+
|
832 |
+
const response = await fetch("http://localhost:8000/generate_viz/", {
|
833 |
+
method: "POST",
|
834 |
+
body: formData,
|
835 |
+
headers: { 'Accept': 'image/*' }
|
836 |
});
|
837 |
+
|
838 |
+
// Vérification
|
839 |
+
if (!response.ok) {
|
840 |
+
throw new Error(`Erreur ${response.status}: ${await response.text()}`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
841 |
}
|
842 |
+
|
843 |
+
const contentType = response.headers.get('Content-Type');
|
844 |
+
if (!contentType?.includes('image')) {
|
845 |
+
throw new Error("Réponse non reconnue comme image");
|
846 |
}
|
847 |
+
|
848 |
+
// Affichage du résultat
|
849 |
+
const imageBlob = await response.blob();
|
850 |
+
const imageUrl = URL.createObjectURL(imageBlob);
|
851 |
+
|
852 |
+
resultImage.onload = () => {
|
853 |
+
URL.revokeObjectURL(imageUrl);
|
854 |
+
// Afficher les options de téléchargement une fois l'image chargée
|
855 |
+
document.getElementById("downloadSection").style.display = "block";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
856 |
placeholderText.textContent = "";
|
857 |
+
};
|
858 |
+
|
859 |
+
resultImage.src = imageUrl;
|
860 |
+
resultImage.style.display = "block";
|
861 |
+
|
862 |
+
} catch (error) {
|
863 |
+
console.error("Erreur:", error);
|
864 |
+
placeholderText.textContent = `Erreur: ${error.message}`;
|
865 |
+
resultImage.style.display = "none";
|
866 |
+
downloadSection.style.display = "none";
|
867 |
+
}
|
868 |
+
};
|
869 |
+
|
870 |
+
// 6. Fonction de téléchargement du graphique
|
871 |
+
const downloadGraph = (format) => {
|
872 |
+
const resultImage = document.getElementById('graphResultImage');
|
873 |
+
if (!resultImage.src || resultImage.style.display === "none") {
|
874 |
+
alert("⚠️Veuillez d'abord générer un graphique");
|
875 |
+
return;
|
876 |
+
}
|
877 |
+
|
878 |
+
// Créer un canvas pour la conversion
|
879 |
+
const canvas = document.createElement('canvas');
|
880 |
+
const ctx = canvas.getContext('2d');
|
881 |
+
canvas.width = resultImage.naturalWidth;
|
882 |
+
canvas.height = resultImage.naturalHeight;
|
883 |
+
ctx.drawImage(resultImage, 0, 0);
|
884 |
+
|
885 |
+
let mimeType, extension;
|
886 |
+
switch(format) {
|
887 |
+
case 'jpg':
|
888 |
+
mimeType = 'image/jpeg';
|
889 |
+
extension = 'jpg';
|
890 |
+
break;
|
891 |
+
|
892 |
+
default: // PNG par défaut
|
893 |
+
mimeType = 'image/png';
|
894 |
+
extension = 'png';
|
895 |
+
}
|
896 |
+
|
897 |
+
// Conversion et téléchargement
|
898 |
+
canvas.toBlob((blob) => {
|
899 |
+
downloadFile(blob, `graphique.${extension}`);
|
900 |
+
}, mimeType, format === 'jpg' ? 0.92 : 1); // Qualité à 92% pour JPG, 100% pour PNG
|
901 |
+
};
|
902 |
+
|
903 |
+
// 7. Fonction utilitaire pour le téléchargement
|
904 |
+
const downloadFile = (blob, filename) => {
|
905 |
+
const url = URL.createObjectURL(blob);
|
906 |
+
const a = document.createElement('a');
|
907 |
+
a.href = url;
|
908 |
+
a.download = filename;
|
909 |
+
document.body.appendChild(a);
|
910 |
+
a.click();
|
911 |
+
document.body.removeChild(a);
|
912 |
+
setTimeout(() => URL.revokeObjectURL(url), 100);
|
913 |
+
};
|
914 |
+
|
915 |
+
// Initialisation
|
916 |
+
setupEventListeners();
|
917 |
+
}
|
918 |
|
919 |
|
920 |
|