// noinspection TsLint
import * as d3 from "d3";
import DoughnutOptions from './DoughnutOptions';
/**
 * Implementation of the 'doughnut' markup element.
 */
var Doughnut = /** @class */ (function () {
    function Doughnut(options) {
        if (options === void 0) { options = new DoughnutOptions(); }
        this.options = options;
        this.radius = Math.min(options.width, options.height) / 2;
    }
    /**
     * @inheritDoc
     */
    Doughnut.prototype.render = function () {
        var div = document.createElement("div");
        div.classList.add("lto-vis-doughnut");
        var width = this.options.width + 200;
        div.innerHTML = "<svg viewBox=\"-" + width / 2 + " -" + this.options.height / 2 + " " + width + " " + this.options.height + "\"/>";
        return div;
    };
    Doughnut.prototype.init = function (element) {
        var _this = this;
        var svg = d3.select(element.querySelector("svg")).append("g");
        svg.append("g").attr("class", "lto-vis-slices");
        svg.append("g").attr("class", "lto-vis-labels");
        svg.append("g").attr("class", "lto-vis-lines");
        this.options.data.then(function (e) { return _this.change(e, svg, element); });
    };
    Doughnut.prototype.getLetter = function (index) {
        return String.fromCharCode('A'.charCodeAt(0) + (index % 5));
    };
    Doughnut.prototype.change = function (data, svg, element) {
        var _this = this;
        var arc = d3.arc().outerRadius(this.radius * 0.8).innerRadius(this.radius * this.options.doughnutRatio);
        var outerArc = d3.arc().innerRadius(this.radius * 0.9).outerRadius(this.radius * 0.9);
        var pie = d3.pie().sort(null).value(function (d) { return d.value; });
        var key = function (d) { return d.data.label; };
        var slice = svg.select(".lto-vis-slices").selectAll("path.lto-vis-slice").data(pie(data), key);
        if (this.options.iconUrl) {
            var width = this.radius * (this.options.doughnutRatio) * Math.sqrt(2);
            svg.select("g")
                .append("image")
                .attr("xlink:href", this.options.iconUrl)
                .attr("width", width)
                .attr("height", width)
                .attr("x", -width / 2)
                .attr("y", -width / 2);
        }
        var _current;
        slice.enter()
            .insert("path")
            .attr("class", function (d, index) { return "lto-vis-" + index + " lto-vis-" + _this.getLetter(index); })
            .merge(slice)
            .transition().duration(1000)
            .attrTween("d", function (d) {
            _current = _current || d;
            var interpolate = d3.interpolate(_current, d);
            _current = interpolate(0);
            return function (t) { return arc(interpolate(t)); };
        });
        slice.exit().remove();
        var $this = this;
        var text = svg.select(".lto-vis-labels").selectAll("text").data(pie(data), key);
        var midAngle = function (d) { return d.startAngle + (d.endAngle - d.startAngle) / 2; };
        text.enter()
            .append("text")
            .attr("dy", ".35em")
            .text(function (d) { return d.data.label; })
            .merge(text)
            .transition().duration(1000)
            .attrTween("transform", function (d) {
            _current = _current || d;
            var interpolate = d3.interpolate(_current, d);
            _current = interpolate(0);
            return function (t) {
                var d2 = interpolate(t);
                var pos = outerArc.centroid(d2);
                pos[0] = $this.radius * (midAngle(d2) < Math.PI ? 1 : -1);
                return "translate(" + pos + ")";
            };
        })
            .styleTween("text-anchor", function (d) {
            _current = _current || d;
            var interpolate = d3.interpolate(_current, d);
            _current = interpolate(0);
            return function (t) {
                var d2 = interpolate(t);
                return midAngle(d2) < Math.PI ? "start" : "end";
            };
        });
        text.exit().remove();
        var polyline = svg.select(".lto-vis-lines").selectAll("polyline").data(pie(data), key);
        polyline.enter()
            .append("polyline")
            .attr("class", function (d, index) { return "lto-vis-" + index + " lto-vis-" + _this.getLetter(index); })
            .merge(polyline)
            .transition().duration(1000)
            .attrTween("points", function (d) {
            _current = _current || d;
            var interpolate = d3.interpolate(_current, d);
            _current = interpolate(0);
            return function (t) {
                var d2 = interpolate(t);
                var pos = outerArc.centroid(d2);
                pos[0] = $this.radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
                return [arc.centroid(d2), outerArc.centroid(d2), pos];
            };
        });
        polyline.exit().remove();
        setTimeout(function () {
            var registry = {};
            element.querySelectorAll(".lto-vis-labels text").forEach(function (text) {
                var x = Math.floor(text.transform.animVal.getItem(0).matrix.e);
                var y = Math.floor(text.transform.animVal.getItem(0).matrix.f);
                if (registry[x + ":" + y] === undefined) {
                    registry[x + ":" + y] = 1;
                }
                else {
                    var amount = registry[x + ":" + y];
                    text.setAttribute("dy", (amount * 20) + "px");
                    registry[x + ":" + y] = registry[x + ":" + y] + 1;
                }
            });
        }, 1200);
    };
    return Doughnut;
}());
export { Doughnut };
//# sourceMappingURL=Doughnut.js.map