multimodalart HF Staff commited on
Commit
dcdcbbd
·
verified ·
1 Parent(s): cf48977

remove Demos tab

Browse files
Files changed (2) hide show
  1. explore.js +4 -188
  2. index.html +1 -1
explore.js CHANGED
@@ -601,173 +601,6 @@ function renderPeriods() {
601
  drawLegend([]);
602
  }
603
 
604
- // ---------- demos leaderboard ----------
605
- function renderDemos() {
606
- const eligible = new Set(filteredCompanies().filter(c => !state.hidden.has(c)));
607
- const focus = [...state.pins].filter(c => eligible.has(c));
608
- const pass = c => focus.length ? focus.includes(c) : eligible.has(c);
609
- const { all } = visibleEntities(); // for stable company colors
610
- const compColor = {}; all.forEach(e => compColor[e.name] = e.color);
611
-
612
- const rows = UI_DATA.demos
613
- .filter(d => d.cs.some(pass))
614
- .map(d => {
615
- let b = null, v = null;
616
- for (let i = state.i0; i <= state.i1; i++) if (d.V[i] != null) { if (b == null) b = d.V[i]; v = d.V[i]; }
617
- const val = v == null ? null : (state.allRepos ? v : v - b);
618
- return { ...d, val };
619
- })
620
- .filter(d => d.val != null && d.val > 0)
621
- .sort((a, b) => b.val - a.val)
622
- .slice(0, Math.max(state.topN, 5));
623
-
624
- const ROW = 52, IW = CW - M.left - M.right;
625
- const H = M.top + rows.length * ROW + 46;
626
- const svg = baseSvg(H);
627
- const g = svg.append("g").attr("transform", `translate(${M.left + 130},${M.top})`);
628
- const maxV = d3.max(rows, d => d.val) || 1;
629
- const x = d3.scaleLinear().domain([0, maxV * 1.06]).range([0, IW - 130]);
630
- g.selectAll(".gridline").data(x.ticks(6)).join("line").attr("class", "gridline")
631
- .attr("y1", -6).attr("y2", rows.length * ROW).attr("x1", d => x(d)).attr("x2", d => x(d));
632
- g.selectAll(".tick-label-x").data(x.ticks(6)).join("text").attr("class", "tick-label-x")
633
- .attr("x", d => x(d)).attr("y", rows.length * ROW + 28).attr("text-anchor", "middle").text(fmtVal);
634
- rows.forEach((d, i) => {
635
- const yc = i * ROW + ROW / 2;
636
- const c = d.cs.find(pass) || d.cs[0];
637
- const col = compColor[c] || "#888";
638
- const [auth, name] = d.id.split("/");
639
- const lbl = g.append("text").attr("x", -14).attr("y", yc).attr("text-anchor", "end")
640
- .attr("dominant-baseline", "central").attr("font-size", 13.5).attr("fill", "#222");
641
- lbl.append("tspan").attr("font-weight", 700).text(name.length > 26 ? name.slice(0, 25) + "…" : name);
642
- lbl.append("tspan").attr("x", -14).attr("dy", 14).attr("fill", "#999").attr("font-size", 11.5).text(auth);
643
- g.append("rect").attr("x", 0).attr("y", yc - 13).attr("height", 26)
644
- .attr("width", Math.max(2, x(d.val))).attr("rx", 5).attr("fill", col)
645
- .style("cursor", "pointer")
646
- .on("click", () => window.open("https://huggingface.co/spaces/" + d.id, "_blank"))
647
- .append("title").text(d.id + " — demos " + d.cs.join(", "));
648
- const lg = UI_DATA.companies[c] && UI_DATA.companies[c].logo;
649
- if (lg) g.append("image").attr("href", lg).attr("x", Math.max(2, x(d.val)) + 8)
650
- .attr("y", yc - 11).attr("width", 22).attr("height", 22);
651
- g.append("text").attr("x", Math.max(2, x(d.val)) + 36).attr("y", yc)
652
- .attr("dominant-baseline", "central").attr("font-size", 14.5).attr("font-weight", 700)
653
- .attr("fill", "#444").text(fmtVal(d.val));
654
- });
655
- drawLegend([]);
656
- }
657
-
658
- // ---------- chart image / race video download ----------
659
- const logoDataCache = {};
660
- async function inlineLogos(svgEl) {
661
- const clone = svgEl.cloneNode(true);
662
- for (const img of clone.querySelectorAll("image")) {
663
- const href = img.getAttribute("href");
664
- if (!href || href.startsWith("data:")) continue;
665
- if (!(href in logoDataCache)) {
666
- try {
667
- const blob = await (await fetch(href)).blob();
668
- logoDataCache[href] = await new Promise(res => {
669
- const r = new FileReader(); r.onload = () => res(r.result); r.readAsDataURL(blob);
670
- });
671
- } catch { logoDataCache[href] = null; }
672
- }
673
- if (logoDataCache[href]) img.setAttribute("href", logoDataCache[href]);
674
- else img.remove();
675
- }
676
- return clone;
677
- }
678
- const EXPORT_CSS = `
679
- text { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; }
680
- .tick-label-y { font-size: 15px; fill: #333; }
681
- .tick-label-x { font-size: 16px; fill: #333; }
682
- .axis-title { font-size: 14px; font-weight: 700; fill: #222; }
683
- .gridline { stroke: #ececec; stroke-width: 1; }
684
- .domain-line { stroke: #d9d9d9; stroke-width: 1.5; }
685
- `;
686
- async function svgToImage(svgEl) {
687
- const clone = await inlineLogos(svgEl);
688
- // page CSS doesn't travel with a serialized svg — inline it, and swap the
689
- // webfont (unavailable inside <img>) for a similar heavy system stack
690
- const st = document.createElementNS("http://www.w3.org/2000/svg", "style");
691
- st.textContent = EXPORT_CSS;
692
- clone.insertBefore(st, clone.firstChild);
693
- for (const t of clone.querySelectorAll("text")) {
694
- const ff = t.getAttribute("font-family");
695
- if (ff && ff.includes("Poppins"))
696
- t.setAttribute("font-family", "Futura, 'Avenir Next', 'Arial Black', 'Segoe UI', sans-serif");
697
- }
698
- clone.setAttribute("width", CW); clone.setAttribute("height", clone.viewBox.baseVal.height);
699
- const xml = new XMLSerializer().serializeToString(clone);
700
- const url = URL.createObjectURL(new Blob([xml], { type: "image/svg+xml" }));
701
- const img = new Image();
702
- await new Promise((res, rej) => { img.onload = res; img.onerror = rej; img.src = url; });
703
- URL.revokeObjectURL(url);
704
- return img;
705
- }
706
- function drawFrame(ctx, cw, headH, img) {
707
- ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
708
- ctx.fillStyle = "#111";
709
- ctx.font = "800 44px Poppins, sans-serif";
710
- ctx.fillText(document.getElementById("charttitle").textContent.toUpperCase(), 40, 62);
711
- ctx.fillStyle = "#888"; ctx.font = "22px -apple-system, sans-serif";
712
- ctx.fillText(document.getElementById("chartsub").textContent, 40, 98);
713
- ctx.drawImage(img, 0, headH, cw, img.height * (cw / img.width));
714
- }
715
- async function downloadImage() {
716
- const svgEl = document.querySelector("#chart svg");
717
- if (!svgEl) return;
718
- await document.fonts.ready;
719
- const img = await svgToImage(svgEl);
720
- const CWpx = 2000, headH = 130;
721
- const canvas = document.createElement("canvas");
722
- canvas.width = CWpx; canvas.height = headH + img.height * (CWpx / img.width);
723
- drawFrame(canvas.getContext("2d"), CWpx, headH, img);
724
- const a = document.createElement("a");
725
- a.href = canvas.toDataURL("image/png");
726
- a.download = `hub-oss_${state.view}_${state.metric}_${state.type}.png`;
727
- a.click();
728
- }
729
- async function recordRaceVideo(btn) {
730
- racePause();
731
- const svgEl = document.querySelector("#chart svg");
732
- const probe = await svgToImage(svgEl);
733
- const CWpx = 1600, headH = 104;
734
- const canvas = document.createElement("canvas");
735
- canvas.width = CWpx; canvas.height = Math.round(headH + probe.height * (CWpx / probe.width));
736
- const ctx = canvas.getContext("2d");
737
- const mime = ["video/mp4;codecs=avc1", "video/mp4", "video/webm;codecs=vp9", "video/webm"]
738
- .find(m => MediaRecorder.isTypeSupported(m));
739
- const stream = canvas.captureStream(30);
740
- const rec = new MediaRecorder(stream, { mimeType: mime, videoBitsPerSecond: 8e6 });
741
- const chunks = [];
742
- rec.ondataavailable = e => chunks.push(e.data);
743
- const done = new Promise(res => rec.onstop = res);
744
- rec.start();
745
- const ents = entitySeries();
746
- const valid = w => ents.some(e => e.V[w] != null);
747
- const dur = +document.getElementById("speed").value;
748
- btn.textContent = "⏺ recording…"; btn.disabled = true;
749
- chartDiv.selectAll("svg").remove();
750
- for (let w = state.i0; w <= state.i1; w++) {
751
- if (!valid(w)) continue;
752
- renderRace(w);
753
- await new Promise(r => setTimeout(r, Math.max(dur, 120)));
754
- const img = await svgToImage(document.querySelector("#chart svg"));
755
- drawFrame(ctx, CWpx, headH, img);
756
- }
757
- await new Promise(r => setTimeout(r, 600));
758
- rec.stop();
759
- await done;
760
- const ext = mime.startsWith("video/mp4") ? "mp4" : "webm";
761
- const a = document.createElement("a");
762
- a.href = URL.createObjectURL(new Blob(chunks, { type: mime }));
763
- a.download = `hub-oss_race_${state.metric}_${state.type}.${ext}`;
764
- a.click();
765
- URL.revokeObjectURL(a.href);
766
- btn.textContent = "⬇ MP4"; btn.disabled = false;
767
- }
768
- document.getElementById("dlmp4").addEventListener("click", () =>
769
- recordRaceVideo(document.getElementById("dlmp4")));
770
-
771
  // ---------- shared hover for line ----------
772
  function hoverLayer(svg, g, x, IW, IH, idxs, shown, valAt) {
773
  const cross = g.append("line").attr("stroke", "#bbb").attr("stroke-width", 1)
@@ -860,11 +693,7 @@ function renderTitles() {
860
  deriv_eco: "community derivatives", demo_eco: "community demo Spaces",
861
  everything: "repos + ecosystem" }[state.type];
862
  let head, sub;
863
- if (state.view === "demos") {
864
- const focus = [...state.pins].join(", ");
865
- head = `Top demo Spaces${focus ? " · " + focus : ""} · ${state.allRepos ? "total likes" : "likes gained"}`;
866
- sub = `${d0} – ${d1} · community Spaces running tracked orgs' models · weekly Hub snapshots`;
867
- } else {
868
  const originT = { all: t, noext: "homegrown " + t, orig: "ground-up original " + t,
869
  anyderiv: "fine-tune & quant " + t, ext: t + " built on other orgs' models" };
870
  const tt = (state.type === "models" || state.type === "all") && !document.getElementById("origin").disabled
@@ -917,20 +746,7 @@ function renderFootnote() {
917
  function exportCSV() {
918
  const esc = s => /[",\n]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
919
  let rows;
920
- if (state.view === "demos") {
921
- // re-derive the demo leaderboard
922
- const eligible = new Set(filteredCompanies().filter(c => !state.hidden.has(c)));
923
- const focus = [...state.pins].filter(c => eligible.has(c));
924
- const pass = c => focus.length ? focus.includes(c) : eligible.has(c);
925
- rows = [["space_id","companies","value"]];
926
- UI_DATA.demos.filter(d => d.cs.some(pass)).forEach(d => {
927
- let b = null, v = null;
928
- for (let i = state.i0; i <= state.i1; i++) if (d.V[i] != null) { if (b == null) b = d.V[i]; v = d.V[i]; }
929
- const val = v == null ? null : (state.allRepos ? v : v - b);
930
- if (val != null && val > 0) rows.push([d.id, d.cs.join("|"), val]);
931
- });
932
- rows = [rows[0], ...rows.slice(1).sort((a, b) => b[2] - a[2])];
933
- } else {
934
  const { shown } = visibleEntities();
935
  rows = [["date","entity","value_in_window","weekly_new","raw_total"]];
936
  for (let w = state.i0; w <= state.i1; w++)
@@ -954,7 +770,8 @@ function update() {
954
  if (ECO_TYPES.has(state.type) && state.group === "origin") {
955
  state.group = "company"; document.getElementById("group").value = "company";
956
  }
957
- if (state.view === "race") state.view = "bars"; // legacy hash value
 
958
  document.getElementById("racebar").classList.toggle("open", state.view === "bars");
959
  d3.selectAll("#view-seg button").classed("on", function() { return this.dataset.v === state.view; });
960
  d3.selectAll("#mode-seg button").classed("on", function() {
@@ -966,7 +783,6 @@ function update() {
966
  document.getElementById("plen").style.display = state.view === "periods" ? "" : "none";
967
  if (state.view === "line") renderLine();
968
  else if (state.view === "bars") { chartDiv.selectAll("svg").remove(); renderRace(raceWeek ?? state.i1); }
969
- else if (state.view === "demos") renderDemos();
970
  else if (state.view === "periods") renderPeriods();
971
  else renderWeekly();
972
  saveHash();
 
601
  drawLegend([]);
602
  }
603
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
604
  // ---------- shared hover for line ----------
605
  function hoverLayer(svg, g, x, IW, IH, idxs, shown, valAt) {
606
  const cross = g.append("line").attr("stroke", "#bbb").attr("stroke-width", 1)
 
693
  deriv_eco: "community derivatives", demo_eco: "community demo Spaces",
694
  everything: "repos + ecosystem" }[state.type];
695
  let head, sub;
696
+ {
 
 
 
 
697
  const originT = { all: t, noext: "homegrown " + t, orig: "ground-up original " + t,
698
  anyderiv: "fine-tune & quant " + t, ext: t + " built on other orgs' models" };
699
  const tt = (state.type === "models" || state.type === "all") && !document.getElementById("origin").disabled
 
746
  function exportCSV() {
747
  const esc = s => /[",\n]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
748
  let rows;
749
+ {
 
 
 
 
 
 
 
 
 
 
 
 
 
750
  const { shown } = visibleEntities();
751
  rows = [["date","entity","value_in_window","weekly_new","raw_total"]];
752
  for (let w = state.i0; w <= state.i1; w++)
 
770
  if (ECO_TYPES.has(state.type) && state.group === "origin") {
771
  state.group = "company"; document.getElementById("group").value = "company";
772
  }
773
+ if (state.view === "race") state.view = "bars"; // legacy hash values
774
+ if (state.view === "demos") state.view = "line";
775
  document.getElementById("racebar").classList.toggle("open", state.view === "bars");
776
  d3.selectAll("#view-seg button").classed("on", function() { return this.dataset.v === state.view; });
777
  d3.selectAll("#mode-seg button").classed("on", function() {
 
783
  document.getElementById("plen").style.display = state.view === "periods" ? "" : "none";
784
  if (state.view === "line") renderLine();
785
  else if (state.view === "bars") { chartDiv.selectAll("svg").remove(); renderRace(raceWeek ?? state.i1); }
 
786
  else if (state.view === "periods") renderPeriods();
787
  else renderWeekly();
788
  saveHash();
index.html CHANGED
@@ -101,7 +101,7 @@
101
 
102
  <div class="controls">
103
  <span class="seg" id="view-seg">
104
- <button data-v="line">Line</button><button data-v="bars">Bars</button><button data-v="weekly">Weekly</button><button data-v="periods">Periods</button><button data-v="demos">Demos</button>
105
  </span>
106
  <span class="seg" id="mode-seg" title="New = gained inside the selected window · Accumulated = running total (window still sets what's visible)">
107
  <button data-m="new">New</button><button data-m="total">Accumulated</button>
 
101
 
102
  <div class="controls">
103
  <span class="seg" id="view-seg">
104
+ <button data-v="line">Line</button><button data-v="bars">Bars</button><button data-v="weekly">Weekly</button><button data-v="periods">Periods</button>
105
  </span>
106
  <span class="seg" id="mode-seg" title="New = gained inside the selected window · Accumulated = running total (window still sets what's visible)">
107
  <button data-m="new">New</button><button data-m="total">Accumulated</button>