| export default class FaceDebugGraph {
    constructor(backendDescriptors = [], capturedColor = "blue", backendColor = "red", lineColor = "black") {
        this.backendDescriptors = backendDescriptors;
        this.capturedColor = capturedColor;
        this.backendColor = backendColor;
        this.lineColor = lineColor;
        this.lines = [];
        this.capturedPoints = [];
        this.backendPoints = [];
        this.isRendered = false;
    }
    processBackendDescriptors() {
        if (!Array.isArray(this.backendDescriptors) || this.backendDescriptors.length === 0) {
            return { capturedPoints: [], backendPoints: [] };
        }
        const capturedPoints = [];
        const backendPoints = [];
        this.backendDescriptors.forEach(({ vec1, vec2, diff }, index) => {
            capturedPoints.push({ x: vec1, y: diff, z: vec1, id: `V1 #${index}` });
            backendPoints.push({ x: vec2, y: diff, z: vec2+0.1, id: `V2 #${index}` });
        });
        this.capturedPoints = capturedPoints;
        this.backendPoints = backendPoints;
    }
    render(containerId = "faceDebugGraphContainer") {
        if (this.isRendered) return;
        let container = document.getElementById(containerId);
        if (!container) {
            container = document.createElement("div");
            container.id = containerId;
            container.style.width = "80%";
            container.style.height = "600px";
            container.style.margin = "auto";
            container.style.border = "1px solid #ccc";
            container.style.padding = "10px";
            container.style.top= "90px";
            document.body.appendChild(container);
        }
        this.processBackendDescriptors();
        const traceCaptured = {
            x: this.capturedPoints.map(p => p.x),
            y: this.capturedPoints.map(p => p.y),
            z: this.capturedPoints.map(p => p.z),
            text: this.capturedPoints.map(p => p.id),
            mode: "markers",
            type: "scatter3d",
            marker: { size: 6, color: this.capturedColor, opacity: 0.8 },
            name: "Vetor Capturado",
        };
        const traceBackend = {
            x: this.backendPoints.map(p => p.x),
            y: this.backendPoints.map(p => p.y),
            z: this.backendPoints.map(p => p.z),
            text: this.backendPoints.map(p => p.id),
            mode: "markers",
            type: "scatter3d",
            marker: { size: 6, color: this.backendColor, opacity: 0.8 },
            name: "Vetor Banco",
        };
        this.data = [traceCaptured, traceBackend];
        this.layout = {
            title: "Distância euclidiana",
            scene: {
                xaxis: { title: "Vec1 (Capturado)" },
                yaxis: { title: "Vec2 (Banco)" },
                zaxis: { title: "Diferença (Diff)" },
            },
            margin: { l: 0, r: 0, b: 0, t: 30 },
        };
        Plotly.newPlot(containerId, this.data, this.layout).then(() => {
            this.isRendered = true;
            this.fixPassiveEvent(containerId);
            container.on("plotly_click", (data) => this.onPointClick(data, containerId));
        });
    }
    onPointClick(data, containerId) {
        if (!data || !data.points || !data.points[0]) {
            console.warn("? Nenhum ponto válido foi clicado.");
            return;
        }
        const clickedIndex = data.points[0].pointNumber;
        if (!Number.isInteger(clickedIndex)) {
            console.error("? Índice de ponto inválido:", clickedIndex);
            return;
        }
        if (!this.capturedPoints[clickedIndex] || !this.backendPoints[clickedIndex]) {
            console.warn(`? Ponto não encontrado para index ${clickedIndex}`);
            return;
        }
        const capturedPoint = this.capturedPoints[clickedIndex];
        const backendPoint = this.backendPoints[clickedIndex];
        console.log(`? Conectando ${capturedPoint.id} ? ${backendPoint.id}`);
        const lineTrace = {
            x: [capturedPoint.x, backendPoint.x],
            y: [capturedPoint.y, backendPoint.y],
            z: [capturedPoint.z, backendPoint.z],
            mode: "lines",
            type: "scatter3d",
            line: { width: 3, color: this.lineColor },
            name: `Conexão ${capturedPoint.id} ? ${backendPoint.id}`,
        };
        const existingLine = this.lines.find(line => line.name === lineTrace.name);
        if (!existingLine) {
            this.lines.push(lineTrace);
            Plotly.addTraces(containerId, [lineTrace]);
        }
    }
    fixPassiveEvent(containerId) {
        setTimeout(() => {
            document.querySelectorAll(`#${containerId} canvas`).forEach(canvas => {
                canvas.addEventListener("wheel", (event) => {
                }, { passive: true });
            });
        }, 1000);
    }
}
 |