thibaud frere commited on
Commit
0ec257a
·
1 Parent(s): 8f47735

fix filter quads range

Browse files
app/src/content/embeds/filters-quad.html CHANGED
@@ -127,6 +127,8 @@
127
  const xScale = d3.scaleLinear(); const yScale = d3.scaleLinear();
128
  const lineGen = d3.line().x(d => xScale(d.step)).y(d => yScale(d.value));
129
  let isRankStrictFlag = false; let rankTickMax = 1;
 
 
130
 
131
  // Colors and markers (match original embeds)
132
  const primary = getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim() || '#E889AB';
@@ -213,15 +215,24 @@
213
  return { innerWidth, innerHeight, tickColor };
214
  }
215
 
216
- function renderMetric(metricKey){
217
  const map = dataByMetric.get(metricKey) || {};
218
  const runs = runOrder;
219
  let minStep = Infinity, maxStep = -Infinity, maxVal = 0, minVal = Infinity;
220
  const isRank = /rank/i.test(metricKey); const isAverage = /average/i.test(metricKey); const isRankStrict = isRank && !isAverage;
221
  runs.forEach(r => { (map[r]||[]).forEach(pt => { const v = isRankStrict ? Math.round(pt.value) : pt.value; minStep=Math.min(minStep,pt.step); maxStep=Math.max(maxStep,pt.step); maxVal=Math.max(maxVal,v); minVal=Math.min(minVal,v); }); });
222
  if (!isFinite(minStep) || !isFinite(maxStep)) return;
223
- xScale.domain([minStep, maxStep]); if (isRank) { rankTickMax = Math.max(1, Math.round(maxVal)); yScale.domain([rankTickMax, 1]); } else { yScale.domain([minVal, maxVal]).nice(); }
 
 
 
 
 
 
 
 
224
  isRankStrictFlag = isRankStrict;
 
225
 
226
  const { innerWidth, innerHeight } = updateScales();
227
 
@@ -317,8 +328,9 @@
317
  // Par défaut, privilégier average_rank, sinon premier dispo
318
  const preferred = metricList.find(m => /average_rank/i.test(m)) || metricList.find(m => m === 'ai2d_exact_match');
319
  const def = preferred || metricList[0];
 
320
  renderMetric(def);
321
- const ro = window.ResizeObserver ? new ResizeObserver(()=>renderMetric(def)) : null; if (ro) ro.observe(cell);
322
  if (typeof readyResolve === 'function') readyResolve();
323
  } catch (e) {
324
  const pre = document.createElement('pre'); pre.textContent = 'CSV load error: ' + (e && e.message ? e.message : e);
@@ -331,7 +343,20 @@
331
  return {
332
  ready,
333
  getMetrics: () => metricList.slice(),
334
- setMetric: (m) => { if (m) renderMetric(m); }
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  };
336
  }
337
 
@@ -376,7 +401,24 @@
376
  if (def) select.value = def;
377
  label.appendChild(select); ctrl.appendChild(label);
378
 
379
- const applyAll = (v) => instances.forEach(i => i && typeof i.setMetric === 'function' && i.setMetric(v));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  if (def) applyAll(def);
381
  select.addEventListener('change', () => applyAll(select.value));
382
 
 
127
  const xScale = d3.scaleLinear(); const yScale = d3.scaleLinear();
128
  const lineGen = d3.line().x(d => xScale(d.step)).y(d => yScale(d.value));
129
  let isRankStrictFlag = false; let rankTickMax = 1;
130
+ // Remember last render params to support resize re-render with shared domain
131
+ let lastMetricKey = null; let lastSharedDomain = null;
132
 
133
  // Colors and markers (match original embeds)
134
  const primary = getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim() || '#E889AB';
 
215
  return { innerWidth, innerHeight, tickColor };
216
  }
217
 
218
+ function renderMetric(metricKey, sharedDomain){
219
  const map = dataByMetric.get(metricKey) || {};
220
  const runs = runOrder;
221
  let minStep = Infinity, maxStep = -Infinity, maxVal = 0, minVal = Infinity;
222
  const isRank = /rank/i.test(metricKey); const isAverage = /average/i.test(metricKey); const isRankStrict = isRank && !isAverage;
223
  runs.forEach(r => { (map[r]||[]).forEach(pt => { const v = isRankStrict ? Math.round(pt.value) : pt.value; minStep=Math.min(minStep,pt.step); maxStep=Math.max(maxStep,pt.step); maxVal=Math.max(maxVal,v); minVal=Math.min(minVal,v); }); });
224
  if (!isFinite(minStep) || !isFinite(maxStep)) return;
225
+ xScale.domain([minStep, maxStep]);
226
+ if (isRank) {
227
+ const forcedMax = Array.isArray(sharedDomain) ? sharedDomain[1] : null;
228
+ rankTickMax = Math.max(1, Math.round(forcedMax != null ? forcedMax : maxVal));
229
+ yScale.domain([rankTickMax, 1]);
230
+ } else {
231
+ const dom = Array.isArray(sharedDomain) ? sharedDomain : [minVal, maxVal];
232
+ yScale.domain(dom).nice();
233
+ }
234
  isRankStrictFlag = isRankStrict;
235
+ lastMetricKey = metricKey; lastSharedDomain = Array.isArray(sharedDomain) ? sharedDomain.slice() : null;
236
 
237
  const { innerWidth, innerHeight } = updateScales();
238
 
 
328
  // Par défaut, privilégier average_rank, sinon premier dispo
329
  const preferred = metricList.find(m => /average_rank/i.test(m)) || metricList.find(m => m === 'ai2d_exact_match');
330
  const def = preferred || metricList[0];
331
+ // Initial render (will be overridden with shared domain by bootstrap)
332
  renderMetric(def);
333
+ const ro = window.ResizeObserver ? new ResizeObserver(()=>{ if (lastMetricKey) renderMetric(lastMetricKey, lastSharedDomain); }) : null; if (ro) ro.observe(cell);
334
  if (typeof readyResolve === 'function') readyResolve();
335
  } catch (e) {
336
  const pre = document.createElement('pre'); pre.textContent = 'CSV load error: ' + (e && e.message ? e.message : e);
 
343
  return {
344
  ready,
345
  getMetrics: () => metricList.slice(),
346
+ getExtent: (metricKey) => {
347
+ try {
348
+ const map = dataByMetric.get(metricKey) || {};
349
+ const isRank = /rank/i.test(metricKey); const isAverage = /average/i.test(metricKey); const isRankStrict = isRank && !isAverage;
350
+ let maxVal = -Infinity, minVal = Infinity;
351
+ Object.values(map).forEach(arr => (arr||[]).forEach(pt => {
352
+ const v = isRankStrict ? Math.round(pt.value) : pt.value;
353
+ if (isFinite(v)) { if (v > maxVal) maxVal = v; if (v < minVal) minVal = v; }
354
+ }));
355
+ if (!isFinite(minVal) || !isFinite(maxVal)) return null;
356
+ return { min: minVal, max: maxVal, isRankStrict };
357
+ } catch { return null; }
358
+ },
359
+ setMetric: (m, sharedDomain) => { if (m) renderMetric(m, sharedDomain); }
360
  };
361
  }
362
 
 
401
  if (def) select.value = def;
402
  label.appendChild(select); ctrl.appendChild(label);
403
 
404
+ let currentMetric = def;
405
+ const applyAll = (v) => {
406
+ currentMetric = v;
407
+ const extents = instances.map(i => (i && typeof i.getExtent === 'function') ? i.getExtent(v) : null).filter(Boolean);
408
+ let shared = null;
409
+ if (extents.length) {
410
+ const anyRank = extents.some(e => e && e.isRankStrict);
411
+ if (anyRank) {
412
+ const maxRank = Math.max.apply(null, extents.map(e => e.max));
413
+ shared = [1, maxRank];
414
+ } else {
415
+ const min = Math.min.apply(null, extents.map(e => e.min));
416
+ const max = Math.max.apply(null, extents.map(e => e.max));
417
+ shared = [min, max];
418
+ }
419
+ }
420
+ instances.forEach(i => i && typeof i.setMetric === 'function' && i.setMetric(v, shared));
421
+ };
422
  if (def) applyAll(def);
423
  select.addEventListener('change', () => applyAll(select.value));
424