pvanand commited on
Commit
8cb8223
·
verified ·
1 Parent(s): 643f187

Create graph-maker.html

Browse files
Files changed (1) hide show
  1. static/graph-maker.html +215 -0
static/graph-maker.html ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Interactive Chart Maker with LLM</title>
8
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
10
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.4/vue.global.min.js"></script>
11
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.4/axios.min.js"></script>
12
+ <style>
13
+ body {
14
+ padding-top: 2rem;
15
+ background-color: #f8f9fa;
16
+ }
17
+ .card {
18
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
19
+ }
20
+ #mermaid-output {
21
+ min-height: 200px;
22
+ width: 100%;
23
+ margin: 1rem auto;
24
+ position: relative;
25
+ background-color: white;
26
+ }
27
+ .loading-overlay {
28
+ position: absolute;
29
+ top: 0;
30
+ left: 0;
31
+ right: 0;
32
+ bottom: 0;
33
+ background-color: rgba(255, 255, 255, 0.7);
34
+ display: flex;
35
+ justify-content: center;
36
+ align-items: center;
37
+ z-index: 1000;
38
+ }
39
+ .code-toggle {
40
+ font-size: 0.9rem;
41
+ padding: 0.25rem 0.5rem;
42
+ margin-bottom: 0.5rem;
43
+ }
44
+ .code-toggle::after {
45
+ content: " ▼";
46
+ font-size: 0.8em;
47
+ transition: transform 0.2s;
48
+ display: inline-block;
49
+ margin-left: 0.25rem;
50
+ }
51
+ .code-toggle.collapsed::after {
52
+ transform: rotate(-90deg);
53
+ }
54
+ @media (max-width: 768px) {
55
+ .input-group {
56
+ flex-direction: column;
57
+ }
58
+ .input-group > * {
59
+ margin-bottom: 0.5rem;
60
+ width: 100%;
61
+ }
62
+ }
63
+ </style>
64
+ </head>
65
+ <body>
66
+ <div id="app" class="container">
67
+ <h1 class="mb-4 text-center">Interactive Chart Maker</h1>
68
+ <div class="row justify-content-center">
69
+ <div class="col-lg-10 col-md-12">
70
+ <div class="card mb-4">
71
+ <div class="card-body">
72
+ <div class="input-group mb-3">
73
+ <input v-model="chartDescription" :disabled="isInputDisabled" class="form-control" placeholder="Describe the chart you want..." aria-label="Chart description" />
74
+ <button @click="generateChart" :disabled="isInputDisabled" class="btn btn-primary">Generate Chart</button>
75
+ </div>
76
+ <div class="d-flex justify-content-end">
77
+ <button class="btn btn-outline-secondary btn-sm code-toggle collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#codeCollapse" aria-expanded="false" aria-controls="codeCollapse">
78
+ Code
79
+ </button>
80
+ </div>
81
+ <div class="collapse" id="codeCollapse">
82
+ <textarea v-model="mermaidInput" @input="debouncedRenderMermaid" :disabled="isInputDisabled" class="form-control mb-3" rows="6" placeholder="Mermaid syntax will appear here..." aria-label="Mermaid syntax"></textarea>
83
+ </div>
84
+ <div id="mermaid-output" class="border rounded p-3">
85
+ <div v-if="loading" class="loading-overlay" aria-busy="true">
86
+ <div class="spinner-border text-primary" role="status">
87
+ <span class="visually-hidden">Loading...</span>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ <div v-if="error" class="alert alert-danger mt-3" role="alert">{{ error }}</div>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </div>
96
+ </div>
97
+
98
+ <script type="module">
99
+ import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
100
+
101
+ const defaultConfig = {
102
+ startOnLoad: true,
103
+ securityLevel: 'strict',
104
+ flowchart: { useMaxWidth: false },
105
+ gantt: { useMaxWidth: false },
106
+ theme: 'default'
107
+ };
108
+
109
+ mermaid.initialize(defaultConfig);
110
+
111
+ const { createApp, ref, watch } = Vue;
112
+
113
+ function debounce(func, wait) {
114
+ let timeout;
115
+ return function executedFunction(...args) {
116
+ const later = () => {
117
+ clearTimeout(timeout);
118
+ func(...args);
119
+ };
120
+ clearTimeout(timeout);
121
+ timeout = setTimeout(later, wait);
122
+ };
123
+ }
124
+
125
+ createApp({
126
+ setup() {
127
+ const chartDescription = ref('');
128
+ const mermaidInput = ref('');
129
+ const error = ref('');
130
+ const loading = ref(false);
131
+ const isInputDisabled = ref(false);
132
+
133
+ const API_ENDPOINT = 'https://pvanand-audio-chat.hf.space/llm-agent';
134
+ const API_KEY = '44d5c2ac18ced6fc25c1e57dcd06fc0b31fb4ad97bf56e67540671a647465df4';
135
+
136
+ const cleanMermaidSyntax = (input) => {
137
+ let cleaned = input.trim();
138
+ cleaned = cleaned.replace(/^```mermaid\n?|```$/gm, '');
139
+ if (!cleaned.match(/^(graph|flowchart|sequenceDiagram|classDiagram|stateDiagram|erDiagram|journey|gantt|pie|requirementDiagram)/)) {
140
+ cleaned = 'graph TD\n' + cleaned;
141
+ }
142
+ return cleaned;
143
+ };
144
+
145
+ const generateChart = async () => {
146
+ if (!chartDescription.value.trim()) {
147
+ error.value = 'Please enter a chart description.';
148
+ return;
149
+ }
150
+
151
+ loading.value = true;
152
+ error.value = '';
153
+ mermaidInput.value = '';
154
+ isInputDisabled.value = true;
155
+
156
+ try {
157
+ const response = await axios.post(API_ENDPOINT, {
158
+ prompt: `Generate Mermaid syntax for the following chart description: ${chartDescription.value}`,
159
+ system_message: "You are a helpful assistant that generates Mermaid syntax for charts. Respond only with the Mermaid syntax, no additional text.",
160
+ model_id: "anthropic/claude-3.5-sonnet",
161
+ conversation_id: "string",
162
+ user_id: "string"
163
+ }, {
164
+ headers: {
165
+ 'accept': 'application/json',
166
+ 'X-API-Key': API_KEY,
167
+ 'Content-Type': 'application/json'
168
+ }
169
+ });
170
+
171
+ mermaidInput.value = cleanMermaidSyntax(response.data);
172
+ } catch (err) {
173
+ error.value = 'Error generating chart. Please try again.';
174
+ console.error('API Error:', err.message);
175
+ } finally {
176
+ loading.value = false;
177
+ isInputDisabled.value = false;
178
+ }
179
+ };
180
+
181
+ const renderMermaid = () => {
182
+ const output = document.getElementById('mermaid-output');
183
+ mermaid.render('mermaid-diagram', mermaidInput.value)
184
+ .then(({ svg }) => {
185
+ output.innerHTML = svg;
186
+ error.value = '';
187
+ })
188
+ .catch(err => {
189
+ error.value = 'Error rendering diagram. Please check your Mermaid syntax.';
190
+ console.error('Mermaid Error:', err.message);
191
+ });
192
+ };
193
+
194
+ const debouncedRenderMermaid = debounce(renderMermaid, 300);
195
+
196
+ watch(mermaidInput, (newValue) => {
197
+ if (newValue.trim() !== '') {
198
+ debouncedRenderMermaid();
199
+ }
200
+ });
201
+
202
+ return {
203
+ chartDescription,
204
+ mermaidInput,
205
+ error,
206
+ loading,
207
+ isInputDisabled,
208
+ generateChart,
209
+ debouncedRenderMermaid
210
+ };
211
+ }
212
+ }).mount('#app');
213
+ </script>
214
+ </body>
215
+ </html>