import {
  getDefaultProfilePlotSettings,
  getProfilePlotConfig,
  profilePlot
} from "./chunk-P3IENRWJ.js";
import {
  fillTwLst,
  renderTable
} from "./chunk-SA7APTJR.js";
import "./chunk-HJ6L54YS.js";
import "./chunk-LSEFWW72.js";
import "./chunk-SKREEF3H.js";
import "./chunk-HYOEWQ5P.js";
import "./chunk-HBW42TDT.js";
import "./chunk-G6O3URDN.js";
import "./chunk-FN5XPUPH.js";
import "./chunk-IIT367QZ.js";
import "./chunk-RZGEKL77.js";
import "./chunk-UI7OCM2A.js";
import "./chunk-YZK37YCC.js";
import {
  dofetch3
} from "./chunk-7EMWHCVW.js";
import "./chunk-7IYJZZQI.js";
import {
  copyMerge,
  getCompInit
} from "./chunk-M3J4MINX.js";
import "./chunk-PF4DSFDR.js";
import "./chunk-QH6W3NVF.js";
import "./chunk-NOEAT6CX.js";
import "./chunk-4UWS5Y3N.js";
import "./chunk-DD4R5P6W.js";
import "./chunk-JNITUVXP.js";
import {
  arc_default
} from "./chunk-KSGA62R2.js";
import "./chunk-LOZEKOES.js";
import "./chunk-TOU7EVFQ.js";
import "./chunk-OAWQ6LOO.js";
import "./chunk-TLT4YIG3.js";
import "./chunk-KYBIQBXE.js";
import "./chunk-I6Y4O3RR.js";
import "./chunk-OMR2DT66.js";
import "./chunk-DQC5FFGV.js";
import "./chunk-HFNDKYVF.js";

// plots/profile/polar2.ts
var ProfilePolar2 = class extends profilePlot {
  constructor(opts) {
    super(opts, "profilePolar2");
    this.radius = 250;
    this.arcGenerator = arc_default().innerRadius(0);
  }
  static {
    this.type = "profilePolar2";
  }
  async init(appState) {
    await super.init(appState);
    const config = appState.plots.find((p) => p.id === this.id);
    this.scoreTerms = config.terms;
    this.angle = Math.PI * 2 / config.terms.length;
  }
  async main() {
    await super.main();
    await this.setControls();
    this.plot();
  }
  /**
   * Fetches aggregated module scores from termdb/profilePolar2Scores after
   * super.setControls() builds the filter UI and sets this.filter. The server
   * derives the facility term from the request term IDs and returns the median
   * percentage across all eligible sites.
   */
  async setControls(additionalInputs = []) {
    await super.setControls(additionalInputs);
    this.data = await this.fetchAggregatedScores();
    if (this.data && "error" in this.data) throw this.data.error;
  }
  async fetchAggregatedScores() {
    return dofetch3("termdb/profilePolar2Scores", {
      body: {
        genome: this.state.vocab.genome,
        dslabel: this.state.vocab.dslabel,
        scoreTerms: this.scoreTerms.map((t) => ({
          score: { term: { id: t.score.term.id }, q: t.score.q },
          maxScore: typeof t.maxScore === "number" ? t.maxScore : { term: { id: t.maxScore.term.id }, q: t.maxScore.q }
        })),
        filterByUserSites: this.settings?.filterByUserSites,
        filter: this.filter
      }
    });
  }
  onMouseOut(event) {
    const target = event.target;
    if (target.tagName === "path") {
      target.setAttribute("stroke", "white");
      if (target.getAttribute("stroke-opacity") === "0") {
        target.setAttribute("stroke-opacity", "1");
      }
    }
    this.tip.hide();
  }
  onMouseOver(event) {
    const target = event.target;
    if (target.tagName === "path") {
      target.setAttribute("stroke-opacity", "0");
      const d = target.__data__;
      const menu = this.tip.clear();
      const percentage = this.getPercentage(d);
      const label = percentage == null ? "N/A" : `${percentage}%`;
      menu.d.text(`${d.module} ${label}`);
      menu.show(event.clientX, event.clientY, true, true);
    } else {
      this.onMouseOut(event);
    }
  }
  plot() {
    this.createSvg();
    const rows = this.drawArcs();
    this.drawGrid();
    this.drawTable(rows);
    this.drawLegend();
  }
  createSvg() {
    const width = this.isComparison ? 800 : 1e3, height = 600;
    this.dom.svg = this.dom.plotDiv.append("div").style("display", "inline-block").append("svg").attr("width", width).attr("height", height);
    this.dom.tableDiv = this.dom.plotDiv.append("div").attr("data-testid", "sjpp-profilePolar2-data-table").style("display", "inline-block").style("vertical-align", "top").style("margin", "45px 20px");
    this.dom.svg.append("text").attr("transform", `translate(130, 40)`).attr("font-weight", "bold").text(this.config.title);
    const x = 280, y = 330;
    this.polarG = this.dom.svg.append("g").attr("transform", `translate(${x},${y})`);
    this.legendG = this.dom.svg.append("g").attr("data-testid", "sjpp-profilePolar2-legend").attr("transform", `translate(${x + 280}, ${y - 200})`);
    this.filterG = this.dom.svg.append("g").attr("transform", `translate(${x + 280},${y})`);
  }
  drawGrid() {
    for (let i = 0; i <= 10; i++) this.drawGridCircle(i * 10);
    this.drawGradeCircle(50, "C");
    this.drawGradeCircle(75, "B");
    this.drawGradeCircle(100, "A");
    for (let i = 0; i <= 10; i++) {
      const percent = i * 10;
      this.polarG.append("text").attr("transform", `translate(-10, ${-percent / 100 * this.radius + 5})`).attr("text-anchor", "end").style("font-size", "0.8rem").text(`${percent}%`).attr("pointer-events", "none");
    }
  }
  drawGridCircle(percent) {
    const circle = this.polarG.append("circle").attr("r", percent / 100 * this.radius).style("fill", "none").style("opacity", "0.5");
    if (percent != 50) circle.style("stroke", "#aaa");
  }
  drawGradeCircle(percent, label) {
    const circle = this.polarG.append("circle").attr("r", percent / 100 * this.radius).style("fill", "none").style("opacity", "0.5");
    if (percent != 100) circle.style("stroke-dasharray", "5, 5").style("stroke-width", "2").style("stroke", "black");
    this.polarG.append("text").attr("transform", `translate(15, ${-(percent / 100 - 0.125) * this.radius + 10})`).attr("text-anchor", "middle").text(label).style("font-weight", "bold").style("font-size", "24px").attr("pointer-events", "none");
  }
  /** Draws the arc slices and returns table rows for drawTable(). */
  drawArcs() {
    const rows = [];
    let i = 0;
    for (const d of this.config.terms) {
      d.i = i;
      const color = d.score.term.color;
      const percentage = this.getPercentage(d);
      rows.push([{ color, disabled: true }, { value: d.module }, { value: percentage ?? "N/A" }]);
      this.polarG.append("g").append("path").datum(d).attr("fill", color).attr("stroke", "white").attr(
        "d",
        this.arcGenerator({
          outerRadius: percentage / 100 * this.radius,
          startAngle: i * this.angle,
          endAngle: (i + 1) * this.angle
        })
      ).on("click", (event) => this.onMouseOver(event));
      i++;
    }
    return rows;
  }
  drawTable(rows) {
    const columns = [{ label: "Color" }, { label: "Module" }, { label: "Score", align: "center" }];
    this.dom.tableDiv.selectAll("*").remove();
    if (!this.isComparison)
      renderTable({
        rows,
        columns,
        div: this.dom.tableDiv,
        showLines: true,
        resize: true,
        maxHeight: "50vh"
      });
  }
  drawLegend() {
    if (!this.isComparison) {
      this.legendG.append("text").attr("text-anchor", "left").style("font-weight", "bold").text("Overall Score").attr("transform", `translate(0, -5)`);
      this.addLegendItem("A", "More than 75% of possible scorable items", 1);
      this.addLegendItem("B", "50-75% of possible scorable items", 2);
      this.addLegendItem("C", "Less than 50% of possible scorable items", 3);
    }
    this.addFilterLegend();
  }
};
async function getPlotConfig(opts, app, _activeCohort) {
  try {
    const activeCohort = _activeCohort === void 0 ? app.getState().activeCohort : _activeCohort;
    const defaults = await getProfilePlotConfig(activeCohort, app, opts);
    if (!defaults) throw "default config not found in termdbConfig.plotConfigByCohort.profilePolar2";
    const settings = getDefaultProfilePlotSettings();
    defaults.settings = { profilePolar2: settings };
    const config = copyMerge(structuredClone(defaults), opts);
    config.settings.controls = { isOpen: false };
    const twlst = [];
    for (const data of config.terms) {
      data.score.q = { mode: "continuous" };
      data.maxScore.q = { mode: "continuous" };
      twlst.push(data.score, data.maxScore);
    }
    await fillTwLst(twlst, app.vocabApi);
    return config;
  } catch (e) {
    throw `${e} [profilePolar2 getPlotConfig()]`;
  }
}
var profilePolar2Init = getCompInit(ProfilePolar2);
var componentInit = profilePolar2Init;
export {
  componentInit,
  getPlotConfig,
  profilePolar2Init
};
//# sourceMappingURL=polar2-YCWPBPFU.js.map
