mnm-matin commited on
Commit
c89e8a4
·
verified ·
1 Parent(s): 936c483

Open DeepFashion demo as business-first results view

Browse files
.hyperview/extensions/fashion-search-readout/panel.js CHANGED
@@ -348,7 +348,7 @@ function SearchResultComparison({ item, models, loadingKey, onSelectResult }) {
348
  React.createElement(
349
  "div",
350
  { style: { color: colors.mutedText, fontSize: 10, marginTop: 3 } },
351
- "Green card = exact product. Click any card to select it in the map.",
352
  ),
353
  ),
354
  models.map((model) =>
@@ -378,7 +378,7 @@ function ExactTargetActions({ item, models, loadingKey, onSelectQuery }) {
378
  const neighborLine =
379
  typeof summary.categoryHits === "number"
380
  ? `${summary.categoryHits}/${summary.total || 10} same-category image neighbors`
381
- : "Open the map to inspect image neighbors";
382
  const choiceKey = `${item.queryId}:${model.key}`;
383
  return React.createElement(
384
  "button",
@@ -387,7 +387,7 @@ function ExactTargetActions({ item, models, loadingKey, onSelectQuery }) {
387
  type: "button",
388
  onClick: () => onSelectQuery(item, model),
389
  disabled: loadingKey === choiceKey,
390
- title: `Select target item and inspect ${model.displayName} image neighbors`,
391
  style: {
392
  border: `1px solid ${modelBorder(model)}`,
393
  borderRadius: 5,
@@ -437,6 +437,7 @@ export default function FashionSearchComparisonPanel() {
437
  const [panelError, setPanelError] = React.useState(null);
438
  const [loadingKey, setLoadingKey] = React.useState(null);
439
  const [selectedExampleId, setSelectedExampleId] = React.useState(null);
 
440
 
441
  const models = React.useMemo(() => normalizeModels(panelProps.models), [panelProps.models]);
442
  const examples = Array.isArray(panelProps.examples) ? panelProps.examples : [];
@@ -458,6 +459,35 @@ export default function FashionSearchComparisonPanel() {
458
  { label: "Image-to-image mAP", hyper3: metrics.imageRetrievalMapHyper3, clip: metrics.imageRetrievalMapClip },
459
  ];
460
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  const clearSelection = async () => {
462
  if (commands.setLabelFilter) commands.setLabelFilter(null);
463
  setPanelError(null);
@@ -549,7 +579,7 @@ export default function FashionSearchComparisonPanel() {
549
  React.createElement(
550
  TextBlock,
551
  null,
552
- "Choose a typed product search, then compare the ranked image results.",
553
  ),
554
  examples.length
555
  ? React.createElement(ExampleChooser, {
@@ -577,7 +607,7 @@ export default function FashionSearchComparisonPanel() {
577
  React.createElement(
578
  TextBlock,
579
  null,
580
- `Select the same target product in the map: ${selectedExample?.targetTitle || "target product"}.`,
581
  ),
582
  selectedExample && models.length
583
  ? React.createElement(ExactTargetActions, {
 
348
  React.createElement(
349
  "div",
350
  { style: { color: colors.mutedText, fontSize: 10, marginTop: 3 } },
351
+ "Green card = exact product. Map context is optional and hidden by default.",
352
  ),
353
  ),
354
  models.map((model) =>
 
378
  const neighborLine =
379
  typeof summary.categoryHits === "number"
380
  ? `${summary.categoryHits}/${summary.total || 10} same-category image neighbors`
381
+ : "Neighbor context available in HyperView";
382
  const choiceKey = `${item.queryId}:${model.key}`;
383
  return React.createElement(
384
  "button",
 
387
  type: "button",
388
  onClick: () => onSelectQuery(item, model),
389
  disabled: loadingKey === choiceKey,
390
+ title: `Select target item for ${model.displayName}`,
391
  style: {
392
  border: `1px solid ${modelBorder(model)}`,
393
  borderRadius: 5,
 
437
  const [panelError, setPanelError] = React.useState(null);
438
  const [loadingKey, setLoadingKey] = React.useState(null);
439
  const [selectedExampleId, setSelectedExampleId] = React.useState(null);
440
+ const didApplyDemoLayout = React.useRef(false);
441
 
442
  const models = React.useMemo(() => normalizeModels(panelProps.models), [panelProps.models]);
443
  const examples = Array.isArray(panelProps.examples) ? panelProps.examples : [];
 
459
  { label: "Image-to-image mAP", hyper3: metrics.imageRetrievalMapHyper3, clip: metrics.imageRetrievalMapClip },
460
  ];
461
 
462
+ React.useEffect(() => {
463
+ if (didApplyDemoLayout.current) return;
464
+ didApplyDemoLayout.current = true;
465
+
466
+ const timer = window.setTimeout(() => {
467
+ [
468
+ "explorer",
469
+ "grid",
470
+ "scatter-euclidean",
471
+ "scatter-poincare",
472
+ "scatter-spherical",
473
+ "scatter-euclidean-3d",
474
+ "scatter-spherical-3d",
475
+ "scatter-default",
476
+ "fashion-map-clip",
477
+ "fashion-map-hyper3",
478
+ ].forEach((panelId) => {
479
+ try {
480
+ commands.closePanel?.(panelId);
481
+ } catch (_error) {
482
+ // Older HyperView builds may not have every panel id; ignore missing panes.
483
+ }
484
+ });
485
+ commands.focusPanel?.("fashion-text-search-readout");
486
+ }, 350);
487
+
488
+ return () => window.clearTimeout(timer);
489
+ }, [commands]);
490
+
491
  const clearSelection = async () => {
492
  if (commands.setLabelFilter) commands.setLabelFilter(null);
493
  setPanelError(null);
 
579
  React.createElement(
580
  TextBlock,
581
  null,
582
+ "Choose a typed product search. The ranked cards are the demo; map context is secondary.",
583
  ),
584
  examples.length
585
  ? React.createElement(ExampleChooser, {
 
607
  React.createElement(
608
  TextBlock,
609
  null,
610
+ `Exact-target summary for: ${selectedExample?.targetTitle || "target product"}.`,
611
  ),
612
  selectedExample && models.length
613
  ? React.createElement(ExactTargetActions, {
Dockerfile CHANGED
@@ -45,8 +45,8 @@ ENV HYPERVIEW_HOST=0.0.0.0 \
45
  HYPERVIEW_WORKSPACE_ID=fashion-deepfashion-text-search \
46
  HYPERVIEW_DATASETS_DIR=/home/user/app/demo_data/datasets \
47
  HYPERVIEW_MEDIA_DIR=/home/user/app/demo_data/media \
48
- DEEPFASHION_SAMPLES_PER_CATEGORY=24 \
49
- DEEPFASHION_MAX_SAMPLES=420 \
50
  HF_HUB_ETAG_TIMEOUT=30 \
51
  HF_HUB_DOWNLOAD_TIMEOUT=120
52
 
 
45
  HYPERVIEW_WORKSPACE_ID=fashion-deepfashion-text-search \
46
  HYPERVIEW_DATASETS_DIR=/home/user/app/demo_data/datasets \
47
  HYPERVIEW_MEDIA_DIR=/home/user/app/demo_data/media \
48
+ DEEPFASHION_SAMPLES_PER_CATEGORY=10 \
49
+ DEEPFASHION_MAX_SAMPLES=180 \
50
  HF_HUB_ETAG_TIMEOUT=30 \
51
  HF_HUB_DOWNLOAD_TIMEOUT=120
52
 
demo.py CHANGED
@@ -405,11 +405,16 @@ def build_examples(dataset: hv.Dataset) -> list[dict[str, Any]]:
405
  def build_demo_view(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.ui.View:
406
  readout_panel = hv.ui.ExtensionPanel(
407
  id="fashion-text-search-readout",
408
- title="Shopper Text Search Proof",
409
  extension="fashion-search-readout",
410
  panel="fashion-comparison",
411
  position="center",
412
  props={
 
 
 
 
 
413
  "models": model_panel_props(layouts),
414
  "examples": build_examples(dataset),
415
  "warnings": RUNTIME_WARNINGS,
@@ -433,7 +438,36 @@ def build_demo_view(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.ui.View:
433
  },
434
  },
435
  )
436
- return hv.ui.View(readout_panel)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
 
438
 
439
  def launch_demo(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.Session:
 
405
  def build_demo_view(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.ui.View:
406
  readout_panel = hv.ui.ExtensionPanel(
407
  id="fashion-text-search-readout",
408
+ title="Retail Search Results",
409
  extension="fashion-search-readout",
410
  panel="fashion-comparison",
411
  position="center",
412
  props={
413
+ "dockview": {
414
+ "closeSamplesPanel": True,
415
+ "hideExplorerPanel": True,
416
+ "minimumWidth": 620,
417
+ },
418
  "models": model_panel_props(layouts),
419
  "examples": build_examples(dataset),
420
  "warnings": RUNTIME_WARNINGS,
 
438
  },
439
  },
440
  )
441
+
442
+ clip_spec = MODEL_SPECS[0]
443
+ candidate_spec = MODEL_SPECS[1]
444
+ map_dockview = {
445
+ "initialWidth": int(os.environ.get("FASHION_MAP_CONTEXT_WIDTH", "340")),
446
+ "minimumWidth": 260,
447
+ }
448
+ clip_map = hv.ui.Scatter(
449
+ id="fashion-map-clip",
450
+ title="Context Map: CLIP",
451
+ layout_key=layouts["clip"],
452
+ position="center",
453
+ reference_panel_id="fashion-text-search-readout",
454
+ direction="right",
455
+ geometry=clip_spec["geometry"],
456
+ layout_dimension=clip_spec["layout_dimension"],
457
+ props={"dockview": map_dockview},
458
+ )
459
+ candidate_map = hv.ui.Scatter(
460
+ id="fashion-map-hyper3",
461
+ title="Context Map: Hyper3",
462
+ layout_key=layouts["candidate"],
463
+ position="center",
464
+ reference_panel_id="fashion-map-clip",
465
+ direction="within",
466
+ geometry=candidate_spec["geometry"],
467
+ layout_dimension=candidate_spec["layout_dimension"],
468
+ props={"dockview": map_dockview},
469
+ )
470
+ return hv.ui.View(readout_panel, clip_map, candidate_map)
471
 
472
 
473
  def launch_demo(dataset: hv.Dataset, layouts: dict[str, str]) -> hv.Session: