tfrere HF Staff commited on
Commit
d8f167c
·
verified ·
1 Parent(s): 89281ce

fais moi un chart cool sur le machine learning en lisant les direxctives dans le readme

Browse files
Files changed (2) hide show
  1. d3-ml-metrics.html +360 -0
  2. index.html +4 -1
d3-ml-metrics.html ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="d3-ml-metrics"></div>
2
+ <style>
3
+ .d3-ml-metrics {
4
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif;
5
+ position: relative;
6
+ }
7
+
8
+ .d3-ml-metrics .chart-container {
9
+ width: 100%;
10
+ overflow: visible;
11
+ }
12
+
13
+ .d3-ml-metrics .axis path,
14
+ .d3-ml-metrics .axis line {
15
+ stroke: var(--axis-color);
16
+ shape-rendering: crispEdges;
17
+ }
18
+
19
+ .d3-ml-metrics .axis text {
20
+ fill: var(--tick-color);
21
+ font-size: 11px;
22
+ }
23
+
24
+ .d3-ml-metrics .grid line {
25
+ stroke: var(--grid-color);
26
+ stroke-dasharray: 2,2;
27
+ shape-rendering: crispEdges;
28
+ }
29
+
30
+ .d3-ml-metrics .line {
31
+ fill: none;
32
+ stroke-width: 2px;
33
+ stroke-linejoin: round;
34
+ stroke-linecap: round;
35
+ }
36
+
37
+ .d3-ml-metrics .legend {
38
+ display: flex;
39
+ flex-direction: column;
40
+ gap: 8px;
41
+ margin-top: 16px;
42
+ }
43
+
44
+ .d3-ml-metrics .legend-title {
45
+ font-size: 12px;
46
+ font-weight: 700;
47
+ color: var(--text-color);
48
+ }
49
+
50
+ .d3-ml-metrics .legend-items {
51
+ display: flex;
52
+ flex-wrap: wrap;
53
+ gap: 12px;
54
+ }
55
+
56
+ .d3-ml-metrics .legend-item {
57
+ display: flex;
58
+ align-items: center;
59
+ gap: 6px;
60
+ cursor: pointer;
61
+ }
62
+
63
+ .d3-ml-metrics .legend-swatch {
64
+ width: 14px;
65
+ height: 14px;
66
+ border-radius: 3px;
67
+ border: 1px solid var(--border-color);
68
+ }
69
+
70
+ .d3-ml-metrics .controls {
71
+ display: flex;
72
+ justify-content: flex-end;
73
+ margin-bottom: 16px;
74
+ }
75
+
76
+ .d3-ml-metrics .control-group {
77
+ display: flex;
78
+ flex-direction: column;
79
+ gap: 6px;
80
+ }
81
+
82
+ .d3-ml-metrics .control-group label {
83
+ font-size: 12px;
84
+ font-weight: 700;
85
+ color: var(--text-color);
86
+ }
87
+
88
+ .d3-ml-metrics .control-group select {
89
+ font-size: 12px;
90
+ padding: 6px 24px 6px 8px;
91
+ border: 1px solid var(--border-color);
92
+ border-radius: 6px;
93
+ background: var(--surface-bg);
94
+ color: var(--text-color);
95
+ appearance: none;
96
+ background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
97
+ background-repeat: no-repeat;
98
+ background-position: right 8px center;
99
+ background-size: 14px;
100
+ }
101
+
102
+ .d3-ml-metrics .d3-tooltip {
103
+ position: absolute;
104
+ padding: 8px 12px;
105
+ background: var(--surface-bg);
106
+ border: 1px solid var(--border-color);
107
+ border-radius: 6px;
108
+ pointer-events: none;
109
+ font-size: 12px;
110
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
111
+ opacity: 0;
112
+ transition: opacity 0.2s;
113
+ }
114
+
115
+ .d3-ml-metrics .d3-tooltip strong {
116
+ display: block;
117
+ margin-bottom: 4px;
118
+ }
119
+ </style>
120
+ <script>
121
+ (() => {
122
+ const ensureD3 = (cb) => {
123
+ if (window.d3 && typeof window.d3.select === 'function') return cb();
124
+ let s = document.getElementById('d3-cdn-script');
125
+ if (!s) { s = document.createElement('script'); s.id = 'd3-cdn-script'; s.src = 'https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js'; document.head.appendChild(s); }
126
+ const onReady = () => { if (window.d3 && typeof window.d3.select === 'function') cb(); };
127
+ s.addEventListener('load', onReady, { once: true });
128
+ if (window.d3) onReady();
129
+ };
130
+
131
+ const bootstrap = () => {
132
+ const scriptEl = document.currentScript;
133
+ let container = scriptEl ? scriptEl.previousElementSibling : null;
134
+ if (!(container && container.classList && container.classList.contains('d3-ml-metrics'))) {
135
+ const candidates = Array.from(document.querySelectorAll('.d3-ml-metrics'))
136
+ .filter((el) => !(el.dataset && el.dataset.mounted === 'true'));
137
+ container = candidates[candidates.length - 1] || null;
138
+ }
139
+ if (!container) return;
140
+ if (container.dataset) {
141
+ if (container.dataset.mounted === 'true') return;
142
+ container.dataset.mounted = 'true';
143
+ }
144
+
145
+ // Create UI elements
146
+ const controls = document.createElement('div');
147
+ controls.className = 'controls';
148
+
149
+ const controlGroup = document.createElement('div');
150
+ controlGroup.className = 'control-group';
151
+
152
+ const label = document.createElement('label');
153
+ label.htmlFor = 'metric-select';
154
+ label.textContent = 'Metric';
155
+
156
+ const select = document.createElement('select');
157
+ select.id = 'metric-select';
158
+
159
+ controlGroup.appendChild(label);
160
+ controlGroup.appendChild(select);
161
+ controls.appendChild(controlGroup);
162
+ container.appendChild(controls);
163
+
164
+ // Create chart elements
165
+ const svg = d3.select(container).append('svg')
166
+ .attr('class', 'chart-container')
167
+ .attr('width', '100%')
168
+ .style('display', 'block');
169
+
170
+ const g = svg.append('g')
171
+ .attr('class', 'chart-content');
172
+
173
+ // Create tooltip
174
+ const tooltip = document.createElement('div');
175
+ tooltip.className = 'd3-tooltip';
176
+ container.appendChild(tooltip);
177
+
178
+ // Sample ML metrics data
179
+ const metricsData = [
180
+ { epoch: 1, accuracy: 0.65, loss: 1.2, val_accuracy: 0.62, val_loss: 1.3 },
181
+ { epoch: 2, accuracy: 0.72, loss: 0.9, val_accuracy: 0.68, val_loss: 1.1 },
182
+ { epoch: 3, accuracy: 0.78, loss: 0.7, val_accuracy: 0.74, val_loss: 0.95 },
183
+ { epoch: 4, accuracy: 0.82, loss: 0.6, val_accuracy: 0.79, val_loss: 0.8 },
184
+ { epoch: 5, accuracy: 0.85, loss: 0.5, val_accuracy: 0.82, val_loss: 0.7 },
185
+ { epoch: 6, accuracy: 0.88, loss: 0.45, val_accuracy: 0.84, val_loss: 0.65 },
186
+ { epoch: 7, accuracy: 0.89, loss: 0.4, val_accuracy: 0.86, val_loss: 0.6 },
187
+ { epoch: 8, accuracy: 0.91, loss: 0.35, val_accuracy: 0.87, val_loss: 0.55 },
188
+ { epoch: 9, accuracy: 0.92, loss: 0.3, val_accuracy: 0.88, val_loss: 0.5 },
189
+ { epoch: 10, accuracy: 0.93, loss: 0.25, val_accuracy: 0.89, val_loss: 0.45 }
190
+ ];
191
+
192
+ // Available metrics
193
+ const metrics = [
194
+ { id: 'accuracy', name: 'Accuracy', color: '#4e79a7' },
195
+ { id: 'loss', name: 'Loss', color: '#e15759' },
196
+ { id: 'val_accuracy', name: 'Val Accuracy', color: '#76b7b2' },
197
+ { id: 'val_loss', name: 'Val Loss', color: '#f28e2b' }
198
+ ];
199
+
200
+ // Populate select
201
+ metrics.forEach(metric => {
202
+ const option = document.createElement('option');
203
+ option.value = metric.id;
204
+ option.textContent = metric.name;
205
+ select.appendChild(option);
206
+ });
207
+
208
+ // Initial selection
209
+ select.value = 'accuracy';
210
+
211
+ // Create legend
212
+ const legend = document.createElement('div');
213
+ legend.className = 'legend';
214
+
215
+ const legendTitle = document.createElement('div');
216
+ legendTitle.className = 'legend-title';
217
+ legendTitle.textContent = 'Legend';
218
+
219
+ const legendItems = document.createElement('div');
220
+ legendItems.className = 'legend-items';
221
+
222
+ metrics.forEach(metric => {
223
+ const item = document.createElement('div');
224
+ item.className = 'legend-item';
225
+ item.dataset.metric = metric.id;
226
+ item.addEventListener('click', () => {
227
+ select.value = metric.id;
228
+ render();
229
+ });
230
+
231
+ const swatch = document.createElement('div');
232
+ swatch.className = 'legend-swatch';
233
+ swatch.style.backgroundColor = metric.color;
234
+
235
+ const name = document.createElement('span');
236
+ name.textContent = metric.name;
237
+
238
+ item.appendChild(swatch);
239
+ item.appendChild(name);
240
+ legendItems.appendChild(item);
241
+ });
242
+
243
+ legend.appendChild(legendTitle);
244
+ legend.appendChild(legendItems);
245
+ container.appendChild(legend);
246
+
247
+ // Chart dimensions and margins
248
+ let width, height;
249
+ const margin = { top: 20, right: 30, bottom: 40, left: 50 };
250
+
251
+ // Scales
252
+ const x = d3.scaleLinear();
253
+ const y = d3.scaleLinear();
254
+
255
+ // Line generator
256
+ const line = d3.line()
257
+ .x(d => x(d.epoch))
258
+ .y(d => y(d[select.value]));
259
+
260
+ // Update dimensions
261
+ function updateDimensions() {
262
+ width = container.clientWidth;
263
+ height = Math.max(300, width * 0.5);
264
+ svg.attr('height', height);
265
+
266
+ x.range([margin.left, width - margin.right])
267
+ .domain([1, d3.max(metricsData, d => d.epoch)]);
268
+
269
+ const selectedMetric = metrics.find(m => m.id === select.value);
270
+ y.range([height - margin.bottom, margin.top])
271
+ .domain([0, d3.max(metricsData, d => d[select.value]) * 1.1]);
272
+ }
273
+
274
+ // Render chart
275
+ function render() {
276
+ updateDimensions();
277
+
278
+ const selectedMetric = metrics.find(m => m.id === select.value);
279
+
280
+ // Clear previous elements
281
+ g.selectAll('*').remove();
282
+
283
+ // Add grid
284
+ g.append('g')
285
+ .attr('class', 'grid')
286
+ .attr('transform', `translate(0,${height - margin.bottom})`)
287
+ .call(d3.axisBottom(x)
288
+ .tickSize(-(height - margin.top - margin.bottom))
289
+ .tickFormat('')
290
+ );
291
+
292
+ g.append('g')
293
+ .attr('class', 'grid')
294
+ .attr('transform', `translate(${margin.left},0)`)
295
+ .call(d3.axisLeft(y)
296
+ .tickSize(-(width - margin.left - margin.right))
297
+ .tickFormat('')
298
+ );
299
+
300
+ // Add axes
301
+ g.append('g')
302
+ .attr('class', 'axis x-axis')
303
+ .attr('transform', `translate(0,${height - margin.bottom})`)
304
+ .call(d3.axisBottom(x));
305
+
306
+ g.append('g')
307
+ .attr('class', 'axis y-axis')
308
+ .attr('transform', `translate(${margin.left},0)`)
309
+ .call(d3.axisLeft(y));
310
+
311
+ // Add line
312
+ g.append('path')
313
+ .datum(metricsData)
314
+ .attr('class', 'line')
315
+ .attr('stroke', selectedMetric.color)
316
+ .attr('d', line);
317
+
318
+ // Add points
319
+ g.selectAll('.point')
320
+ .data(metricsData)
321
+ .enter()
322
+ .append('circle')
323
+ .attr('class', 'point')
324
+ .attr('cx', d => x(d.epoch))
325
+ .attr('cy', d => y(d[select.value]))
326
+ .attr('r', 4)
327
+ .attr('fill', selectedMetric.color)
328
+ .on('mouseover', (event, d) => {
329
+ tooltip.innerHTML = `
330
+ <strong>Epoch ${d.epoch}</strong>
331
+ ${selectedMetric.name}: ${d[select.value].toFixed(3)}
332
+ `;
333
+ tooltip.style.left = `${event.pageX + 10}px`;
334
+ tooltip.style.top = `${event.pageY - 10}px`;
335
+ tooltip.style.opacity = 1;
336
+ })
337
+ .on('mouseout', () => {
338
+ tooltip.style.opacity = 0;
339
+ });
340
+ }
341
+
342
+ // Handle select change
343
+ select.addEventListener('change', render);
344
+
345
+ // Initial render
346
+ render();
347
+
348
+ // Handle resize
349
+ const ro = window.ResizeObserver ? new ResizeObserver(render) : null;
350
+ if (ro) ro.observe(container);
351
+ else window.addEventListener('resize', render);
352
+ };
353
+
354
+ if (document.readyState === 'loading') {
355
+ document.addEventListener('DOMContentLoaded', () => ensureD3(bootstrap), { once: true });
356
+ } else {
357
+ ensureD3(bootstrap);
358
+ }
359
+ })();
360
+ </script>
index.html CHANGED
@@ -10,10 +10,13 @@
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>
 
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
+ <div class="chart-container">
14
+ <iframe src="d3-ml-metrics.html" style="width:100%; height:500px; border:none;"></iframe>
15
+ </div>
16
  <p>
17
  Also don't forget to check the
18
  <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
19
  </p>
20
+ </div>
21
  </body>
22
  </html>