| | <!DOCTYPE html> |
| | <html> |
| |
|
| | <head> |
| | <title>ChatChain Visualizer</title> |
| | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"> |
| | <style> |
| | body { |
| | display: flex; |
| | justify-content: center; |
| | align-items: center; |
| | height: 100vh; |
| | } |
| | |
| | #visualization { |
| | display: flex; |
| | flex-wrap: nowrap; |
| | overflow-x: auto; |
| | max-width: 1800px; |
| | margin: 20px; |
| | } |
| | |
| | .card { |
| | margin-right: 10px; |
| | background-color: #f0f0f0; |
| | display: inline-block; |
| | min-width: 350px; |
| | vertical-align: top; |
| | } |
| | |
| | .card-content { |
| | padding: 10px; |
| | } |
| | </style> |
| | </head> |
| |
|
| | <body> |
| | <div class="container"> |
| | <h2>ChatChain Visualizer</h2> |
| | <p>Select your ChatChainConfig.json to visualize</p> |
| | <input type="file" id="fileInput"> |
| | <div id="visualization"></div> |
| | </div> |
| |
|
| | <script> |
| | document.getElementById('fileInput').addEventListener('change', handleFileSelect, false); |
| | |
| | function handleFileSelect(event) { |
| | const file = event.target.files[0]; |
| | if (!file) return; |
| | |
| | const reader = new FileReader(); |
| | reader.onload = function(event) { |
| | try { |
| | const jsonContent = JSON.parse(event.target.result); |
| | visualizeChain(jsonContent.chain); |
| | } catch (error) { |
| | alert('Error parsing JSON file.'); |
| | } |
| | }; |
| | reader.readAsText(file); |
| | } |
| | |
| | function createCard(element) { |
| | const card = document.createElement('div'); |
| | card.className = 'card'; |
| | |
| | const cardContent = document.createElement('div'); |
| | cardContent.className = 'card-content'; |
| | |
| | |
| | |
| | |
| | if (element.phaseType === "ComposedPhase") { |
| | delete element.Composition; |
| | } |
| | |
| | const phase = document.createElement('span'); |
| | phase.innerHTML = `<strong>PhaseName: </strong>${element.phase || 'No PhaseName'}`; |
| | |
| | |
| | const phaseType = document.createElement('p'); |
| | phaseType.innerHTML = `<strong>PhaseType: </strong>${element.phaseType || 'No phaseType'}`; |
| | |
| | |
| | delete element.phase; |
| | delete element.phaseType; |
| | const jsonContent = document.createElement('pre'); |
| | jsonContent.innerText = JSON.stringify(element, null, 2); |
| | |
| | cardContent.appendChild(phase); |
| | cardContent.appendChild(phaseType); |
| | cardContent.appendChild(jsonContent); |
| | |
| | card.appendChild(cardContent); |
| | |
| | return card; |
| | } |
| | |
| | function visualizeChain(chain) { |
| | const visualization = document.getElementById('visualization'); |
| | visualization.innerHTML = ''; |
| | |
| | chain.forEach(element => { |
| | if (element.phaseType === "ComposedPhase") { |
| | const composition = element.Composition || []; |
| | const card = createCard(element); |
| | |
| | const nestedCards = composition.map(composedElement => { |
| | return createCard(composedElement); |
| | }); |
| | |
| | const nestedCardWrapper = document.createElement('div'); |
| | nestedCardWrapper.style.marginTop = '10px'; |
| | |
| | nestedCards.forEach(nestedCard => { |
| | nestedCardWrapper.appendChild(nestedCard); |
| | }); |
| | |
| | card.appendChild(nestedCardWrapper); |
| | visualization.appendChild(card); |
| | } else { |
| | const card = createCard(element); |
| | visualization.appendChild(card); |
| | } |
| | }); |
| | } |
| | </script> |
| | </body> |
| |
|
| | </html> |