// noinspection TsLint
import LineOptions from './LineOptions';
import * as d3 from "d3";
/**
 * Implementation of the 'line' markup element.
 */
var Line = /** @class */ (function () {
    function Line(options) {
        if (options === void 0) { options = new LineOptions(); }
        this.options = options;
    }
    /**
     * @inheritDoc
     */
    Line.prototype.render = function () {
        var div = document.createElement("div");
        div.classList.add("lto-vis-line");
        div.innerHTML = "<svg width=\"" + this.options.width + "\" height=\"" + this.options.height + "\" />";
        return div;
    };
    Line.prototype.init = function (element) {
        var _this = this;
        this.options.data.then(function (data) {
            var svg = d3.select(element.querySelector("svg"));
            var dates = data.dates.map(function (e) { return new Date(e); });
            var line = d3.line().defined(_this.options.isDefined).x(function (d, i) { return x(data.dates[i]); }).y(function (d) { return y(d); });
            var x = d3.scaleTime()
                // @ts-ignore
                .domain(d3.extent(dates))
                .range([_this.options.margin.left, _this.options.width - _this.options.margin.right]);
            var y = d3.scaleLinear()
                // @ts-ignore
                .domain([0, d3.max(data.series, function (d) { return d3.max(d.values); })]).nice()
                .range([_this.options.height - _this.options.margin.bottom, _this.options.margin.top]);
            svg.append("g").call(_this.xAxis(x));
            svg.append("g").call(_this.yAxis(y, data));
            svg.append("g").call(_this.grid(x));
            var counter = 0;
            var path = svg.append("g")
                .attr("class", function () { return "lto-vis-lines"; })
                .selectAll("path")
                .data(data.series)
                // @ts-ignore
                .join("path")
                .style("mix-blend-mode", "color-dodge")
                .attr("class", function () { return "lto-vis-line-" + counter++; })
                .attr("d", function (d) {
                var _line = line(d.values);
                // console.debug("LINE");
                // console.debug(_line);
                return _line;
            })
                .style("stroke-dasharray", function (d, e, f) { return Math.max.apply(null, f.map(function (e) { return e.getTotalLength(); })); })
                .style("stroke-dashoffset", function (d, e, f) { return Math.max.apply(null, f.map(function (e) { return e.getTotalLength(); })); });
            svg.call(_this.hover(x, y, data), path);
        });
    };
    Line.prototype.xAxis = function (x) {
        var _this = this;
        return function (g) { return g
            .attr("transform", "translate(0," + (_this.options.height - _this.options.margin.bottom) + ")")
            .call(d3.axisBottom(x).ticks(_this.options.width / 80).tickSizeOuter(0)); };
    };
    Line.prototype.yAxis = function (y, data) {
        var _this = this;
        return function (g) {
            g
                .attr("transform", "translate(" + _this.options.margin.left + ",0)")
                .call(d3.axisLeft(y))
                .call(function (g) { return g.select(".domain").remove(); })
                .call(function (g) { return g.select(".tick:last-of-type text").clone()
                .attr("x", 3)
                .attr("class", "lto-vis-text-0")
                .attr("text-anchor", "start")
                .attr("font-weight", "bold")
                .text(data.y); });
            if (data.y2) {
                g.call(function (g) { return g.select(".tick:last-of-type text").clone()
                    .attr("x", 3)
                    .attr("y", 15)
                    .attr("class", "lto-vis-text-1")
                    .attr("text-anchor", "start")
                    .attr("font-weight", "bold")
                    .text(data.y2); });
            }
            return g;
        };
    };
    Line.prototype.hover = function (x, y, data) {
        return function (svg, path) {
            svg.style("position", "relative");
            if ("ontouchstart" in document) {
                svg
                    .style("-webkit-tap-highlight-color", "transparent")
                    .on("touchmove", moved)
                    .on("touchstart", entered)
                    .on("touchend", left);
            }
            else {
                svg
                    .on("mousemove", moved)
                    .on("mouseenter", entered)
                    .on("mouseleave", left);
            }
            var dot = svg.append("g").attr("display", "none");
            dot.append("circle").attr("r", 2.5);
            dot.append("text")
                .style("font", "10px sans-serif")
                .attr("text-anchor", "middle")
                .attr("y", -8);
            function moved() {
                d3.event.preventDefault();
                var ym = y.invert(d3.event.layerY);
                var xm = x.invert(d3.event.layerX);
                var i1 = d3.bisectLeft(data.dates, xm, 1);
                var i0 = i1 - 1;
                var i = xm - data.dates[i0] > data.dates[i1] - xm ? i1 : i0;
                var s = data.series.reduce(function (a, b) { return Math.abs(a.values[i] - ym) < Math.abs(b.values[i] - ym) ? a : b; });
                path.attr("stroke", function (d) { return d === s ? null : "#ddd"; }).filter(function (d) { return d === s; }).raise();
                dot.attr("transform", "translate(" + x(data.dates[i]) + "," + y(s.values[i]) + ")");
                dot.select("text").text(s.name);
            }
            function entered() {
                path.style("stroke-dasharray", null);
                path.style("stroke-dashoffset", null);
                path.style("mix-blend-mode", null).attr("stroke", "#ddd");
                dot.attr("display", null);
            }
            function left() {
                path.style("mix-blend-mode", "color-dodge").attr("stroke", null);
                dot.attr("display", "none");
            }
        };
    };
    Line.prototype.grid = function (x) {
        var _this = this;
        return function (g) {
            g.append("path")
                .attr("class", "lto-grid")
                .attr("stroke", "gray")
                .attr("d", "M " + _this.options.margin.left + " " + _this.options.height / 3 + " L " + (_this.options.width - _this.options.margin.right) + " " + _this.options.height / 3 + " Z");
            g.append("path")
                .attr("class", "lto-grid")
                .attr("stroke", "gray")
                .attr("d", "M " + _this.options.margin.left + " " + _this.options.height / 3 * 2 + " L " + (_this.options.width - _this.options.margin.right) + " " + _this.options.height / 3 * 2 + " Z");
        };
    };
    return Line;
}());
export { Line };
//# sourceMappingURL=Line.js.map