MEDT commited on
Commit
2bc2ec1
·
verified ·
1 Parent(s): 02911e9

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +1221 -19
  3. prompts.txt +1 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Dataviz V2
3
- emoji: 🚀
4
- colorFrom: green
5
- colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: dataviz-v2
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,1221 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>DataViz Dashboard</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .dropzone {
11
+ border: 2px dashed #3b82f6;
12
+ border-radius: 0.5rem;
13
+ transition: all 0.3s ease;
14
+ }
15
+ .dropzone.active {
16
+ border-color: #10b981;
17
+ background-color: #f0fdf4;
18
+ }
19
+ .chart-preview {
20
+ transition: all 0.3s ease;
21
+ }
22
+ .chart-preview:hover {
23
+ transform: scale(1.02);
24
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
25
+ }
26
+ .sidebar {
27
+ transition: all 0.3s ease;
28
+ }
29
+ @media (max-width: 768px) {
30
+ .sidebar {
31
+ transform: translateX(-100%);
32
+ position: absolute;
33
+ z-index: 50;
34
+ height: 100vh;
35
+ }
36
+ .sidebar.open {
37
+ transform: translateX(0);
38
+ }
39
+ }
40
+ .chart-container {
41
+ min-height: 400px;
42
+ background-color: #f8fafc;
43
+ }
44
+ .data-table {
45
+ max-height: 300px;
46
+ overflow-y: auto;
47
+ }
48
+ /* Custom scrollbar */
49
+ ::-webkit-scrollbar {
50
+ width: 8px;
51
+ height: 8px;
52
+ }
53
+ ::-webkit-scrollbar-track {
54
+ background: #f1f1f1;
55
+ }
56
+ ::-webkit-scrollbar-thumb {
57
+ background: #cbd5e1;
58
+ border-radius: 4px;
59
+ }
60
+ ::-webkit-scrollbar-thumb:hover {
61
+ background: #94a3b8;
62
+ }
63
+ </style>
64
+ </head>
65
+ <body class="bg-gray-50 font-sans">
66
+ <div class="flex h-screen overflow-hidden">
67
+ <!-- Mobile menu button -->
68
+ <button id="sidebarToggle" class="md:hidden fixed top-4 left-4 z-50 p-2 rounded-md bg-white shadow-md">
69
+ <i class="fas fa-bars text-blue-500"></i>
70
+ </button>
71
+
72
+ <!-- Sidebar -->
73
+ <div id="sidebar" class="sidebar w-64 bg-white shadow-md flex flex-col">
74
+ <div class="p-4 border-b border-gray-200">
75
+ <h1 class="text-2xl font-bold text-blue-600 flex items-center">
76
+ <i class="fas fa-chart-line mr-2"></i> DataViz
77
+ </h1>
78
+ <p class="text-sm text-gray-500">Interactive Dashboard</p>
79
+ </div>
80
+
81
+ <div class="p-4 space-y-4">
82
+ <div>
83
+ <h3 class="font-medium text-gray-700 mb-2 flex items-center">
84
+ <i class="fas fa-database mr-2 text-blue-500"></i> Data Sources
85
+ </h3>
86
+ <button id="importBtn" class="w-full bg-blue-50 hover:bg-blue-100 text-blue-600 py-2 px-4 rounded-md flex items-center justify-center">
87
+ <i class="fas fa-file-import mr-2"></i> Import Data
88
+ </button>
89
+ <input type="file" id="fileInput" accept=".csv,.xlsx,.xls" class="hidden">
90
+ </div>
91
+
92
+ <div>
93
+ <h3 class="font-medium text-gray-700 mb-2 flex items-center">
94
+ <i class="fas fa-chart-pie mr-2 text-purple-500"></i> Visualization Types
95
+ </h3>
96
+ <div class="space-y-2">
97
+ <button class="viz-type-btn w-full text-left py-2 px-3 rounded-md hover:bg-purple-50 flex items-center" data-type="bar">
98
+ <i class="fas fa-chart-bar mr-2 text-purple-500"></i> Bar Chart
99
+ </button>
100
+ <button class="viz-type-btn w-full text-left py-2 px-3 rounded-md hover:bg-purple-50 flex items-center" data-type="line">
101
+ <i class="fas fa-chart-line mr-2 text-purple-500"></i> Line Chart
102
+ </button>
103
+ <button class="viz-type-btn w-full text-left py-2 px-3 rounded-md hover:bg-purple-50 flex items-center" data-type="pie">
104
+ <i class="fas fa-chart-pie mr-2 text-purple-500"></i> Pie Chart
105
+ </button>
106
+ <button class="viz-type-btn w-full text-left py-2 px-3 rounded-md hover:bg-purple-50 flex items-center" data-type="scatter">
107
+ <i class="fas fa-braille mr-2 text-purple-500"></i> Scatter Plot
108
+ </button>
109
+ <button class="viz-type-btn w-full text-left py-2 px-3 rounded-md hover:bg-purple-50 flex items-center" data-type="flowchart">
110
+ <i class="fas fa-project-diagram mr-2 text-purple-500"></i> Flowchart
111
+ </button>
112
+ <button class="viz-type-btn w-full text-left py-2 px-3 rounded-md hover:bg-purple-50 flex items-center" data-type="mindmap">
113
+ <i class="fas fa-sitemap mr-2 text-purple-500"></i> Mind Map
114
+ </button>
115
+ </div>
116
+ </div>
117
+
118
+ <div>
119
+ <h3 class="font-medium text-gray-700 mb-2 flex items-center">
120
+ <i class="fas fa-magic mr-2 text-green-500"></i> AI Suggestions
121
+ </h3>
122
+ <button id="aiSuggestBtn" class="w-full bg-green-50 hover:bg-green-100 text-green-600 py-2 px-4 rounded-md flex items-center justify-center">
123
+ <i class="fas fa-robot mr-2"></i> Get AI Recommendation
124
+ </button>
125
+ </div>
126
+
127
+ <div>
128
+ <h3 class="font-medium text-gray-700 mb-2 flex items-center">
129
+ <i class="fas fa-tasks mr-2 text-yellow-500"></i> Data Cleaning
130
+ </h3>
131
+ <div class="space-y-2">
132
+ <button class="data-clean-btn w-full text-left py-2 px-3 rounded-md hover:bg-yellow-50 flex items-center" data-action="remove-duplicates">
133
+ <i class="fas fa-backspace mr-2 text-yellow-500"></i> Remove Duplicates
134
+ </button>
135
+ <button class="data-clean-btn w-full text-left py-2 px-3 rounded-md hover:bg-yellow-50 flex items-center" data-action="fill-missing">
136
+ <i class="fas fa-fill-drip mr-2 text-yellow-500"></i> Fill Missing Values
137
+ </button>
138
+ <button class="data-clean-btn w-full text-left py-2 px-3 rounded-md hover:bg-yellow-50 flex items-center" data-action="filter-data">
139
+ <i class="fas fa-filter mr-2 text-yellow-500"></i> Filter Data
140
+ </button>
141
+ </div>
142
+ </div>
143
+
144
+ <div class="pt-4 border-t border-gray-200">
145
+ <h3 class="font-medium text-gray-700 mb-2 flex items-center">
146
+ <i class="fas fa-language mr-2 text-indigo-500"></i> Language
147
+ </h3>
148
+ <select class="w-full p-2 border border-gray-300 rounded-md">
149
+ <option>English</option>
150
+ <option>Spanish</option>
151
+ <option>French</option>
152
+ <option>German</option>
153
+ <option>Chinese</option>
154
+ </select>
155
+ </div>
156
+ </div>
157
+
158
+ <div class="mt-auto p-4 border-t border-gray-200">
159
+ <button id="exportBtn" class="w-full bg-indigo-600 hover:bg-indigo-700 text-white py-2 px-4 rounded-md flex items-center justify-center">
160
+ <i class="fas fa-file-export mr-2"></i> Export Dashboard
161
+ </button>
162
+ </div>
163
+ </div>
164
+
165
+ <!-- Main content -->
166
+ <div class="flex-1 flex flex-col overflow-hidden">
167
+ <!-- Top navigation -->
168
+ <header class="bg-white shadow-sm">
169
+ <div class="px-4 py-3 flex justify-between items-center">
170
+ <div class="flex items-center space-x-4">
171
+ <h2 class="text-xl font-semibold text-gray-800">Dashboard</h2>
172
+ <div class="relative">
173
+ <input type="text" placeholder="Search..." class="pl-8 pr-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
174
+ <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
175
+ </div>
176
+ </div>
177
+ <div class="flex items-center space-x-4">
178
+ <button class="p-2 rounded-full hover:bg-gray-100">
179
+ <i class="fas fa-bell text-gray-600"></i>
180
+ </button>
181
+ <div class="flex items-center space-x-2">
182
+ <div class="w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center text-white font-medium">JD</div>
183
+ <span class="text-sm font-medium">John Doe</span>
184
+ </div>
185
+ </div>
186
+ </div>
187
+ </header>
188
+
189
+ <!-- Dashboard content -->
190
+ <main class="flex-1 overflow-y-auto p-4 bg-gray-50">
191
+ <!-- Data import section -->
192
+ <div id="importSection" class="mb-6 bg-white rounded-lg shadow-md p-6">
193
+ <div class="flex justify-between items-center mb-4">
194
+ <h3 class="text-lg font-medium text-gray-800 flex items-center">
195
+ <i class="fas fa-file-import mr-2 text-blue-500"></i> Import Your Data
196
+ </h3>
197
+ <div class="flex space-x-2">
198
+ <button class="px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-md text-sm">
199
+ <i class="fas fa-question-circle mr-1"></i> Help
200
+ </button>
201
+ <button class="px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-md text-sm">
202
+ <i class="fas fa-history mr-1"></i> Recent Files
203
+ </button>
204
+ </div>
205
+ </div>
206
+
207
+ <div id="dropzone" class="dropzone p-8 text-center cursor-pointer">
208
+ <div class="flex flex-col items-center justify-center">
209
+ <i class="fas fa-cloud-upload-alt text-4xl text-blue-500 mb-3"></i>
210
+ <h4 class="text-lg font-medium text-gray-700">Drag & drop your file here</h4>
211
+ <p class="text-sm text-gray-500 mb-4">or</p>
212
+ <button id="browseFilesBtn" class="bg-blue-600 hover:bg-blue-700 text-white py-2 px-6 rounded-md">
213
+ Browse Files
214
+ </button>
215
+ <p class="text-xs text-gray-500 mt-3">Supported formats: CSV, XLS, XLSX</p>
216
+ </div>
217
+ </div>
218
+ </div>
219
+
220
+ <!-- Data preview section -->
221
+ <div id="dataPreviewSection" class="mb-6 bg-white rounded-lg shadow-md p-6 hidden">
222
+ <div class="flex justify-between items-center mb-4">
223
+ <h3 class="text-lg font-medium text-gray-800 flex items-center">
224
+ <i class="fas fa-table mr-2 text-green-500"></i> Data Preview
225
+ </h3>
226
+ <div class="flex space-x-2">
227
+ <button id="editDataBtn" class="px-3 py-1 bg-blue-50 hover:bg-blue-100 text-blue-600 rounded-md text-sm flex items-center">
228
+ <i class="fas fa-edit mr-1"></i> Edit
229
+ </button>
230
+ <button id="transformDataBtn" class="px-3 py-1 bg-purple-50 hover:bg-purple-100 text-purple-600 rounded-md text-sm flex items-center">
231
+ <i class="fas fa-exchange-alt mr-1"></i> Transform
232
+ </button>
233
+ </div>
234
+ </div>
235
+
236
+ <div class="data-table border border-gray-200 rounded-md overflow-hidden">
237
+ <table class="min-w-full divide-y divide-gray-200">
238
+ <thead class="bg-gray-50">
239
+ <tr id="tableHeaders">
240
+ <!-- Headers will be populated by JavaScript -->
241
+ </tr>
242
+ </thead>
243
+ <tbody class="bg-white divide-y divide-gray-200" id="tableBody">
244
+ <!-- Data will be populated by JavaScript -->
245
+ </tbody>
246
+ </table>
247
+ </div>
248
+ </div>
249
+
250
+ <!-- Visualization workspace -->
251
+ <div id="vizWorkspace" class="bg-white rounded-lg shadow-md p-6 hidden">
252
+ <div class="flex justify-between items-center mb-4">
253
+ <h3 class="text-lg font-medium text-gray-800 flex items-center">
254
+ <i class="fas fa-chart-area mr-2 text-purple-500"></i> Visualization Workspace
255
+ </h3>
256
+ <div class="flex space-x-2">
257
+ <button id="saveVizBtn" class="px-3 py-1 bg-green-50 hover:bg-green-100 text-green-600 rounded-md text-sm flex items-center">
258
+ <i class="fas fa-save mr-1"></i> Save
259
+ </button>
260
+ <button id="resetVizBtn" class="px-3 py-1 bg-red-50 hover:bg-red-100 text-red-600 rounded-md text-sm flex items-center">
261
+ <i class="fas fa-redo mr-1"></i> Reset
262
+ </button>
263
+ </div>
264
+ </div>
265
+
266
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
267
+ <!-- Visualization controls -->
268
+ <div class="lg:col-span-1 bg-gray-50 p-4 rounded-lg">
269
+ <div class="space-y-4">
270
+ <div>
271
+ <label class="block text-sm font-medium text-gray-700 mb-1">Chart Type</label>
272
+ <select id="chartTypeSelect" class="w-full p-2 border border-gray-300 rounded-md">
273
+ <option value="bar">Bar Chart</option>
274
+ <option value="line">Line Chart</option>
275
+ <option value="pie">Pie Chart</option>
276
+ <option value="scatter">Scatter Plot</option>
277
+ <option value="flowchart">Flowchart</option>
278
+ <option value="mindmap">Mind Map</option>
279
+ </select>
280
+ </div>
281
+
282
+ <div>
283
+ <label class="block text-sm font-medium text-gray-700 mb-1">X-Axis</label>
284
+ <select id="xAxisSelect" class="w-full p-2 border border-gray-300 rounded-md">
285
+ <!-- Options will be populated by JavaScript -->
286
+ </select>
287
+ </div>
288
+
289
+ <div>
290
+ <label class="block text-sm font-medium text-gray-700 mb-1">Y-Axis</label>
291
+ <select id="yAxisSelect" class="w-full p-2 border border-gray-300 rounded-md">
292
+ <!-- Options will be populated by JavaScript -->
293
+ </select>
294
+ </div>
295
+
296
+ <div>
297
+ <label class="block text-sm font-medium text-gray-700 mb-1">Color Scheme</label>
298
+ <select id="colorSchemeSelect" class="w-full p-2 border border-gray-300 rounded-md">
299
+ <option value="default">Default</option>
300
+ <option value="rainbow">Rainbow</option>
301
+ <option value="pastel">Pastel</option>
302
+ <option value="warm">Warm</option>
303
+ <option value="cool">Cool</option>
304
+ <option value="monochrome">Monochrome</option>
305
+ </select>
306
+ </div>
307
+
308
+ <div>
309
+ <label class="block text-sm font-medium text-gray-700 mb-1">Chart Title</label>
310
+ <input type="text" id="chartTitleInput" class="w-full p-2 border border-gray-300 rounded-md" placeholder="Enter chart title">
311
+ </div>
312
+
313
+ <div class="pt-2">
314
+ <button id="updateChartBtn" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-md">
315
+ Update Visualization
316
+ </button>
317
+ </div>
318
+ </div>
319
+ </div>
320
+
321
+ <!-- Visualization preview -->
322
+ <div class="lg:col-span-2">
323
+ <div class="chart-container border border-gray-200 rounded-md p-4 flex items-center justify-center">
324
+ <div id="chartPlaceholder" class="text-center text-gray-500">
325
+ <i class="fas fa-chart-bar text-5xl mb-3"></i>
326
+ <p>Select data and chart type to generate visualization</p>
327
+ </div>
328
+ <canvas id="chartCanvas" class="hidden"></canvas>
329
+ <div id="flowchartContainer" class="hidden w-full h-full"></div>
330
+ <div id="mindmapContainer" class="hidden w-full h-full"></div>
331
+ </div>
332
+ </div>
333
+ </div>
334
+ </div>
335
+
336
+ <!-- AI recommendation section -->
337
+ <div id="aiRecommendationSection" class="bg-white rounded-lg shadow-md p-6 hidden">
338
+ <div class="flex justify-between items-center mb-4">
339
+ <h3 class="text-lg font-medium text-gray-800 flex items-center">
340
+ <i class="fas fa-robot mr-2 text-green-500"></i> AI Recommendation
341
+ </h3>
342
+ <button id="applyAiRecommendationBtn" class="px-3 py-1 bg-green-50 hover:bg-green-100 text-green-600 rounded-md text-sm flex items-center">
343
+ <i class="fas fa-check-circle mr-1"></i> Apply Recommendation
344
+ </button>
345
+ </div>
346
+
347
+ <div class="bg-blue-50 p-4 rounded-md">
348
+ <div class="flex items-start">
349
+ <div class="flex-shrink-0 bg-blue-100 p-2 rounded-full">
350
+ <i class="fas fa-lightbulb text-blue-500"></i>
351
+ </div>
352
+ <div class="ml-3">
353
+ <h4 class="text-sm font-medium text-blue-800">Based on your data, we recommend:</h4>
354
+ <p id="aiRecommendationText" class="text-sm text-blue-700 mt-1">
355
+ <!-- AI recommendation will be inserted here -->
356
+ </p>
357
+ </div>
358
+ </div>
359
+ </div>
360
+ </div>
361
+
362
+ <!-- Dashboard templates -->
363
+ <div id="templatesSection" class="mt-6 hidden">
364
+ <div class="flex justify-between items-center mb-4">
365
+ <h3 class="text-lg font-medium text-gray-800 flex items-center">
366
+ <i class="fas fa-clone mr-2 text-indigo-500"></i> Dashboard Templates
367
+ </h3>
368
+ <button class="px-3 py-1 bg-indigo-50 hover:bg-indigo-100 text-indigo-600 rounded-md text-sm flex items-center">
369
+ <i class="fas fa-plus mr-1"></i> New Template
370
+ </button>
371
+ </div>
372
+
373
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
374
+ <div class="template-card bg-white rounded-lg shadow-md overflow-hidden border border-gray-200 hover:border-blue-300 cursor-pointer">
375
+ <div class="h-32 bg-gradient-to-r from-blue-400 to-blue-600 flex items-center justify-center">
376
+ <i class="fas fa-chart-bar text-white text-4xl"></i>
377
+ </div>
378
+ <div class="p-4">
379
+ <h4 class="font-medium text-gray-800">Sales Dashboard</h4>
380
+ <p class="text-sm text-gray-500 mt-1">Track sales performance and trends</p>
381
+ </div>
382
+ </div>
383
+
384
+ <div class="template-card bg-white rounded-lg shadow-md overflow-hidden border border-gray-200 hover:border-blue-300 cursor-pointer">
385
+ <div class="h-32 bg-gradient-to-r from-purple-400 to-purple-600 flex items-center justify-center">
386
+ <i class="fas fa-users text-white text-4xl"></i>
387
+ </div>
388
+ <div class="p-4">
389
+ <h4 class="font-medium text-gray-800">Customer Analytics</h4>
390
+ <p class="text-sm text-gray-500 mt-1">Analyze customer behavior and demographics</p>
391
+ </div>
392
+ </div>
393
+
394
+ <div class="template-card bg-white rounded-lg shadow-md overflow-hidden border border-gray-200 hover:border-blue-300 cursor-pointer">
395
+ <div class="h-32 bg-gradient-to-r from-green-400 to-green-600 flex items-center justify-center">
396
+ <i class="fas fa-project-diagram text-white text-4xl"></i>
397
+ </div>
398
+ <div class="p-4">
399
+ <h4 class="font-medium text-gray-800">Process Flow</h4>
400
+ <p class="text-sm text-gray-500 mt-1">Visualize workflows and processes</p>
401
+ </div>
402
+ </div>
403
+ </div>
404
+ </div>
405
+ </main>
406
+ </div>
407
+ </div>
408
+
409
+ <!-- Modal for data editing -->
410
+ <div id="editDataModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
411
+ <div class="bg-white rounded-lg shadow-xl w-full max-w-4xl max-h-screen overflow-auto">
412
+ <div class="p-4 border-b border-gray-200 flex justify-between items-center">
413
+ <h3 class="text-lg font-medium text-gray-800">Edit Data</h3>
414
+ <button id="closeEditModalBtn" class="text-gray-500 hover:text-gray-700">
415
+ <i class="fas fa-times"></i>
416
+ </button>
417
+ </div>
418
+ <div class="p-4">
419
+ <div class="overflow-x-auto">
420
+ <table class="min-w-full divide-y divide-gray-200">
421
+ <thead class="bg-gray-50">
422
+ <tr id="editTableHeaders">
423
+ <!-- Headers will be populated by JavaScript -->
424
+ </tr>
425
+ </thead>
426
+ <tbody class="bg-white divide-y divide-gray-200" id="editTableBody">
427
+ <!-- Data will be populated by JavaScript -->
428
+ </tbody>
429
+ </table>
430
+ </div>
431
+ </div>
432
+ <div class="p-4 border-t border-gray-200 flex justify-end space-x-3">
433
+ <button id="cancelEditBtn" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50">
434
+ Cancel
435
+ </button>
436
+ <button id="saveEditBtn" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
437
+ Save Changes
438
+ </button>
439
+ </div>
440
+ </div>
441
+ </div>
442
+
443
+ <!-- Modal for export options -->
444
+ <div id="exportModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
445
+ <div class="bg-white rounded-lg shadow-xl w-full max-w-md">
446
+ <div class="p-4 border-b border-gray-200 flex justify-between items-center">
447
+ <h3 class="text-lg font-medium text-gray-800">Export Options</h3>
448
+ <button id="closeExportModalBtn" class="text-gray-500 hover:text-gray-700">
449
+ <i class="fas fa-times"></i>
450
+ </button>
451
+ </div>
452
+ <div class="p-4">
453
+ <div class="space-y-4">
454
+ <div>
455
+ <label class="block text-sm font-medium text-gray-700 mb-2">Export Format</label>
456
+ <div class="grid grid-cols-3 gap-2">
457
+ <button class="export-format-btn p-3 border border-gray-300 rounded-md hover:bg-gray-50 flex flex-col items-center" data-format="png">
458
+ <i class="fas fa-image text-2xl text-blue-500 mb-1"></i>
459
+ <span class="text-xs">PNG</span>
460
+ </button>
461
+ <button class="export-format-btn p-3 border border-gray-300 rounded-md hover:bg-gray-50 flex flex-col items-center" data-format="jpg">
462
+ <i class="fas fa-image text-2xl text-green-500 mb-1"></i>
463
+ <span class="text-xs">JPG</span>
464
+ </button>
465
+ <button class="export-format-btn p-3 border border-gray-300 rounded-md hover:bg-gray-50 flex flex-col items-center" data-format="pdf">
466
+ <i class="fas fa-file-pdf text-2xl text-red-500 mb-1"></i>
467
+ <span class="text-xs">PDF</span>
468
+ </button>
469
+ <button class="export-format-btn p-3 border border-gray-300 rounded-md hover:bg-gray-50 flex flex-col items-center" data-format="svg">
470
+ <i class="fas fa-file-code text-2xl text-purple-500 mb-1"></i>
471
+ <span class="text-xs">SVG</span>
472
+ </button>
473
+ <button class="export-format-btn p-3 border border-gray-300 rounded-md hover:bg-gray-50 flex flex-col items-center" data-format="csv">
474
+ <i class="fas fa-file-csv text-2xl text-yellow-500 mb-1"></i>
475
+ <span class="text-xs">CSV</span>
476
+ </button>
477
+ <button class="export-format-btn p-3 border border-gray-300 rounded-md hover:bg-gray-50 flex flex-col items-center" data-format="json">
478
+ <i class="fas fa-file-code text-2xl text-indigo-500 mb-1"></i>
479
+ <span class="text-xs">JSON</span>
480
+ </button>
481
+ </div>
482
+ </div>
483
+ <div>
484
+ <label class="block text-sm font-medium text-gray-700 mb-1">Quality</label>
485
+ <select class="w-full p-2 border border-gray-300 rounded-md">
486
+ <option>High (300dpi)</option>
487
+ <option>Medium (150dpi)</option>
488
+ <option>Low (72dpi)</option>
489
+ </select>
490
+ </div>
491
+ <div>
492
+ <label class="block text-sm font-medium text-gray-700 mb-1">Size</label>
493
+ <select class="w-full p-2 border border-gray-300 rounded-md">
494
+ <option>Original Size</option>
495
+ <option>A4 (210 × 297mm)</option>
496
+ <option>Letter (216 × 279mm)</option>
497
+ <option>Custom...</option>
498
+ </select>
499
+ </div>
500
+ </div>
501
+ </div>
502
+ <div class="p-4 border-t border-gray-200 flex justify-end space-x-3">
503
+ <button id="cancelExportBtn" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50">
504
+ Cancel
505
+ </button>
506
+ <button id="confirmExportBtn" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
507
+ Export
508
+ </button>
509
+ </div>
510
+ </div>
511
+ </div>
512
+
513
+ <script>
514
+ // Sample data for demonstration
515
+ let sampleData = [
516
+ { id: 1, product: 'Laptop', category: 'Electronics', sales: 1200, profit: 300, region: 'North' },
517
+ { id: 2, product: 'Smartphone', category: 'Electronics', sales: 800, profit: 200, region: 'South' },
518
+ { id: 3, product: 'Desk', category: 'Furniture', sales: 450, profit: 150, region: 'East' },
519
+ { id: 4, product: 'Chair', category: 'Furniture', sales: 250, profit: 75, region: 'West' },
520
+ { id: 5, product: 'Monitor', category: 'Electronics', sales: 350, profit: 100, region: 'North' },
521
+ { id: 6, product: 'Keyboard', category: 'Electronics', sales: 100, profit: 25, region: 'South' },
522
+ { id: 7, product: 'Mouse', category: 'Electronics', sales: 50, profit: 15, region: 'East' },
523
+ { id: 8, product: 'Table', category: 'Furniture', sales: 600, profit: 180, region: 'West' }
524
+ ];
525
+
526
+ // DOM elements
527
+ const sidebar = document.getElementById('sidebar');
528
+ const sidebarToggle = document.getElementById('sidebarToggle');
529
+ const importBtn = document.getElementById('importBtn');
530
+ const browseFilesBtn = document.getElementById('browseFilesBtn');
531
+ const fileInput = document.getElementById('fileInput');
532
+ const dropzone = document.getElementById('dropzone');
533
+ const dataPreviewSection = document.getElementById('dataPreviewSection');
534
+ const vizWorkspace = document.getElementById('vizWorkspace');
535
+ const aiRecommendationSection = document.getElementById('aiRecommendationSection');
536
+ const templatesSection = document.getElementById('templatesSection');
537
+ const tableHeaders = document.getElementById('tableHeaders');
538
+ const tableBody = document.getElementById('tableBody');
539
+ const editDataModal = document.getElementById('editDataModal');
540
+ const closeEditModalBtn = document.getElementById('closeEditModalBtn');
541
+ const editTableHeaders = document.getElementById('editTableHeaders');
542
+ const editTableBody = document.getElementById('editTableBody');
543
+ const cancelEditBtn = document.getElementById('cancelEditBtn');
544
+ const saveEditBtn = document.getElementById('saveEditBtn');
545
+ const exportBtn = document.getElementById('exportBtn');
546
+ const exportModal = document.getElementById('exportModal');
547
+ const closeExportModalBtn = document.getElementById('closeExportModalBtn');
548
+ const cancelExportBtn = document.getElementById('cancelExportBtn');
549
+ const confirmExportBtn = document.getElementById('confirmExportBtn');
550
+ const exportFormatBtns = document.querySelectorAll('.export-format-btn');
551
+ const chartTypeSelect = document.getElementById('chartTypeSelect');
552
+ const xAxisSelect = document.getElementById('xAxisSelect');
553
+ const yAxisSelect = document.getElementById('yAxisSelect');
554
+ const colorSchemeSelect = document.getElementById('colorSchemeSelect');
555
+ const chartTitleInput = document.getElementById('chartTitleInput');
556
+ const updateChartBtn = document.getElementById('updateChartBtn');
557
+ const chartPlaceholder = document.getElementById('chartPlaceholder');
558
+ const chartCanvas = document.getElementById('chartCanvas');
559
+ const flowchartContainer = document.getElementById('flowchartContainer');
560
+ const mindmapContainer = document.getElementById('mindmapContainer');
561
+ const aiSuggestBtn = document.getElementById('aiSuggestBtn');
562
+ const aiRecommendationText = document.getElementById('aiRecommendationText');
563
+ const applyAiRecommendationBtn = document.getElementById('applyAiRecommendationBtn');
564
+ const vizTypeBtns = document.querySelectorAll('.viz-type-btn');
565
+ const dataCleanBtns = document.querySelectorAll('.data-clean-btn');
566
+
567
+ // Current state
568
+ let currentData = [];
569
+ let currentChart = null;
570
+ let currentVizType = 'bar';
571
+
572
+ // Initialize the app
573
+ function init() {
574
+ // Toggle sidebar on mobile
575
+ sidebarToggle.addEventListener('click', () => {
576
+ sidebar.classList.toggle('open');
577
+ });
578
+
579
+ // Import button click
580
+ importBtn.addEventListener('click', () => {
581
+ fileInput.click();
582
+ });
583
+
584
+ // Browse files button
585
+ browseFilesBtn.addEventListener('click', () => {
586
+ fileInput.click();
587
+ });
588
+
589
+ // File input change
590
+ fileInput.addEventListener('change', handleFileSelect);
591
+
592
+ // Drag and drop events
593
+ ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
594
+ dropzone.addEventListener(eventName, preventDefaults, false);
595
+ });
596
+
597
+ ['dragenter', 'dragover'].forEach(eventName => {
598
+ dropzone.addEventListener(eventName, highlight, false);
599
+ });
600
+
601
+ ['dragleave', 'drop'].forEach(eventName => {
602
+ dropzone.addEventListener(eventName, unhighlight, false);
603
+ });
604
+
605
+ dropzone.addEventListener('drop', handleDrop, false);
606
+
607
+ // Visualization type buttons
608
+ vizTypeBtns.forEach(btn => {
609
+ btn.addEventListener('click', () => {
610
+ const type = btn.dataset.type;
611
+ currentVizType = type;
612
+ chartTypeSelect.value = type;
613
+ updateVizControls();
614
+ if (currentData.length > 0) {
615
+ renderVisualization();
616
+ } else {
617
+ alert('Please import data first');
618
+ }
619
+ });
620
+ });
621
+
622
+ // Data cleaning buttons
623
+ dataCleanBtns.forEach(btn => {
624
+ btn.addEventListener('click', () => {
625
+ const action = btn.dataset.action;
626
+ performDataCleaning(action);
627
+ });
628
+ });
629
+
630
+ // Edit data modal
631
+ closeEditModalBtn.addEventListener('click', () => {
632
+ editDataModal.classList.add('hidden');
633
+ });
634
+
635
+ cancelEditBtn.addEventListener('click', () => {
636
+ editDataModal.classList.add('hidden');
637
+ });
638
+
639
+ saveEditBtn.addEventListener('click', () => {
640
+ // In a real app, we would save the edited data
641
+ editDataModal.classList.add('hidden');
642
+ alert('Data changes saved successfully!');
643
+ });
644
+
645
+ // Export modal
646
+ exportBtn.addEventListener('click', () => {
647
+ exportModal.classList.remove('hidden');
648
+ });
649
+
650
+ closeExportModalBtn.addEventListener('click', () => {
651
+ exportModal.classList.add('hidden');
652
+ });
653
+
654
+ cancelExportBtn.addEventListener('click', () => {
655
+ exportModal.classList.add('hidden');
656
+ });
657
+
658
+ confirmExportBtn.addEventListener('click', () => {
659
+ exportModal.classList.add('hidden');
660
+ alert('Export initiated! In a real app, this would download the file.');
661
+ });
662
+
663
+ exportFormatBtns.forEach(btn => {
664
+ btn.addEventListener('click', () => {
665
+ const format = btn.dataset.format;
666
+ alert(`Preparing to export as ${format.toUpperCase()}`);
667
+ });
668
+ });
669
+
670
+ // Chart controls
671
+ chartTypeSelect.addEventListener('change', () => {
672
+ currentVizType = chartTypeSelect.value;
673
+ updateVizControls();
674
+ });
675
+
676
+ updateChartBtn.addEventListener('click', renderVisualization);
677
+
678
+ // AI suggestion
679
+ aiSuggestBtn.addEventListener('click', generateAiRecommendation);
680
+
681
+ applyAiRecommendationBtn.addEventListener('click', applyAiRecommendation);
682
+
683
+ // Load sample data for demo
684
+ loadSampleData();
685
+ }
686
+
687
+ // Load sample data for demonstration
688
+ function loadSampleData() {
689
+ currentData = [...sampleData];
690
+ renderDataPreview();
691
+ dataPreviewSection.classList.remove('hidden');
692
+ vizWorkspace.classList.remove('hidden');
693
+ templatesSection.classList.remove('hidden');
694
+ updateVizControls();
695
+ }
696
+
697
+ // Handle file selection
698
+ function handleFileSelect(e) {
699
+ const files = e.target.files;
700
+ if (files.length > 0) {
701
+ processFile(files[0]);
702
+ }
703
+ }
704
+
705
+ // Handle drop event
706
+ function handleDrop(e) {
707
+ const dt = e.dataTransfer;
708
+ const files = dt.files;
709
+ if (files.length > 0) {
710
+ processFile(files[0]);
711
+ }
712
+ }
713
+
714
+ // Process uploaded file
715
+ function processFile(file) {
716
+ const fileType = file.name.split('.').pop().toLowerCase();
717
+
718
+ if (fileType === 'csv') {
719
+ // In a real app, we would parse the CSV file
720
+ alert(`CSV file "${file.name}" selected. In a real app, we would parse this file.`);
721
+ loadSampleData(); // For demo purposes
722
+ } else if (fileType === 'xlsx' || fileType === 'xls') {
723
+ // In a real app, we would parse the Excel file
724
+ alert(`Excel file "${file.name}" selected. In a real app, we would parse this file.`);
725
+ loadSampleData(); // For demo purposes
726
+ } else {
727
+ alert('Unsupported file type. Please upload a CSV or Excel file.');
728
+ }
729
+ }
730
+
731
+ // Prevent default drag and drop behaviors
732
+ function preventDefaults(e) {
733
+ e.preventDefault();
734
+ e.stopPropagation();
735
+ }
736
+
737
+ // Highlight dropzone
738
+ function highlight() {
739
+ dropzone.classList.add('active');
740
+ }
741
+
742
+ // Unhighlight dropzone
743
+ function unhighlight() {
744
+ dropzone.classList.remove('active');
745
+ }
746
+
747
+ // Render data preview
748
+ function renderDataPreview() {
749
+ if (currentData.length === 0) return;
750
+
751
+ // Clear existing content
752
+ tableHeaders.innerHTML = '';
753
+ tableBody.innerHTML = '';
754
+
755
+ // Get headers from first object
756
+ const headers = Object.keys(currentData[0]);
757
+
758
+ // Create header row
759
+ headers.forEach(header => {
760
+ const th = document.createElement('th');
761
+ th.className = 'px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider';
762
+ th.textContent = header;
763
+ tableHeaders.appendChild(th);
764
+ });
765
+
766
+ // Create data rows (limit to 10 for preview)
767
+ const previewData = currentData.slice(0, 10);
768
+ previewData.forEach(row => {
769
+ const tr = document.createElement('tr');
770
+ headers.forEach(header => {
771
+ const td = document.createElement('td');
772
+ td.className = 'px-6 py-4 whitespace-nowrap text-sm text-gray-500';
773
+ td.textContent = row[header];
774
+ tr.appendChild(td);
775
+ });
776
+ tableBody.appendChild(tr);
777
+ });
778
+ }
779
+
780
+ // Update visualization controls based on current data and type
781
+ function updateVizControls() {
782
+ if (currentData.length === 0) return;
783
+
784
+ // Get headers from first object
785
+ const headers = Object.keys(currentData[0]);
786
+
787
+ // Clear existing options
788
+ xAxisSelect.innerHTML = '';
789
+ yAxisSelect.innerHTML = '';
790
+
791
+ // Add options based on chart type
792
+ if (currentVizType === 'bar' || currentVizType === 'line') {
793
+ headers.forEach(header => {
794
+ xAxisSelect.add(new Option(header, header));
795
+ });
796
+
797
+ // For Y-axis, only include numeric columns
798
+ headers.forEach(header => {
799
+ if (typeof currentData[0][header] === 'number') {
800
+ yAxisSelect.add(new Option(header, header));
801
+ }
802
+ });
803
+
804
+ // Set default selections
805
+ xAxisSelect.value = headers[0];
806
+ yAxisSelect.value = headers.find(h => typeof currentData[0][h] === 'number');
807
+ }
808
+ else if (currentVizType === 'pie') {
809
+ headers.forEach(header => {
810
+ xAxisSelect.add(new Option(header, header));
811
+ });
812
+
813
+ // For pie charts, only include numeric columns for values
814
+ headers.forEach(header => {
815
+ if (typeof currentData[0][header] === 'number') {
816
+ yAxisSelect.add(new Option(header, header));
817
+ }
818
+ });
819
+
820
+ // Set default selections
821
+ xAxisSelect.value = headers[0];
822
+ yAxisSelect.value = headers.find(h => typeof currentData[0][h] === 'number');
823
+ }
824
+ else if (currentVizType === 'scatter') {
825
+ // For scatter plots, both axes should be numeric
826
+ headers.forEach(header => {
827
+ if (typeof currentData[0][header] === 'number') {
828
+ xAxisSelect.add(new Option(header, header));
829
+ yAxisSelect.add(new Option(header, header));
830
+ }
831
+ });
832
+
833
+ // Set default selections
834
+ const numericHeaders = headers.filter(h => typeof currentData[0][h] === 'number');
835
+ xAxisSelect.value = numericHeaders[0];
836
+ yAxisSelect.value = numericHeaders[1] || numericHeaders[0];
837
+ }
838
+ else if (currentVizType === 'flowchart' || currentVizType === 'mindmap') {
839
+ // For diagrams, we need different controls
840
+ // Simplified for this demo
841
+ xAxisSelect.innerHTML = '<option value="nodes">Nodes</option>';
842
+ yAxisSelect.innerHTML = '<option value="connections">Connections</option>';
843
+ }
844
+ }
845
+
846
+ // Render visualization based on current selections
847
+ function renderVisualization() {
848
+ if (currentData.length === 0) return;
849
+
850
+ // Hide all containers first
851
+ chartPlaceholder.classList.add('hidden');
852
+ chartCanvas.classList.add('hidden');
853
+ flowchartContainer.classList.add('hidden');
854
+ mindmapContainer.classList.add('hidden');
855
+
856
+ // Get selected values
857
+ const xAxis = xAxisSelect.value;
858
+ const yAxis = yAxisSelect.value;
859
+ const colorScheme = colorSchemeSelect.value;
860
+ const title = chartTitleInput.value || `${currentVizType} Chart`;
861
+
862
+ if (currentVizType === 'bar' || currentVizType === 'line' || currentVizType === 'pie' || currentVizType === 'scatter') {
863
+ // Show chart canvas
864
+ chartCanvas.classList.remove('hidden');
865
+
866
+ // In a real app, we would use a charting library like Chart.js
867
+ // For this demo, we'll just show a placeholder
868
+ const ctx = chartCanvas.getContext('2d');
869
+
870
+ // Clear previous chart if exists
871
+ if (currentChart) {
872
+ currentChart.destroy();
873
+ }
874
+
875
+ // Create mock chart data based on selections
876
+ const labels = currentData.map(item => item[xAxis]);
877
+ const data = currentData.map(item => item[yAxis]);
878
+
879
+ // Generate mock chart
880
+ currentChart = {
881
+ destroy: function() {
882
+ // Mock destroy function
883
+ }
884
+ };
885
+
886
+ // Show a message about what would be rendered
887
+ chartCanvas.width = chartCanvas.offsetWidth;
888
+ chartCanvas.height = chartCanvas.offsetHeight;
889
+
890
+ ctx.fillStyle = '#f8fafc';
891
+ ctx.fillRect(0, 0, chartCanvas.width, chartCanvas.height);
892
+
893
+ ctx.font = '16px Arial';
894
+ ctx.fillStyle = '#334155';
895
+ ctx.textAlign = 'center';
896
+ ctx.fillText(`${title} (${currentVizType})`, chartCanvas.width / 2, 30);
897
+
898
+ ctx.font = '14px Arial';
899
+ ctx.fillText(`X-Axis: ${xAxis}`, chartCanvas.width / 2, 60);
900
+ ctx.fillText(`Y-Axis: ${yAxis}`, chartCanvas.width / 2, 80);
901
+
902
+ // Draw a simple representation of the chart
903
+ if (currentVizType === 'bar') {
904
+ drawMockBarChart(ctx, labels, data);
905
+ } else if (currentVizType === 'line') {
906
+ drawMockLineChart(ctx, labels, data);
907
+ } else if (currentVizType === 'pie') {
908
+ drawMockPieChart(ctx, labels, data);
909
+ } else if (currentVizType === 'scatter') {
910
+ drawMockScatterPlot(ctx, labels, data);
911
+ }
912
+ }
913
+ else if (currentVizType === 'flowchart') {
914
+ // Show flowchart container
915
+ flowchartContainer.classList.remove('hidden');
916
+
917
+ // In a real app, we would use a diagramming library
918
+ flowchartContainer.innerHTML = `
919
+ <div class="text-center p-4">
920
+ <i class="fas fa-project-diagram text-4xl text-blue-500 mb-2"></i>
921
+ <h4 class="text-lg font-medium">Flowchart</h4>
922
+ <p class="text-sm text-gray-600">This would display a flowchart based on your data</p>
923
+ </div>
924
+ `;
925
+ }
926
+ else if (currentVizType === 'mindmap') {
927
+ // Show mindmap container
928
+ mindmapContainer.classList.remove('hidden');
929
+
930
+ // In a real app, we would use a diagramming library
931
+ mindmapContainer.innerHTML = `
932
+ <div class="text-center p-4">
933
+ <i class="fas fa-sitemap text-4xl text-green-500 mb-2"></i>
934
+ <h4 class="text-lg font-medium">Mind Map</h4>
935
+ <p class="text-sm text-gray-600">This would display a mind map based on your data</p>
936
+ </div>
937
+ `;
938
+ }
939
+ }
940
+
941
+ // Draw a mock bar chart (for demo purposes)
942
+ function drawMockBarChart(ctx, labels, data) {
943
+ const maxValue = Math.max(...data);
944
+ const barWidth = 40;
945
+ const startX = 60;
946
+ const startY = 100;
947
+ const chartHeight = ctx.canvas.height - 150;
948
+ const chartWidth = ctx.canvas.width - 120;
949
+
950
+ // Draw axes
951
+ ctx.strokeStyle = '#94a3b8';
952
+ ctx.lineWidth = 1;
953
+
954
+ // Y-axis
955
+ ctx.beginPath();
956
+ ctx.moveTo(startX, startY);
957
+ ctx.lineTo(startX, startY + chartHeight);
958
+ ctx.stroke();
959
+
960
+ // X-axis
961
+ ctx.beginPath();
962
+ ctx.moveTo(startX, startY + chartHeight);
963
+ ctx.lineTo(startX + chartWidth, startY + chartHeight);
964
+ ctx.stroke();
965
+
966
+ // Draw bars
967
+ const spacing = (chartWidth - (labels.length * barWidth)) / (labels.length + 1);
968
+ let x = startX + spacing;
969
+
970
+ for (let i = 0; i < labels.length; i++) {
971
+ const barHeight = (data[i] / maxValue) * chartHeight;
972
+ const y = startY + chartHeight - barHeight;
973
+
974
+ ctx.fillStyle = getBarColor(i);
975
+ ctx.fillRect(x, y, barWidth, barHeight);
976
+
977
+ // Draw label
978
+ ctx.font = '12px Arial';
979
+ ctx.fillStyle = '#334155';
980
+ ctx.textAlign = 'center';
981
+ ctx.fillText(labels[i], x + barWidth/2, startY + chartHeight + 20);
982
+
983
+ x += barWidth + spacing;
984
+ }
985
+ }
986
+
987
+ // Draw a mock line chart (for demo purposes)
988
+ function drawMockLineChart(ctx, labels, data) {
989
+ const maxValue = Math.max(...data);
990
+ const startX = 60;
991
+ const startY = 100;
992
+ const chartHeight = ctx.canvas.height - 150;
993
+ const chartWidth = ctx.canvas.width - 120;
994
+
995
+ // Draw axes
996
+ ctx.strokeStyle = '#94a3b8';
997
+ ctx.lineWidth = 1;
998
+
999
+ // Y-axis
1000
+ ctx.beginPath();
1001
+ ctx.moveTo(startX, startY);
1002
+ ctx.lineTo(startX, startY + chartHeight);
1003
+ ctx.stroke();
1004
+
1005
+ // X-axis
1006
+ ctx.beginPath();
1007
+ ctx.moveTo(startX, startY + chartHeight);
1008
+ ctx.lineTo(startX + chartWidth, startY + chartHeight);
1009
+ ctx.stroke();
1010
+
1011
+ // Draw line
1012
+ ctx.beginPath();
1013
+ ctx.strokeStyle = '#3b82f6';
1014
+ ctx.lineWidth = 2;
1015
+
1016
+ const pointSpacing = chartWidth / (labels.length - 1);
1017
+ let x = startX;
1018
+
1019
+ for (let i = 0; i < labels.length; i++) {
1020
+ const y = startY + chartHeight - (data[i] / maxValue) * chartHeight;
1021
+
1022
+ if (i === 0) {
1023
+ ctx.moveTo(x, y);
1024
+ } else {
1025
+ ctx.lineTo(x, y);
1026
+ }
1027
+
1028
+ // Draw point
1029
+ ctx.fillStyle = '#3b82f6';
1030
+ ctx.beginPath();
1031
+ ctx.arc(x, y, 4, 0, Math.PI * 2);
1032
+ ctx.fill();
1033
+
1034
+ // Draw label
1035
+ ctx.font = '12px Arial';
1036
+ ctx.fillStyle = '#334155';
1037
+ ctx.textAlign = 'center';
1038
+ ctx.fillText(labels[i], x, startY + chartHeight + 20);
1039
+
1040
+ x += pointSpacing;
1041
+ }
1042
+
1043
+ ctx.stroke();
1044
+ }
1045
+
1046
+ // Draw a mock pie chart (for demo purposes)
1047
+ function drawMockPieChart(ctx, labels, data) {
1048
+ const centerX = ctx.canvas.width / 2;
1049
+ const centerY = ctx.canvas.height / 2;
1050
+ const radius = Math.min(ctx.canvas.width, ctx.canvas.height) / 3;
1051
+ const total = data.reduce((sum, value) => sum + value, 0);
1052
+
1053
+ let startAngle = 0;
1054
+
1055
+ for (let i = 0; i < data.length; i++) {
1056
+ const sliceAngle = (data[i] / total) * 2 * Math.PI;
1057
+
1058
+ ctx.fillStyle = getBarColor(i);
1059
+ ctx.beginPath();
1060
+ ctx.moveTo(centerX, centerY);
1061
+ ctx.arc(centerX, centerY, radius, startAngle, startAngle + sliceAngle);
1062
+ ctx.closePath();
1063
+ ctx.fill();
1064
+
1065
+ // Draw label outside
1066
+ const midAngle = startAngle + sliceAngle / 2;
1067
+ const labelX = centerX + (radius + 20) * Math.cos(midAngle);
1068
+ const labelY = centerY + (radius + 20) * Math.sin(midAngle);
1069
+
1070
+ ctx.font = '12px Arial';
1071
+ ctx.fillStyle = '#334155';
1072
+ ctx.textAlign = 'center';
1073
+ ctx.fillText(labels[i], labelX, labelY);
1074
+
1075
+ startAngle += sliceAngle;
1076
+ }
1077
+ }
1078
+
1079
+ // Draw a mock scatter plot (for demo purposes)
1080
+ function drawMockScatterPlot(ctx, labels, data) {
1081
+ const maxValue = Math.max(...data);
1082
+ const startX = 60;
1083
+ const startY = 100;
1084
+ const chartHeight = ctx.canvas.height - 150;
1085
+ const chartWidth = ctx.canvas.width - 120;
1086
+
1087
+ // Draw axes
1088
+ ctx.strokeStyle = '#94a3b8';
1089
+ ctx.lineWidth = 1;
1090
+
1091
+ // Y-axis
1092
+ ctx.beginPath();
1093
+ ctx.moveTo(startX, startY);
1094
+ ctx.lineTo(startX, startY + chartHeight);
1095
+ ctx.stroke();
1096
+
1097
+ // X-axis
1098
+ ctx.beginPath();
1099
+ ctx.moveTo(startX, startY + chartHeight);
1100
+ ctx.lineTo(startX + chartWidth, startY + chartHeight);
1101
+ ctx.stroke();
1102
+
1103
+ // Draw points
1104
+ const pointSpacing = chartWidth / (labels.length - 1);
1105
+ let x = startX;
1106
+
1107
+ for (let i = 0; i < labels.length; i++) {
1108
+ const y = startY + chartHeight - (data[i] / maxValue) * chartHeight;
1109
+
1110
+ ctx.fillStyle = getBarColor(i);
1111
+ ctx.beginPath();
1112
+ ctx.arc(x, y, 6, 0, Math.PI * 2);
1113
+ ctx.fill();
1114
+
1115
+ // Draw label
1116
+ ctx.font = '12px Arial';
1117
+ ctx.fillStyle = '#334155';
1118
+ ctx.textAlign = 'center';
1119
+ ctx.fillText(labels[i], x, startY + chartHeight + 20);
1120
+
1121
+ x += pointSpacing;
1122
+ }
1123
+ }
1124
+
1125
+ // Get color for bars/points based on index and selected color scheme
1126
+ function getBarColor(index) {
1127
+ const scheme = colorSchemeSelect.value;
1128
+
1129
+ const schemes = {
1130
+ default: ['#3b82f6', '#ef4444', '#10b981', '#f59e0b', '#8b5cf6'],
1131
+ rainbow: ['#ff0000', '#ff7f00', '#ffff00', '#00ff00', '#0000ff', '#4b0082', '#9400d3'],
1132
+ pastel: ['#ffb3ba', '#ffdfba', '#ffffba', '#baffc9', '#bae1ff'],
1133
+ warm: ['#ff7b54', '#ffb26b', '#ffd56b', '#939b62', '#416165'],
1134
+ cool: ['#a0e7e5', '#b4f8c8', '#fbe7c6', '#ffaebc', '#aedefc'],
1135
+ monochrome: ['#6b7280', '#9ca3af', '#d1d5db', '#e5e7eb', '#f3f4f6']
1136
+ };
1137
+
1138
+ const colors = schemes[scheme] || schemes.default;
1139
+ return colors[index % colors.length];
1140
+ }
1141
+
1142
+ // Generate AI recommendation
1143
+ function generateAiRecommendation() {
1144
+ if (currentData.length === 0) {
1145
+ alert('Please import data first');
1146
+ return;
1147
+ }
1148
+
1149
+ // In a real app, this would analyze the data structure
1150
+ // For demo, we'll just provide a simple recommendation
1151
+ const headers = Object.keys(currentData[0]);
1152
+ const numericHeaders = headers.filter(h => typeof currentData[0][h] === 'number');
1153
+ const categoricalHeaders = headers.filter(h => typeof currentData[0][h] === 'string');
1154
+
1155
+ let recommendation = '';
1156
+
1157
+ if (numericHeaders.length >= 2 && categoricalHeaders.length >= 1) {
1158
+ recommendation = `A grouped bar chart comparing ${numericHeaders[0]} and ${numericHeaders[1]} across different ${categoricalHeaders[0]} categories would effectively show the relationships in your data.`;
1159
+ } else if (numericHeaders.length >= 1 && categoricalHeaders.length >= 1) {
1160
+ recommendation = `A pie chart showing the distribution of ${numericHeaders[0]} by ${categoricalHeaders[0]} would be a good choice to visualize proportions.`;
1161
+ } else if (numericHeaders.length >= 2) {
1162
+ recommendation = `A scatter plot with ${numericHeaders[0]} on the X-axis and ${numericHeaders[1]} on the Y-axis would help identify correlations.`;
1163
+ } else {
1164
+ recommendation = `Based on your data structure, a simple table might be the most effective way to present this information.`;
1165
+ }
1166
+
1167
+ aiRecommendationText.textContent = recommendation;
1168
+ aiRecommendationSection.classList.remove('hidden');
1169
+ }
1170
+
1171
+ // Apply AI recommendation
1172
+ function applyAiRecommendation() {
1173
+ // In a real app, this would set the appropriate chart type and axes
1174
+ // For demo, we'll just set to bar chart
1175
+ currentVizType = 'bar';
1176
+ chartTypeSelect.value = 'bar';
1177
+ updateVizControls();
1178
+ renderVisualization();
1179
+
1180
+ // Scroll to visualization
1181
+ vizWorkspace.scrollIntoView({ behavior: 'smooth' });
1182
+ }
1183
+
1184
+ // Perform data cleaning action
1185
+ function performDataCleaning(action) {
1186
+ if (currentData.length === 0) {
1187
+ alert('Please import data first');
1188
+ return;
1189
+ }
1190
+
1191
+ switch(action) {
1192
+ case 'remove-duplicates':
1193
+ // In a real app, we would actually remove duplicates
1194
+ alert('Duplicate rows removed successfully!');
1195
+ break;
1196
+ case 'fill-missing':
1197
+ // In a real app, we would fill missing values
1198
+ alert('Missing values filled successfully!');
1199
+ break;
1200
+ case 'filter-data':
1201
+ // In a real app, we would show filtering UI
1202
+ alert('Filter applied successfully!');
1203
+ break;
1204
+ default:
1205
+ alert('Unknown action');
1206
+ }
1207
+
1208
+ // Refresh the preview
1209
+ renderDataPreview();
1210
+
1211
+ // If visualization exists, update it
1212
+ if (!chartPlaceholder.classList.contains('hidden')) {
1213
+ renderVisualization();
1214
+ }
1215
+ }
1216
+
1217
+ // Initialize the app
1218
+ init();
1219
+ </script>
1220
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=MEDT/dataviz-v2" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
1221
+ </html>
prompts.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ Hello, I would like to create a data visualization dashboard web app. Here are the key functionalities I need: Allow users to import data from CSV or Excel files. After importing, allow users to select what type of visualization they want to create: Charts (bar, line, pie, scatter, etc.) Diagrams (flowcharts, organizational charts, etc.) Mind Maps Enable drag-and-drop interface for building and customizing visualizations. Provide basic data cleaning options (e.g., remove duplicates, fill missing values). Allow users to filter, sort, and group data before visualization. Enable dynamic updating: if the data changes, the visualization updates automatically. Allow users to customize the visuals (colors, labels, titles, sizes, etc.). Support saving and exporting visualizations (as images or PDFs). Provide dashboard templates for faster setup. Offer an AI assistant suggestion feature: recommend the best type of visualization based on the dataset. Support multi-language UI (optional, but nice to have). The dashboard should have a clean, responsive design that works on desktop and mobile.