import * as d3 from "d3";
import GraphOptions from './GraphOptions';
/**
 * Implementation of the 'graph' markup element.
 */
var Graph = /** @class */ (function () {
    function Graph(options) {
        if (options === void 0) { options = new GraphOptions(); }
        this.options = options;
    }
    /**
     * @inheritDoc
     */
    Graph.prototype.render = function () {
        var div = document.createElement("div");
        div.classList.add("lto-vis-graph");
        div.innerHTML = "<svg width=\"" + this.options.width + "\" height=\"" + this.options.height + "\" />";
        return div;
    };
    Graph.prototype.init = function (element) {
        var _this = this;
        this.options.data.then(function (data) {
            var links = data.links.map(function (d) { return Object.create(d); });
            var nodes = data.nodes.map(function (d) { return Object.create(d); });
            var svg = d3.select(element.querySelector("svg"));
            _this.generateArrow(svg);
            var simulation = d3.forceSimulation(nodes)
                .force("link", d3.forceLink(links).id(function (d) { return d.id; }).distance(_this.options.distance))
                .force("name", d3.forceCollide(_this.options.collision))
                .force("charge", d3.forceManyBody().strength(_this.options.charge))
                .force("center", d3.forceCenter(_this.options.width / 2, _this.options.height / 2));
            var link = svg.append("g")
                .selectAll("line")
                .data(links)
                // @ts-ignore
                .join("line")
                .attr("marker-end", "url(#arrow)");
            var node = svg.append("g")
                .selectAll("circle")
                .data(nodes)
                // @ts-ignore
                .join("circle")
                .attr("r", _this.options.radius)
                .attr("class", function (d) { return "lto-node lto-node-" + d.group; })
                //@ts-ignore
                .call(_this.drag(simulation));
            node.append("title").text(function (d) { return d.group; });
            var text = svg.append("g")
                .attr("text-anchor", "middle")
                .selectAll("text")
                .data(nodes)
                // @ts-ignore
                .join("text")
                .attr("x", function (d) { return d.cx; })
                .attr("y", function (d) { return d.cy + (_this.options.radius + (_this.options.fontSize * 0.7)); })
                .text(function (d) { return d.id; })
                .attr("class", function (d) { return "lto-node-text lto-node-test-" + d.group; })
                //@ts-ignore
                .call(_this.drag(simulation));
            simulation.on("tick", function () {
                link.attr("x1", function (d) { return d.source.x; })
                    .attr("y1", function (d) { return d.source.y; })
                    .attr("x2", function (d) { return d.target.x; })
                    .attr("y2", function (d) { return d.target.y; });
                node.attr("cx", function (d) { return d.x; })
                    .attr("cy", function (d) { return d.y; });
                text.attr("x", function (d) { return d.x; })
                    .attr("y", function (d) { return d.y + (_this.options.radius + (_this.options.fontSize * 0.7)); });
            });
        });
    };
    Graph.prototype.drag = function (simulation) {
        function dragstarted(d) {
            if (!d3.event.active)
                simulation.alphaTarget(0.3).restart();
            d.fx = d.x;
            d.fy = d.y;
        }
        function dragged(d) {
            d.fx = d3.event.x;
            d.fy = d3.event.y;
        }
        function dragended(d) {
            if (!d3.event.active)
                simulation.alphaTarget(0);
            d.fx = null;
            d.fy = null;
        }
        return d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended);
    };
    Graph.prototype.generateArrow = function (svg) {
        svg.append("svg:defs").selectAll("marker")
            .data(["arrow"])
            .enter().append("svg:marker")
            .attr("id", String)
            .attr("viewBox", "0 -5 10 10")
            .attr("refX", this.options.radius + 10)
            .attr("refY", -1.5)
            .attr("markerWidth", 10)
            .attr("markerHeight", 10)
            .attr("orient", "auto")
            .append("svg:path")
            .attr("d", "M0,-5L10,0L0,5");
    };
    return Graph;
}());
export { Graph };
//# sourceMappingURL=Graph.js.map