thibaud frere commited on
Commit
281e5ea
·
1 Parent(s): 4da5277

fix chart responsiveness

Browse files
app/src/content/embeds/against-baselines-deduplicated.html CHANGED
@@ -330,6 +330,20 @@
330
  }
331
  } catch {}
332
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  // Update clip rect to match inner plotting area with padding so
334
  // first/last markers are not clipped at the edges
335
  const clipPad = Math.max(6, Math.ceil(markerSize * 2));
@@ -368,6 +382,16 @@
368
  // Axes
369
  gAxes.selectAll('*').remove();
370
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
371
  if (isRankStrictFlag) {
372
  const [dx0, dx1] = xScale.domain();
373
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -375,9 +399,10 @@
375
  const xTicks = [];
376
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
377
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
378
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
379
  } else {
380
  xAxis = xAxis.ticks(8);
 
381
  }
382
  const yAxis = d3.axisLeft(yScale)
383
  .tickValues(yTicks)
 
330
  }
331
  } catch {}
332
 
333
+ // Mobile layout: stack legend above select, allow legend to take full width
334
+ try {
335
+ const isMobile = width < 640;
336
+ if (controls && controls.style && labelMetric && labelMetric.style) {
337
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
338
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
339
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
340
+ if (legendInline && legendInline.style) {
341
+ legendInline.style.width = isMobile ? '100%' : '';
342
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
343
+ }
344
+ }
345
+ } catch {}
346
+
347
  // Update clip rect to match inner plotting area with padding so
348
  // first/last markers are not clipped at the edges
349
  const clipPad = Math.max(6, Math.ceil(markerSize * 2));
 
382
  // Axes
383
  gAxes.selectAll('*').remove();
384
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
385
+ const isMobileTicks = width < 640;
386
+ const tfMobile = (d) => {
387
+ const abs = Math.abs(d);
388
+ if (abs >= 1000) {
389
+ const v = d / 1000;
390
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
391
+ return out + 'k';
392
+ }
393
+ return d3.format('d')(d);
394
+ };
395
  if (isRankStrictFlag) {
396
  const [dx0, dx1] = xScale.domain();
397
  const start = Math.ceil(dx0 / 1000) * 1000;
 
399
  const xTicks = [];
400
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
401
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
402
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
403
  } else {
404
  xAxis = xAxis.ticks(8);
405
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
406
  }
407
  const yAxis = d3.axisLeft(yScale)
408
  .tickValues(yTicks)
app/src/content/embeds/against-baselines.html CHANGED
@@ -328,6 +328,20 @@
328
  }
329
  } catch {}
330
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  xScale.range([0, innerWidth]);
332
  yScale.range([innerHeight, 0]);
333
 
@@ -365,6 +379,16 @@
365
  // Axes
366
  gAxes.selectAll('*').remove();
367
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
368
  if (isRankStrictFlag) {
369
  const [dx0, dx1] = xScale.domain();
370
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -372,9 +396,10 @@
372
  const xTicks = [];
373
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
374
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
375
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
376
  } else {
377
  xAxis = xAxis.ticks(8);
 
378
  }
379
  const yAxis = d3.axisLeft(yScale)
380
  .tickValues(yTicks)
 
328
  }
329
  } catch {}
330
 
331
+ // Mobile layout: stack legend above select, allow legend to take full width
332
+ try {
333
+ const isMobile = width < 640;
334
+ if (controls && controls.style && labelMetric && labelMetric.style) {
335
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
336
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
337
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
338
+ if (legendInline && legendInline.style) {
339
+ legendInline.style.width = isMobile ? '100%' : '';
340
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
341
+ }
342
+ }
343
+ } catch {}
344
+
345
  xScale.range([0, innerWidth]);
346
  yScale.range([innerHeight, 0]);
347
 
 
379
  // Axes
380
  gAxes.selectAll('*').remove();
381
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
382
+ const isMobileTicks = width < 640;
383
+ const tfMobile = (d) => {
384
+ const abs = Math.abs(d);
385
+ if (abs >= 1000) {
386
+ const v = d / 1000;
387
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
388
+ return out + 'k';
389
+ }
390
+ return d3.format('d')(d);
391
+ };
392
  if (isRankStrictFlag) {
393
  const [dx0, dx1] = xScale.domain();
394
  const start = Math.ceil(dx0 / 1000) * 1000;
 
396
  const xTicks = [];
397
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
398
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
399
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
400
  } else {
401
  xAxis = xAxis.ticks(8);
402
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
403
  }
404
  const yAxis = d3.axisLeft(yScale)
405
  .tickValues(yTicks)
app/src/content/embeds/all-ratings.html CHANGED
@@ -318,6 +318,20 @@
318
  }
319
  } catch {}
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  xScale.range([0, innerWidth]);
322
  yScale.range([innerHeight, 0]);
323
 
@@ -347,6 +361,16 @@
347
  // Axes
348
  gAxes.selectAll('*').remove();
349
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
350
  if (isRankStrictFlag) {
351
  const [dx0, dx1] = xScale.domain();
352
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -354,9 +378,10 @@
354
  const xTicks = [];
355
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
356
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
357
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
358
  } else {
359
  xAxis = xAxis.ticks(8);
 
360
  }
361
  const yAxis = d3.axisLeft(yScale)
362
  .tickValues(yTicks)
@@ -415,6 +440,20 @@
415
  color: 'var(--text-color)'
416
  });
417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  return { innerWidth, innerHeight };
419
  }
420
 
 
318
  }
319
  } catch {}
320
 
321
+ // Mobile layout: stack legend above select, allow legend to take full width
322
+ try {
323
+ const isMobile = width < 640;
324
+ if (controls && controls.style && labelMetric && labelMetric.style) {
325
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
326
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
327
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
328
+ if (legendInline && legendInline.style) {
329
+ legendInline.style.width = isMobile ? '100%' : '';
330
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
331
+ }
332
+ }
333
+ } catch {}
334
+
335
  xScale.range([0, innerWidth]);
336
  yScale.range([innerHeight, 0]);
337
 
 
361
  // Axes
362
  gAxes.selectAll('*').remove();
363
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
364
+ const isMobileTicks = width < 640;
365
+ const tfMobile = (d) => {
366
+ const abs = Math.abs(d);
367
+ if (abs >= 1000) {
368
+ const v = d / 1000;
369
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
370
+ return out + 'k';
371
+ }
372
+ return d3.format('d')(d);
373
+ };
374
  if (isRankStrictFlag) {
375
  const [dx0, dx1] = xScale.domain();
376
  const start = Math.ceil(dx0 / 1000) * 1000;
 
378
  const xTicks = [];
379
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
380
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
381
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
382
  } else {
383
  xAxis = xAxis.ticks(8);
384
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
385
  }
386
  const yAxis = d3.axisLeft(yScale)
387
  .tickValues(yTicks)
 
440
  color: 'var(--text-color)'
441
  });
442
 
443
+ // Mobile layout: stack legend above select, allow legend to take full width
444
+ try {
445
+ const isMobile = width < 640;
446
+ if (controls && controls.style && labelMetric && labelMetric.style) {
447
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
448
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
449
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
450
+ if (legendInline && legendInline.style) {
451
+ legendInline.style.width = isMobile ? '100%' : '';
452
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
453
+ }
454
+ }
455
+ } catch {}
456
+
457
  return { innerWidth, innerHeight };
458
  }
459
 
app/src/content/embeds/filters-quad.html CHANGED
@@ -202,6 +202,18 @@
202
  // Axes
203
  gAxes.selectAll('*').remove();
204
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0); xAxis = xAxis.ticks(8);
 
 
 
 
 
 
 
 
 
 
 
 
205
  const yAxis = d3.axisLeft(yScale).tickValues(yTicks).tickSizeOuter(0).tickFormat(isRankStrictFlag ? d3.format('d') : d3.format('.2f'));
206
  gAxes.append('g').attr('transform', `translate(0,${innerHeight})`).call(xAxis).call(g=>{ g.selectAll('path, line').attr('stroke',axisColor); g.selectAll('text').attr('fill',tickColor).style('font-size','11px'); });
207
  gAxes.append('g').call(yAxis).call(g=>{ g.selectAll('path, line').attr('stroke',axisColor); g.selectAll('text').attr('fill',tickColor).style('font-size','11px'); });
@@ -452,6 +464,36 @@
452
  }
453
  } catch {}
454
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
455
  })();
456
  };
457
 
 
202
  // Axes
203
  gAxes.selectAll('*').remove();
204
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0); xAxis = xAxis.ticks(8);
205
+ // Mobile tick formatter: 2k/2.5k instead of 2,000
206
+ const isMobileTicks = width < 640;
207
+ const tfMobile = (d) => {
208
+ const abs = Math.abs(d);
209
+ if (abs >= 1000) {
210
+ const v = d / 1000;
211
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
212
+ return out + 'k';
213
+ }
214
+ return d3.format('d')(d);
215
+ };
216
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
217
  const yAxis = d3.axisLeft(yScale).tickValues(yTicks).tickSizeOuter(0).tickFormat(isRankStrictFlag ? d3.format('d') : d3.format('.2f'));
218
  gAxes.append('g').attr('transform', `translate(0,${innerHeight})`).call(xAxis).call(g=>{ g.selectAll('path, line').attr('stroke',axisColor); g.selectAll('text').attr('fill',tickColor).style('font-size','11px'); });
219
  gAxes.append('g').call(yAxis).call(g=>{ g.selectAll('path, line').attr('stroke',axisColor); g.selectAll('text').attr('fill',tickColor).style('font-size','11px'); });
 
464
  }
465
  } catch {}
466
  }
467
+
468
+ // Mobile layout: legend above controls and full-width stacks
469
+ function adjustGlobalLayout(){
470
+ try {
471
+ const rect = host.getBoundingClientRect();
472
+ const isMobile = rect && rect.width < 640;
473
+ const ctrl = host.querySelector('.filters-quad__controls');
474
+ const legend = host.querySelector('.filters-quad__legend');
475
+ if (!ctrl || !legend) return;
476
+ if (isMobile) {
477
+ if (legend.nextElementSibling !== ctrl) {
478
+ host.insertBefore(legend, ctrl);
479
+ }
480
+ ctrl.style.justifyContent = 'flex-start';
481
+ legend.style.justifyContent = 'flex-start';
482
+ ctrl.style.width = '100%';
483
+ legend.style.width = '100%';
484
+ } else {
485
+ if (ctrl.nextElementSibling !== legend) {
486
+ host.insertBefore(ctrl, legend);
487
+ }
488
+ ctrl.style.justifyContent = '';
489
+ legend.style.justifyContent = '';
490
+ ctrl.style.width = '';
491
+ legend.style.width = '';
492
+ }
493
+ } catch {}
494
+ }
495
+ adjustGlobalLayout();
496
+ if (window.ResizeObserver) { const ro = new ResizeObserver(()=>adjustGlobalLayout()); ro.observe(host); }
497
  })();
498
  };
499
 
app/src/content/embeds/formatting-filters.html CHANGED
@@ -318,6 +318,20 @@
318
  }
319
  } catch {}
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  xScale.range([0, innerWidth]);
322
  yScale.range([innerHeight, 0]);
323
 
@@ -347,6 +361,16 @@
347
  // Axes
348
  gAxes.selectAll('*').remove();
349
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
350
  if (isRankStrictFlag) {
351
  const [dx0, dx1] = xScale.domain();
352
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -354,9 +378,10 @@
354
  const xTicks = [];
355
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
356
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
357
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
358
  } else {
359
  xAxis = xAxis.ticks(8);
 
360
  }
361
  const yAxis = d3.axisLeft(yScale)
362
  .tickValues(yTicks)
 
318
  }
319
  } catch {}
320
 
321
+ // Mobile layout: stack legend above select, allow legend to take full width
322
+ try {
323
+ const isMobile = width < 640;
324
+ if (controls && controls.style && labelMetric && labelMetric.style) {
325
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
326
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
327
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
328
+ if (legendInline && legendInline.style) {
329
+ legendInline.style.width = isMobile ? '100%' : '';
330
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
331
+ }
332
+ }
333
+ } catch {}
334
+
335
  xScale.range([0, innerWidth]);
336
  yScale.range([innerHeight, 0]);
337
 
 
361
  // Axes
362
  gAxes.selectAll('*').remove();
363
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
364
+ const isMobileTicks = width < 640;
365
+ const tfMobile = (d) => {
366
+ const abs = Math.abs(d);
367
+ if (abs >= 1000) {
368
+ const v = d / 1000;
369
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
370
+ return out + 'k';
371
+ }
372
+ return d3.format('d')(d);
373
+ };
374
  if (isRankStrictFlag) {
375
  const [dx0, dx1] = xScale.domain();
376
  const start = Math.ceil(dx0 / 1000) * 1000;
 
378
  const xTicks = [];
379
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
380
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
381
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
382
  } else {
383
  xAxis = xAxis.ticks(8);
384
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
385
  }
386
  const yAxis = d3.axisLeft(yScale)
387
  .tickValues(yTicks)
app/src/content/embeds/image-correspondence-filters.html CHANGED
@@ -318,6 +318,20 @@
318
  }
319
  } catch {}
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  xScale.range([0, innerWidth]);
322
  yScale.range([innerHeight, 0]);
323
 
@@ -347,6 +361,16 @@
347
  // Axes
348
  gAxes.selectAll('*').remove();
349
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
350
  if (isRankStrictFlag) {
351
  const [dx0, dx1] = xScale.domain();
352
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -354,9 +378,10 @@
354
  const xTicks = [];
355
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
356
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
357
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
358
  } else {
359
  xAxis = xAxis.ticks(8);
 
360
  }
361
  const yAxis = d3.axisLeft(yScale)
362
  .tickValues(yTicks)
@@ -415,6 +440,20 @@
415
  color: 'var(--text-color)'
416
  });
417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  return { innerWidth, innerHeight };
419
  }
420
 
 
318
  }
319
  } catch {}
320
 
321
+ // Mobile layout: stack legend above select, allow legend to take full width
322
+ try {
323
+ const isMobile = width < 640;
324
+ if (controls && controls.style && labelMetric && labelMetric.style) {
325
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
326
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
327
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
328
+ if (legendInline && legendInline.style) {
329
+ legendInline.style.width = isMobile ? '100%' : '';
330
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
331
+ }
332
+ }
333
+ } catch {}
334
+
335
  xScale.range([0, innerWidth]);
336
  yScale.range([innerHeight, 0]);
337
 
 
361
  // Axes
362
  gAxes.selectAll('*').remove();
363
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
364
+ const isMobileTicks = width < 640;
365
+ const tfMobile = (d) => {
366
+ const abs = Math.abs(d);
367
+ if (abs >= 1000) {
368
+ const v = d / 1000;
369
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
370
+ return out + 'k';
371
+ }
372
+ return d3.format('d')(d);
373
+ };
374
  if (isRankStrictFlag) {
375
  const [dx0, dx1] = xScale.domain();
376
  const start = Math.ceil(dx0 / 1000) * 1000;
 
378
  const xTicks = [];
379
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
380
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
381
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
382
  } else {
383
  xAxis = xAxis.ticks(8);
384
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
385
  }
386
  const yAxis = d3.axisLeft(yScale)
387
  .tickValues(yTicks)
 
440
  color: 'var(--text-color)'
441
  });
442
 
443
+ // Mobile layout: stack legend above select, allow legend to take full width
444
+ try {
445
+ const isMobile = width < 640;
446
+ if (controls && controls.style && labelMetric && labelMetric.style) {
447
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
448
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
449
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
450
+ if (legendInline && legendInline.style) {
451
+ legendInline.style.width = isMobile ? '100%' : '';
452
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
453
+ }
454
+ }
455
+ } catch {}
456
+
457
  return { innerWidth, innerHeight };
458
  }
459
 
app/src/content/embeds/internal-deduplication.html CHANGED
@@ -360,6 +360,16 @@
360
  // Axes
361
  gAxes.selectAll('*').remove();
362
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
363
  if (isRankStrictFlag) {
364
  const [dx0, dx1] = xScale.domain();
365
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -367,9 +377,10 @@
367
  const xTicks = [];
368
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
369
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
370
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
371
  } else {
372
  xAxis = xAxis.ticks(8);
 
373
  }
374
  const yAxis = d3.axisLeft(yScale)
375
  .tickValues(yTicks)
@@ -428,6 +439,20 @@
428
  color: 'var(--text-color)'
429
  });
430
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  return { innerWidth, innerHeight };
432
  }
433
 
 
360
  // Axes
361
  gAxes.selectAll('*').remove();
362
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
363
+ const isMobileTicks = width < 640;
364
+ const tfMobile = (d) => {
365
+ const abs = Math.abs(d);
366
+ if (abs >= 1000) {
367
+ const v = d / 1000;
368
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
369
+ return out + 'k';
370
+ }
371
+ return d3.format('d')(d);
372
+ };
373
  if (isRankStrictFlag) {
374
  const [dx0, dx1] = xScale.domain();
375
  const start = Math.ceil(dx0 / 1000) * 1000;
 
377
  const xTicks = [];
378
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
379
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
380
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
381
  } else {
382
  xAxis = xAxis.ticks(8);
383
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
384
  }
385
  const yAxis = d3.axisLeft(yScale)
386
  .tickValues(yTicks)
 
439
  color: 'var(--text-color)'
440
  });
441
 
442
+ // Mobile layout: stack legend above select, allow legend to take full width
443
+ try {
444
+ const isMobile = width < 640;
445
+ if (controls && controls.style && labelMetric && labelMetric.style) {
446
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
447
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
448
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
449
+ if (legendInline && legendInline.style) {
450
+ legendInline.style.width = isMobile ? '100%' : '';
451
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
452
+ }
453
+ }
454
+ } catch {}
455
+
456
  return { innerWidth, innerHeight };
457
  }
458
 
app/src/content/embeds/relevance-filters.html CHANGED
@@ -318,6 +318,20 @@
318
  }
319
  } catch {}
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  xScale.range([0, innerWidth]);
322
  yScale.range([innerHeight, 0]);
323
 
@@ -347,6 +361,16 @@
347
  // Axes
348
  gAxes.selectAll('*').remove();
349
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
350
  if (isRankStrictFlag) {
351
  const [dx0, dx1] = xScale.domain();
352
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -354,9 +378,10 @@
354
  const xTicks = [];
355
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
356
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
357
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
358
  } else {
359
  xAxis = xAxis.ticks(8);
 
360
  }
361
  const yAxis = d3.axisLeft(yScale)
362
  .tickValues(yTicks)
@@ -415,6 +440,20 @@
415
  color: 'var(--text-color)'
416
  });
417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  return { innerWidth, innerHeight };
419
  }
420
 
 
318
  }
319
  } catch {}
320
 
321
+ // Mobile layout: stack legend above select, allow legend to take full width
322
+ try {
323
+ const isMobile = width < 640;
324
+ if (controls && controls.style && labelMetric && labelMetric.style) {
325
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
326
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
327
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
328
+ if (legendInline && legendInline.style) {
329
+ legendInline.style.width = isMobile ? '100%' : '';
330
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
331
+ }
332
+ }
333
+ } catch {}
334
+
335
  xScale.range([0, innerWidth]);
336
  yScale.range([innerHeight, 0]);
337
 
 
361
  // Axes
362
  gAxes.selectAll('*').remove();
363
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
364
+ const isMobileTicks = width < 640;
365
+ const tfMobile = (d) => {
366
+ const abs = Math.abs(d);
367
+ if (abs >= 1000) {
368
+ const v = d / 1000;
369
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
370
+ return out + 'k';
371
+ }
372
+ return d3.format('d')(d);
373
+ };
374
  if (isRankStrictFlag) {
375
  const [dx0, dx1] = xScale.domain();
376
  const start = Math.ceil(dx0 / 1000) * 1000;
 
378
  const xTicks = [];
379
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
380
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
381
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
382
  } else {
383
  xAxis = xAxis.ticks(8);
384
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
385
  }
386
  const yAxis = d3.axisLeft(yScale)
387
  .tickValues(yTicks)
 
440
  color: 'var(--text-color)'
441
  });
442
 
443
+ // Mobile layout: stack legend above select, allow legend to take full width
444
+ try {
445
+ const isMobile = width < 640;
446
+ if (controls && controls.style && labelMetric && labelMetric.style) {
447
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
448
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
449
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
450
+ if (legendInline && legendInline.style) {
451
+ legendInline.style.width = isMobile ? '100%' : '';
452
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
453
+ }
454
+ }
455
+ } catch {}
456
+
457
  return { innerWidth, innerHeight };
458
  }
459
 
app/src/content/embeds/remove-ch.html CHANGED
@@ -321,6 +321,20 @@
321
  }
322
  } catch {}
323
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  xScale.range([0, innerWidth]);
325
  yScale.range([innerHeight, 0]);
326
 
@@ -350,6 +364,16 @@
350
  // Axes
351
  gAxes.selectAll('*').remove();
352
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
353
  if (isRankStrictFlag) {
354
  const [dx0, dx1] = xScale.domain();
355
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -357,9 +381,10 @@
357
  const xTicks = [];
358
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
359
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
360
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
361
  } else {
362
  xAxis = xAxis.ticks(8);
 
363
  }
364
  const yAxis = d3.axisLeft(yScale)
365
  .tickValues(yTicks)
@@ -418,6 +443,20 @@
418
  color: 'var(--text-color)'
419
  });
420
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  return { innerWidth, innerHeight };
422
  }
423
 
 
321
  }
322
  } catch {}
323
 
324
+ // Mobile layout: stack legend above select, allow legend to take full width
325
+ try {
326
+ const isMobile = width < 640;
327
+ if (controls && controls.style && labelMetric && labelMetric.style) {
328
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
329
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
330
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
331
+ if (legendInline && legendInline.style) {
332
+ legendInline.style.width = isMobile ? '100%' : '';
333
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
334
+ }
335
+ }
336
+ } catch {}
337
+
338
  xScale.range([0, innerWidth]);
339
  yScale.range([innerHeight, 0]);
340
 
 
364
  // Axes
365
  gAxes.selectAll('*').remove();
366
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
367
+ const isMobileTicks = width < 640;
368
+ const tfMobile = (d) => {
369
+ const abs = Math.abs(d);
370
+ if (abs >= 1000) {
371
+ const v = d / 1000;
372
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
373
+ return out + 'k';
374
+ }
375
+ return d3.format('d')(d);
376
+ };
377
  if (isRankStrictFlag) {
378
  const [dx0, dx1] = xScale.domain();
379
  const start = Math.ceil(dx0 / 1000) * 1000;
 
381
  const xTicks = [];
382
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
383
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
384
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
385
  } else {
386
  xAxis = xAxis.ticks(8);
387
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
388
  }
389
  const yAxis = d3.axisLeft(yScale)
390
  .tickValues(yTicks)
 
443
  color: 'var(--text-color)'
444
  });
445
 
446
+ // Mobile layout: stack legend above select, allow legend to take full width
447
+ try {
448
+ const isMobile = width < 640;
449
+ if (controls && controls.style && labelMetric && labelMetric.style) {
450
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
451
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
452
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
453
+ if (legendInline && legendInline.style) {
454
+ legendInline.style.width = isMobile ? '100%' : '';
455
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
456
+ }
457
+ }
458
+ } catch {}
459
+
460
  return { innerWidth, innerHeight };
461
  }
462
 
app/src/content/embeds/s25-ratings.html CHANGED
@@ -347,6 +347,16 @@
347
  // Axes
348
  gAxes.selectAll('*').remove();
349
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
350
  if (isRankStrictFlag) {
351
  const [dx0, dx1] = xScale.domain();
352
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -354,9 +364,10 @@
354
  const xTicks = [];
355
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
356
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
357
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
358
  } else {
359
  xAxis = xAxis.ticks(8);
 
360
  }
361
  const yAxis = d3.axisLeft(yScale)
362
  .tickValues(yTicks)
@@ -376,6 +387,20 @@
376
  g.selectAll('text').attr('fill', tickColor).style('font-size', '12px');
377
  });
378
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  // Axis labels (X and Y)
380
  gAxes.append('text')
381
  .attr('class', 'axis-label axis-label--x')
 
347
  // Axes
348
  gAxes.selectAll('*').remove();
349
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
350
+ const isMobileTicks = width < 640;
351
+ const tfMobile = (d) => {
352
+ const abs = Math.abs(d);
353
+ if (abs >= 1000) {
354
+ const v = d / 1000;
355
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
356
+ return out + 'k';
357
+ }
358
+ return d3.format('d')(d);
359
+ };
360
  if (isRankStrictFlag) {
361
  const [dx0, dx1] = xScale.domain();
362
  const start = Math.ceil(dx0 / 1000) * 1000;
 
364
  const xTicks = [];
365
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
366
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
367
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
368
  } else {
369
  xAxis = xAxis.ticks(8);
370
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
371
  }
372
  const yAxis = d3.axisLeft(yScale)
373
  .tickValues(yTicks)
 
387
  g.selectAll('text').attr('fill', tickColor).style('font-size', '12px');
388
  });
389
 
390
+ // Mobile layout: stack legend above select, allow legend to take full width
391
+ try {
392
+ const isMobile = width < 640;
393
+ if (controls && controls.style && labelMetric && labelMetric.style) {
394
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
395
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
396
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
397
+ if (legendInline && legendInline.style) {
398
+ legendInline.style.width = isMobile ? '100%' : '';
399
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
400
+ }
401
+ }
402
+ } catch {}
403
+
404
  // Axis labels (X and Y)
405
  gAxes.append('text')
406
  .attr('class', 'axis-label axis-label--x')
app/src/content/embeds/ss-vs-s1.html CHANGED
@@ -318,6 +318,20 @@
318
  }
319
  } catch {}
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  xScale.range([0, innerWidth]);
322
  yScale.range([innerHeight, 0]);
323
 
@@ -347,6 +361,16 @@
347
  // Axes
348
  gAxes.selectAll('*').remove();
349
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
350
  if (isRankStrictFlag) {
351
  const [dx0, dx1] = xScale.domain();
352
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -354,9 +378,10 @@
354
  const xTicks = [];
355
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
356
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
357
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
358
  } else {
359
  xAxis = xAxis.ticks(8);
 
360
  }
361
  const yAxis = d3.axisLeft(yScale)
362
  .tickValues(yTicks)
@@ -415,6 +440,20 @@
415
  color: 'var(--text-color)'
416
  });
417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  return { innerWidth, innerHeight };
419
  }
420
 
 
318
  }
319
  } catch {}
320
 
321
+ // Mobile layout: stack legend above select, allow legend to take full width
322
+ try {
323
+ const isMobile = width < 640;
324
+ if (controls && controls.style && labelMetric && labelMetric.style) {
325
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
326
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
327
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
328
+ if (legendInline && legendInline.style) {
329
+ legendInline.style.width = isMobile ? '100%' : '';
330
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
331
+ }
332
+ }
333
+ } catch {}
334
+
335
  xScale.range([0, innerWidth]);
336
  yScale.range([innerHeight, 0]);
337
 
 
361
  // Axes
362
  gAxes.selectAll('*').remove();
363
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
364
+ const isMobileTicks = width < 640;
365
+ const tfMobile = (d) => {
366
+ const abs = Math.abs(d);
367
+ if (abs >= 1000) {
368
+ const v = d / 1000;
369
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
370
+ return out + 'k';
371
+ }
372
+ return d3.format('d')(d);
373
+ };
374
  if (isRankStrictFlag) {
375
  const [dx0, dx1] = xScale.domain();
376
  const start = Math.ceil(dx0 / 1000) * 1000;
 
378
  const xTicks = [];
379
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
380
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
381
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
382
  } else {
383
  xAxis = xAxis.ticks(8);
384
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
385
  }
386
  const yAxis = d3.axisLeft(yScale)
387
  .tickValues(yTicks)
 
440
  color: 'var(--text-color)'
441
  });
442
 
443
+ // Mobile layout: stack legend above select, allow legend to take full width
444
+ try {
445
+ const isMobile = width < 640;
446
+ if (controls && controls.style && labelMetric && labelMetric.style) {
447
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
448
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
449
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
450
+ if (legendInline && legendInline.style) {
451
+ legendInline.style.width = isMobile ? '100%' : '';
452
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
453
+ }
454
+ }
455
+ } catch {}
456
+
457
  return { innerWidth, innerHeight };
458
  }
459
 
app/src/content/embeds/visual-dependency-filters.html CHANGED
@@ -360,6 +360,16 @@
360
  // Axes
361
  gAxes.selectAll('*').remove();
362
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
 
 
 
 
 
 
 
 
 
 
363
  if (isRankStrictFlag) {
364
  const [dx0, dx1] = xScale.domain();
365
  const start = Math.ceil(dx0 / 1000) * 1000;
@@ -367,9 +377,10 @@
367
  const xTicks = [];
368
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
369
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
370
- xAxis = xAxis.tickValues(xTicks).tickFormat(d3.format('d'));
371
  } else {
372
  xAxis = xAxis.ticks(8);
 
373
  }
374
  const yAxis = d3.axisLeft(yScale)
375
  .tickValues(yTicks)
@@ -428,6 +439,20 @@
428
  color: 'var(--text-color)'
429
  });
430
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  return { innerWidth, innerHeight };
432
  }
433
 
 
360
  // Axes
361
  gAxes.selectAll('*').remove();
362
  let xAxis = d3.axisBottom(xScale).tickSizeOuter(0);
363
+ const isMobileTicks = width < 640;
364
+ const tfMobile = (d) => {
365
+ const abs = Math.abs(d);
366
+ if (abs >= 1000) {
367
+ const v = d / 1000;
368
+ const out = Math.abs(v) >= 10 ? Math.round(v) : +v.toFixed(1);
369
+ return out + 'k';
370
+ }
371
+ return d3.format('d')(d);
372
+ };
373
  if (isRankStrictFlag) {
374
  const [dx0, dx1] = xScale.domain();
375
  const start = Math.ceil(dx0 / 1000) * 1000;
 
377
  const xTicks = [];
378
  for (let v = start; v <= end; v += 1000) xTicks.push(v);
379
  if (xTicks.length === 0) xTicks.push(Math.round(dx0));
380
+ xAxis = xAxis.tickValues(xTicks).tickFormat(isMobileTicks ? tfMobile : d3.format('d'));
381
  } else {
382
  xAxis = xAxis.ticks(8);
383
+ if (isMobileTicks) xAxis = xAxis.tickFormat(tfMobile);
384
  }
385
  const yAxis = d3.axisLeft(yScale)
386
  .tickValues(yTicks)
 
439
  color: 'var(--text-color)'
440
  });
441
 
442
+ // Mobile layout: stack legend above select, allow legend to take full width
443
+ try {
444
+ const isMobile = width < 640;
445
+ if (controls && controls.style && labelMetric && labelMetric.style) {
446
+ controls.style.flexDirection = isMobile ? 'column' : 'row';
447
+ controls.style.alignItems = isMobile ? 'flex-start' : 'center';
448
+ labelMetric.style.marginLeft = isMobile ? '0' : 'auto';
449
+ if (legendInline && legendInline.style) {
450
+ legendInline.style.width = isMobile ? '100%' : '';
451
+ legendInline.style.justifyContent = isMobile ? 'flex-start' : '';
452
+ }
453
+ }
454
+ } catch {}
455
+
456
  return { innerWidth, innerHeight };
457
  }
458