Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Sankey Flow Wizard</title> | |
| <link rel="stylesheet" href="style.css"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/d3@7"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/d3-sankey@0.12.3/dist/d3-sankey.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| </head> | |
| <body class="bg-gray-100 min-h-screen flex flex-col"> | |
| <!-- Edit Modal --> | |
| <div id="edit-modal" class="fixed inset-0 bg-gray-600 bg-opacity-50 hidden flex items-center justify-center z-50"> | |
| <div class="bg-white rounded-lg p-6 w-96 shadow-xl"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 id="modal-title" class="text-lg font-semibold text-gray-800"></h3> | |
| <button id="close-modal" class="text-gray-500 hover:text-gray-700"> | |
| <i data-feather="x"></i> | |
| </button> | |
| </div> | |
| <div id="modal-content"> | |
| <!-- Node editing form --> | |
| <div id="node-edit-form" class="hidden"> | |
| <div class="mb-4"> | |
| <label class="block text-sm text-gray-600 mb-1">Node Name</label> | |
| <input type="text" id="edit-node-name" class="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| </div> | |
| </div> | |
| <!-- Link editing form --> | |
| <div id="link-edit-form" class="hidden"> | |
| <div class="mb-4"> | |
| <label class="block text-sm text-gray-600 mb-1">Source Node</label> | |
| <select id="edit-link-source" class="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></select> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-sm text-gray-600 mb-1">Target Node</label> | |
| <select id="edit-link-target" class="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></select> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-sm text-gray-600 mb-1">Value</label> | |
| <input type="number" id="edit-link-value" class="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" min="0"> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="flex justify-end space-x-2 mt-6"> | |
| <button id="cancel-edit" class="px-4 py-2 text-gray-600 hover:text-gray-800 rounded-md">Cancel</button> | |
| <button id="save-edit" class="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-md">Save</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Header --> | |
| <div class="bg-white shadow-lg p-4 flex items-center justify-between relative"> | |
| <div class="flex items-center"> | |
| <button id="toggle-sidebar" class="text-gray-600 hover:text-gray-800 p-2 rounded-md mr-4 tooltip-trigger" title="Toggle Sidebar"> | |
| <i data-feather="menu"></i> | |
| </button> | |
| <h1 class="text-xl font-bold text-gray-800">Sankey Flow Wizard</h1> | |
| </div> | |
| <div class="flex items-center space-x-2"> | |
| <button id="import-csv" class="p-2 text-gray-600 hover:text-gray-800 rounded-md tooltip-trigger" title="Import CSV"> | |
| <i data-feather="upload"></i> | |
| </button> | |
| <button id="export-csv" class="p-2 text-gray-600 hover:text-gray-800 rounded-md tooltip-trigger" title="Export CSV"> | |
| <i data-feather="download"></i> | |
| </button> | |
| <button id="center-diagram" class="p-2 text-gray-600 hover:text-gray-800 rounded-md tooltip-trigger" title="Center Diagram"> | |
| <i data-feather="crosshair"></i> | |
| </button> | |
| <div class="relative"> | |
| <button id="settings-btn" class="p-2 text-gray-600 hover:text-gray-800 rounded-md tooltip-trigger" title="Settings"> | |
| <i data-feather="settings"></i> | |
| </button> | |
| <!-- Settings Dropdown Menu --> | |
| <div id="settings-dropdown" class="hidden absolute right-0 mt-2 w-64 bg-white rounded-lg shadow-lg z-50"> | |
| <div class="p-4 space-y-4"> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Text Color</label> | |
| <input type="color" id="text-color" value="#000000" class="w-full h-8"> | |
| </div> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Text Position</label> | |
| <select id="text-position" class="w-full p-2 border rounded-md"> | |
| <option value="default" selected>Default</option> | |
| <option value="left">Left</option> | |
| <option value="right">Right</option> | |
| <option value="top">Top</option> | |
| <option value="bottom">Bottom</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Text Padding (px)</label> | |
| <input type="range" id="text-padding" min="2" max="30" value="6" class="w-full"> | |
| <div class="text-xs text-gray-500 mt-1">Distance between text and node</div> | |
| </div> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Node Width</label> | |
| <input type="range" id="node-width" min="10" max="80" value="40" class="w-full"> | |
| </div> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Link Alpha</label> | |
| <input type="range" id="link-alpha" min="0.1" max="1" step="0.1" value="0.5" class="w-full"> | |
| </div> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Link Color Mode</label> | |
| <select id="link-color-mode" class="w-full p-2 border rounded-md"> | |
| <option value="source">Source Node Color</option> | |
| <option value="target">Target Node Color</option> | |
| <option value="static">Static Color</option> | |
| </select> | |
| </div> | |
| <div id="static-link-color-container" class="hidden"> | |
| <label class="block text-sm text-gray-600 mb-1">Link Static Color</label> | |
| <input type="color" id="static-link-color" value="#93c5fd" class="w-full h-8"> | |
| </div> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Diagram Height</label> | |
| <input type="range" id="diagram-height" min="300" max="800" value="400" class="w-full"> | |
| </div> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Font Size</label> | |
| <select id="font-size" class="w-full p-2 border rounded-md"> | |
| <option value="small">Small</option> | |
| <option value="medium" selected>Medium</option> | |
| <option value="large">Large</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Background Color</label> | |
| <input type="color" id="background-color" value="#f3f4f6" class="w-full h-8"> | |
| </div> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Node Edge Color</label> | |
| <input type="color" id="node-edge-color" value="#000000" class="w-full h-8"> | |
| </div> | |
| <div> | |
| <label class="block text-sm text-gray-600 mb-1">Text Shadow</label> | |
| <select id="text-shadow" class="w-full p-2 border rounded-md"> | |
| <option value="none">None</option> | |
| <option value="light">Light</option> | |
| <option value="medium">Medium</option> | |
| <option value="dark">Dark</option> | |
| </select> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="flex flex-1"> | |
| <!-- Sidebar --> | |
| <div id="sidebar" class="w-80 bg-white shadow-lg flex flex-col transition-all duration-300 ease-in-out"> | |
| <div class="p-2 border-b"> | |
| <h2 class="text-lg font-semibold text-gray-800">Diagram Editor</h2> | |
| </div> | |
| <div class="flex-1 overflow-y-auto p-2 space-y-1"> | |
| <!-- File input for CSV import --> | |
| <input type="file" id="csv-file" accept=".csv" class="hidden"> | |
| <!-- Nodes Management --> | |
| <div class="bg-gray-50 rounded-lg"> | |
| <div class="p-2 border-b"> | |
| <h3 class="font-medium text-gray-700 flex items-center"> | |
| <i data-feather="circle" class="mr-2"></i> Nodes | |
| </h3> | |
| </div> | |
| <div class="p-3"> | |
| <div class="space-y-3"> | |
| <div id="nodes-list" class="max-h-[200px] overflow-y-auto border rounded-md p-2 space-y-2 bg-white"></div> | |
| <div class="flex space-x-2"> | |
| <input type="text" id="node-name" placeholder="Node name" class="flex-1 px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| <button id="add-node" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-md transition">Add</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Links Management --> | |
| <div class="bg-gray-50 p-4 rounded-lg"> | |
| <h3 class="font-medium text-gray-700 mb-3 flex items-center"> | |
| <i data-feather="link" class="mr-2"></i> Links | |
| </h3> | |
| <div class="space-y-3"> | |
| <div class="grid grid-cols-3 gap-2"> | |
| <select id="source-node" class="col-span-1 p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></select> | |
| <select id="target-node" class="col-span-1 p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"></select> | |
| <input type="number" id="link-value" placeholder="Value" min="1" value="1" class="col-span-1 p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| </div> | |
| <div class="flex justify-end"> | |
| <button id="add-link" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-md transition">Add Link</button> | |
| </div> | |
| <div id="links-list" class="max-h-60 overflow-y-auto border rounded-md p-2 space-y-2"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="flex-1 flex flex-col"> | |
| <!-- Diagram Area --> | |
| <div class="flex-1 p-6"> | |
| <div id="diagram-container" class="bg-gray-200 rounded-xl shadow-md h-full overflow-hidden"> | |
| <svg id="sankey-diagram" class="w-full h-full"></svg> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Initialize feather icons --> | |
| <script> | |
| feather.replace(); | |
| </script> | |
| <!-- Main app script --> | |
| <script src="script.js"></script> | |
| </body> | |
| </html> | |