Перетаскивание узлов в принудительно ориентированный граф с D3 и PIXI - PullRequest
0 голосов
/ 30 мая 2020

В настоящее время я работаю с d3.v5 и PIXI. js из этого примера принудительно направленного графа, и у меня возникли проблемы с его преобразованием для загрузки несчастных json. Взаимодействие отлично работает с масштабированием и панорамированием, но перетаскивание узла - нет. Текущий код здесь

document.documentElement.style.overflow = 'hidden';
let width = window.outerWidth;
let height = window.outerHeight;
let globalDragging = false;

var pixiCanvas = d3.select('#pixiCanvas');

let options = {
    width: width,
    height: height,
    antialias: !0,
    transparent: !0,
    resolution: 1,
    view: pixiCanvas.node()
}
const app = new PIXI.Application(options);
document.body.appendChild(app.view);
const viewport = new Viewport.Viewport({
    screenWidth: width,
    screenHeight: height,
    worldWidth: width,
    worldHeight: height
});

viewport.wheel().drag().decelerate();
app.stage.addChild(viewport);
let colour = (function () {
    let scale = d3.scaleOrdinal(d3.schemeCategory10);
    return (num) => parseInt(scale(num).slice(1), 16);
})();


let radius = 5
let simulation = d3.forceSimulation()
    .force('charge', d3.forceManyBody()
        .strength(-100)
        .distanceMax(250)
        .distanceMin(80)
    )
    .force('center', d3.forceCenter(width / 2, height / 2))
    .force("collision", d3.forceCollide()
        .radius(radius)
    )

d3.json("https://gist.githubusercontent.com/abkunal/98d35b9b235312e90f3e43c9f7b6932b/raw/d5589ddd53731ae8eec7abd091320df91cdcf5cd/miserables.json")
    .then(function (graph) {
        let links = new PIXI.Graphics();
        viewport.addChild(links);

        graph.nodes.forEach((node) => {
            node.gfx = new PIXI.Graphics();
            node.gfx.lineStyle(1.5, 0xFFFFFF);
            node.gfx.interactive = true;
            node.gfx.beginFill(colour(node.group));
            node.gfx.drawCircle(1, 1, radius);
            node.gfx.on("pointerdown", onDragStart)
            node.gfx.on("pointerup", onDragEnd)
            node.gfx.on("pointerupoutside", onDragEnd)
            node.gfx.on("pointermove", onDragMove);
            viewport.addChild(node.gfx);
        });

        simulation
            .nodes(graph.nodes)
            .on("tick", function () {
            });
        simulation.force('link', d3.forceLink(graph.links)
            .id((d) => d.id)
        )
        simulation.stop()

        app.ticker.add(function ticked() {
            simulation.tick();
            graph.nodes.forEach((node) => {
                let {x, y, gfx} = node;
                gfx.position = new PIXI.Point(x, y);
            });

            links.clear();
            links.alpha = 0.6;

            graph.links.forEach((link) => {
                let {source, target} = link;
                links.lineStyle(Math.sqrt(link.value), 0x999999);
                links.moveTo(source.x, source.y);
                links.lineTo(target.x, target.y);
            });
            links.endFill();
        });
    });


function onDragStart(event) {
    viewport.plugins.pause('drag')
    simulation.alphaTarget(0.3).restart();
    this.isDown = true;
    this.event = event.data;
    this.alpha = 0.5;
    this.dragging = true;
    globalDragging = true;

}

function onDragEnd(event) {
    if (!event.active) simulation.alphaTarget(0);
    this.alpha = 1;
    this.dragging = false;
    this.isOver = false;
    this.event = null;
    globalDragging = false;
    viewport.plugins.resume('drag')
}

function onDragMove(event) {
    if (this.dragging) {
        const newPosition = this.event.getLocalPosition(this.parent);
        this.x = newPosition.x;
        this.y = newPosition.y;
    }
}

Если я удалю ссылки в графе, я смогу перетащить узлы, поэтому я думаю, что проблема может заключаться в том, как я обновляю ссылки в тик, но в настоящее время неясно, как мне это изменить.

...