Juhayna commited on
Commit
4483bcf
·
verified ·
1 Parent(s): a72afd5

条的高度太高了,我想要白色主题的,去掉Instructions,示例的JSON可以格式化一下 - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +261 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Events Visualizer
3
- emoji: 🏢
4
- colorFrom: purple
5
- colorTo: gray
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: events-visualizer
3
+ emoji: 🐳
4
+ colorFrom: red
5
+ colorTo: blue
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,261 @@
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>Event Timeline Visualizer</title>
7
+ <meta name="description" content="Visualize event timelines as Gantt charts">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <style>
10
+ .chart-container {
11
+ overflow-x: auto;
12
+ overflow-y: visible;
13
+ }
14
+ .event-bar {
15
+ transition: opacity 0.2s;
16
+ }
17
+ .event-bar:hover {
18
+ opacity: 0.8;
19
+ }
20
+ .tooltip {
21
+ position: absolute;
22
+ background: rgba(0, 0, 0, 0.8);
23
+ color: white;
24
+ padding: 5px 10px;
25
+ border-radius: 4px;
26
+ font-size: 12px;
27
+ pointer-events: none;
28
+ z-index: 10;
29
+ transform: translate(-50%, -100%);
30
+ display: none;
31
+ }
32
+ </style>
33
+ </head>
34
+ <body class="bg-gray-50 min-h-screen">
35
+ <header class="bg-white shadow-sm">
36
+ <div class="container mx-auto px-4 py-6">
37
+ <h1 class="text-2xl font-bold text-gray-800">Event Timeline Visualizer</h1>
38
+ <p class="text-gray-600 mt-2">Paste your event data to generate a Gantt chart</p>
39
+ </div>
40
+ </header>
41
+
42
+ <main class="container mx-auto px-4 py-8">
43
+ <div class="bg-white rounded-lg shadow-md p-6 mb-8">
44
+ <div class="mb-4">
45
+ <label for="eventData" class="block text-sm font-medium text-gray-700 mb-2">Event Data (JSON format)</label>
46
+ <textarea
47
+ id="eventData"
48
+ rows="8"
49
+ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm"
50
+ placeholder="Paste your event data here (e.g. {'Event name': [[start1, end1], [start2, end2], ...]})">{
51
+ 'Video game sound': [[0.0, 10.0]],
52
+ 'Male speech, man speaking': [[0.015, 3.829], [4.293, 4.875], [5.089, 7.349], [8.071, 9.978]]
53
+ }</textarea>
54
+ </div>
55
+ <div class="flex justify-between items-center">
56
+ <div>
57
+ <label for="maxTime" class="block text-sm font-medium text-gray-700 mb-1">Max Time (seconds)</label>
58
+ <input
59
+ type="number"
60
+ id="maxTime"
61
+ value="10"
62
+ min="1"
63
+ step="1"
64
+ class="w-24 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
65
+ </div>
66
+ <div class="flex items-center">
67
+ <input
68
+ type="checkbox"
69
+ id="autoUpdate"
70
+ checked
71
+ class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
72
+ <label for="autoUpdate" class="ml-2 block text-sm text-gray-700">Auto-update</label>
73
+ </div>
74
+ </div>
75
+ </div>
76
+
77
+ <div id="chartContainer" class="chart-container bg-white rounded-lg shadow-md p-6">
78
+ <div id="tooltip" class="tooltip"></div>
79
+ <div id="chart" class="min-w-full"></div>
80
+ </div>
81
+ </main>
82
+
83
+ <footer class="bg-white border-t mt-8 py-6">
84
+ <div class="container mx-auto px-4 text-center text-gray-500 text-sm">
85
+ <p>Event Timeline Visualizer - Paste JSON data to generate Gantt charts</p>
86
+ </div>
87
+ </footer>
88
+
89
+ <script>
90
+ // Color palette for events
91
+ const colors = [
92
+ '#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6',
93
+ '#EC4899', '#14B8A6', '#F97316', '#84CC16', '#06B6D4'
94
+ ];
95
+
96
+ // Initialize variables
97
+ let timeoutId = null;
98
+ const tooltip = document.getElementById('tooltip');
99
+
100
+ // Set up event listeners
101
+ document.getElementById('eventData').addEventListener('input', handleInputChange);
102
+ document.getElementById('maxTime').addEventListener('input', handleInputChange);
103
+
104
+ function handleInputChange() {
105
+ if (document.getElementById('autoUpdate').checked) {
106
+ // Debounce the update to prevent excessive rendering
107
+ clearTimeout(timeoutId);
108
+ timeoutId = setTimeout(generateChart, 300);
109
+ }
110
+ }
111
+
112
+ function generateChart() {
113
+ const eventDataText = document.getElementById('eventData').value;
114
+ const maxTime = parseFloat(document.getElementById('maxTime').value) || 10;
115
+
116
+ try {
117
+ // Replace single quotes with double quotes for valid JSON
118
+ const jsonString = eventDataText.replace(/'/g, '"');
119
+ const events = JSON.parse(jsonString);
120
+
121
+ renderChart(events, maxTime);
122
+ } catch (error) {
123
+ console.error(error);
124
+ }
125
+ }
126
+
127
+ function renderChart(events, maxTime) {
128
+ const chartElement = document.getElementById('chart');
129
+ chartElement.innerHTML = '';
130
+
131
+ const eventNames = Object.keys(events);
132
+ if (eventNames.length === 0) {
133
+ chartElement.innerHTML = '<p class="text-gray-500">No events to display</p>';
134
+ return;
135
+ }
136
+
137
+ // Calculate dimensions
138
+ const labelWidth = 200; // Increased width for labels
139
+ const chartWidth = Math.max(800, maxTime * 80);
140
+ const barHeight = 30;
141
+ const rowGap = 15;
142
+ const padding = 40;
143
+ const totalHeight = (barHeight + rowGap) * eventNames.length + padding * 2;
144
+
145
+ // Create SVG element
146
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
147
+ svg.setAttribute('width', '100%');
148
+ svg.setAttribute('height', totalHeight);
149
+ svg.setAttribute('viewBox', `0 0 ${chartWidth + labelWidth} ${totalHeight}`);
150
+
151
+ // Add background
152
+ const bg = document.createElementNS("http://www.w3.org/2000/svg", "rect");
153
+ bg.setAttribute('width', '100%');
154
+ bg.setAttribute('height', '100%');
155
+ bg.setAttribute('fill', 'white');
156
+ svg.appendChild(bg);
157
+
158
+ // Add time axis
159
+ const timeAxis = document.createElementNS("http://www.w3.org/2000/svg", "line");
160
+ timeAxis.setAttribute('x1', labelWidth);
161
+ timeAxis.setAttribute('y1', padding);
162
+ timeAxis.setAttribute('x2', chartWidth + labelWidth - padding);
163
+ timeAxis.setAttribute('y2', padding);
164
+ timeAxis.setAttribute('stroke', '#D1D5DB');
165
+ timeAxis.setAttribute('stroke-width', '1');
166
+ svg.appendChild(timeAxis);
167
+
168
+ // Add time ticks
169
+ for (let t = 0; t <= maxTime; t++) {
170
+ const x = labelWidth + (t / maxTime) * (chartWidth - padding);
171
+
172
+ const tick = document.createElementNS("http://www.w3.org/2000/svg", "line");
173
+ tick.setAttribute('x1', x);
174
+ tick.setAttribute('y1', padding);
175
+ tick.setAttribute('x2', x);
176
+ tick.setAttribute('y2', padding + 5);
177
+ tick.setAttribute('stroke', '#D1D5DB');
178
+ tick.setAttribute('stroke-width', '1');
179
+ svg.appendChild(tick);
180
+
181
+ const label = document.createElementNS("http://www.w3.org/2000/svg", "text");
182
+ label.setAttribute('x', x);
183
+ label.setAttribute('y', padding + 20);
184
+ label.setAttribute('text-anchor', 'middle');
185
+ label.setAttribute('font-size', '12');
186
+ label.setAttribute('fill', '#6B7280');
187
+ label.textContent = t;
188
+ svg.appendChild(label);
189
+ }
190
+
191
+ // Add events
192
+ eventNames.forEach((eventName, index) => {
193
+ const y = padding + 40 + index * (barHeight + rowGap);
194
+
195
+ // Add event label with ellipsis for long names
196
+ const label = document.createElementNS("http://www.w3.org/2000/svg", "text");
197
+ label.setAttribute('x', labelWidth - 10);
198
+ label.setAttribute('y', y + barHeight / 2 + 5);
199
+ label.setAttribute('text-anchor', 'end');
200
+ label.setAttribute('font-size', '12');
201
+ label.setAttribute('fill', '#374151');
202
+
203
+ // Truncate long labels
204
+ const maxChars = 25;
205
+ const displayName = eventName.length > maxChars
206
+ ? eventName.substring(0, maxChars) + '...'
207
+ : eventName;
208
+ label.textContent = displayName;
209
+
210
+ // Add full name as title for hover
211
+ const title = document.createElementNS("http://www.w3.org/2000/svg", "title");
212
+ title.textContent = eventName;
213
+ label.appendChild(title);
214
+
215
+ svg.appendChild(label);
216
+
217
+ // Add event bars
218
+ const intervals = events[eventName];
219
+ const color = colors[index % colors.length];
220
+
221
+ intervals.forEach(interval => {
222
+ const [start, end] = interval;
223
+ const x1 = labelWidth + (start / maxTime) * (chartWidth - padding);
224
+ const x2 = labelWidth + (end / maxTime) * (chartWidth - padding);
225
+ const width = Math.max(1, x2 - x1);
226
+
227
+ const bar = document.createElementNS("http://www.w3.org/2000/svg", "rect");
228
+ bar.setAttribute('x', x1);
229
+ bar.setAttribute('y', y);
230
+ bar.setAttribute('width', width);
231
+ bar.setAttribute('height', barHeight);
232
+ bar.setAttribute('fill', color);
233
+ bar.setAttribute('rx', '3');
234
+ bar.setAttribute('ry', '3');
235
+ bar.classList.add('event-bar');
236
+
237
+ // Add mouse events for tooltip
238
+ bar.addEventListener('mouseenter', (e) => {
239
+ const rect = e.target.getBoundingClientRect();
240
+ tooltip.textContent = `${eventName}: ${start.toFixed(3)}s - ${end.toFixed(3)}s`;
241
+ tooltip.style.display = 'block';
242
+ tooltip.style.left = `${rect.left + rect.width/2}px`;
243
+ tooltip.style.top = `${rect.top}px`;
244
+ });
245
+
246
+ bar.addEventListener('mouseleave', () => {
247
+ tooltip.style.display = 'none';
248
+ });
249
+
250
+ svg.appendChild(bar);
251
+ });
252
+ });
253
+
254
+ chartElement.appendChild(svg);
255
+ }
256
+
257
+ // Generate initial chart
258
+ generateChart();
259
+ </script>
260
+ <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=Juhayna/events-visualizer" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
261
+ </html>