| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>AI Plotting Chatbot</title> |
| <link href="/static/tailwind.css" rel="stylesheet"> |
| <style> |
| |
| html, body { height: 100%; margin: 0; padding: 0; } |
| body { display: flex; flex-direction: column; justify-content: flex-start; align-items: center; } |
| #chatContainer { max-width: 600px; width: 100%; flex: 1; display: flex; flex-direction: column; overflow-y: auto; margin-bottom: 1rem; } |
| .message { padding: 0.5rem 1rem; border-radius: 12px; margin-bottom: 0.5rem; max-width: 80%; } |
| .userMsg { background-color: #3b82f6; color: white; align-self: flex-end; } |
| .botMsg { background-color: #f3f4f6; color: #111827; align-self: flex-start; } |
| </style> |
| </head> |
| <body class="bg-gray-100 p-4"> |
|
|
| <h1 class="text-2xl font-bold mb-4 text-center">AI Plotting Chatbot</h1> |
|
|
| <div class="w-full max-w-lg flex flex-col items-center mb-4"> |
| <input id="excelFile" type="file" accept=".xlsx" class="w-full mb-2 p-2 border rounded-xl shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-400" /> |
| <div class="flex w-full"> |
| <input id="userQuery" type="text" placeholder="Enter plot request..." class="flex-1 p-2 border rounded-l-xl shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-400" /> |
| <button onclick="sendMessage()" class="bg-blue-600 text-white px-4 rounded-r-xl">➡</button> |
| </div> |
| </div> |
|
|
| <div id="chatContainer" class="w-full max-w-lg bg-white p-4 rounded-xl shadow flex flex-col"> |
| |
| </div> |
|
|
| <div class="w-full max-w-lg bg-white p-4 rounded-xl shadow mt-4"> |
| <h2 class="font-bold mb-2">Plot Output</h2> |
| <img id="plotImg" class="w-full rounded-xl shadow" /> |
| </div> |
|
|
| <div class="w-full max-w-lg bg-white p-4 rounded-xl shadow mt-4 mb-8"> |
| <h2 class="font-bold mb-2">Generated Code & Console</h2> |
| <pre id="consoleOutput" class="overflow-x-auto text-sm"></pre> |
| </div> |
|
|
| <script> |
| const chatContainer = document.getElementById("chatContainer"); |
| |
| function addMessage(content, type="botMsg") { |
| const msg = document.createElement("div"); |
| msg.className = `message ${type}`; |
| msg.textContent = content; |
| chatContainer.appendChild(msg); |
| chatContainer.scrollTop = chatContainer.scrollHeight; |
| } |
| |
| async function sendMessage() { |
| const fileInput = document.getElementById("excelFile"); |
| const queryInput = document.getElementById("userQuery"); |
| |
| if (!fileInput.files.length) { alert("Please upload a file."); return; } |
| if (!queryInput.value.trim()) { return; } |
| |
| |
| addMessage(queryInput.value.trim(), "userMsg"); |
| |
| const formData = new FormData(); |
| formData.append("file", fileInput.files[0]); |
| formData.append("query", queryInput.value.trim()); |
| |
| |
| queryInput.value = ""; |
| |
| |
| const loadingMsg = document.createElement("div"); |
| loadingMsg.className = "message botMsg"; |
| loadingMsg.textContent = "Processing..."; |
| chatContainer.appendChild(loadingMsg); |
| chatContainer.scrollTop = chatContainer.scrollHeight; |
| |
| try { |
| const response = await fetch("/generate_plot_file", { |
| method: "POST", |
| body: formData |
| }); |
| const data = await response.json(); |
| |
| |
| chatContainer.removeChild(loadingMsg); |
| |
| |
| addMessage("Plot generated.", "botMsg"); |
| |
| |
| if(data.success){ |
| document.getElementById("plotImg").src = "data:image/png;base64," + data.plot; |
| } |
| |
| |
| document.getElementById("consoleOutput").textContent = data.code; |
| |
| } catch (err) { |
| chatContainer.removeChild(loadingMsg); |
| addMessage("Error generating plot: " + err.message, "botMsg"); |
| } |
| } |
| |
| |
| window.addEventListener('resize', () => { |
| chatContainer.scrollTop = chatContainer.scrollHeight; |
| }); |
| |
| |
| document.getElementById("userQuery").addEventListener("keypress", function(e) { |
| if (e.key === "Enter") sendMessage(); |
| }); |
| </script> |
|
|
| </body> |
| </html> |
|
|