function _array_like_to_array(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
    return arr2;
}
function _array_with_holes(arr) {
    if (Array.isArray(arr)) return arr;
}
function _assert_this_initialized(self) {
    if (self === void 0) {
        throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
    }
    return self;
}
function _call_super(_this, derived, args) {
    derived = _get_prototype_of(derived);
    return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
}
function _class_call_check(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}
function _defineProperties(target, props) {
    for(var i = 0; i < props.length; i++){
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}
function _create_class(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    return Constructor;
}
function _get(target, property, receiver) {
    if (typeof Reflect !== "undefined" && Reflect.get) {
        _get = Reflect.get;
    } else {
        _get = function get(target, property, receiver) {
            var base = _super_prop_base(target, property);
            if (!base) return;
            var desc = Object.getOwnPropertyDescriptor(base, property);
            if (desc.get) {
                return desc.get.call(receiver || target);
            }
            return desc.value;
        };
    }
    return _get(target, property, receiver || target);
}
function _get_prototype_of(o) {
    _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
        return o.__proto__ || Object.getPrototypeOf(o);
    };
    return _get_prototype_of(o);
}
function _inherits(subClass, superClass) {
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function");
    }
    subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
            value: subClass,
            writable: true,
            configurable: true
        }
    });
    if (superClass) _set_prototype_of(subClass, superClass);
}
function _iterable_to_array_limit(arr, i) {
    var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
    if (_i == null) return;
    var _arr = [];
    var _n = true;
    var _d = false;
    var _s, _e;
    try {
        for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
            _arr.push(_s.value);
            if (i && _arr.length === i) break;
        }
    } catch (err) {
        _d = true;
        _e = err;
    } finally{
        try {
            if (!_n && _i["return"] != null) _i["return"]();
        } finally{
            if (_d) throw _e;
        }
    }
    return _arr;
}
function _non_iterable_rest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _possible_constructor_return(self, call) {
    if (call && (_type_of(call) === "object" || typeof call === "function")) {
        return call;
    }
    return _assert_this_initialized(self);
}
function _set_prototype_of(o, p) {
    _set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
        o.__proto__ = p;
        return o;
    };
    return _set_prototype_of(o, p);
}
function _sliced_to_array(arr, i) {
    return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
}
function _super_prop_base(object, property) {
    while(!Object.prototype.hasOwnProperty.call(object, property)){
        object = _get_prototype_of(object);
        if (object === null) break;
    }
    return object;
}
function _type_of(obj) {
    "@swc/helpers - typeof";
    return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
}
function _unsupported_iterable_to_array(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _array_like_to_array(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(n);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
function _is_native_reflect_construct() {
    try {
        var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
    } catch (_) {}
    return (_is_native_reflect_construct = function() {
        return !!result;
    })();
}
import { groups } from "d3-array";
import { sankey, sankeyCenter, sankeyJustify, sankeyLeft, sankeyLinkHorizontal, sankeyRight } from "d3-sankey";
var sankeyAligns = {
    center: sankeyCenter,
    justify: sankeyJustify,
    left: sankeyLeft,
    right: sankeyRight
};
import { addToQueue } from "@d3plus/data";
import { assign, elem } from "@d3plus/dom";
import { accessor, configPrep, constant } from "../utils/index.js";
import { Path } from "../shapes/index.js";
import * as shapes from "../shapes/index.js";
import Viz from "./Viz.js";
var Sankey = /*#__PURE__*/ function(Viz) {
    "use strict";
    _inherits(Sankey, Viz);
    function Sankey() {
        _class_call_check(this, Sankey);
        var _this;
        _this = _call_super(this, Sankey);
        _this._iterations = 6;
        _this._nodeId = accessor("id");
        _this._nodeSort = undefined;
        _this._links = accessor("links");
        _this._linkSort = undefined;
        _this._linksSource = "source";
        _this._linksTarget = "target";
        _this._noDataMessage = false;
        _this._nodes = accessor("nodes");
        _this._nodeAlign = sankeyAligns.justify;
        _this._nodePadding = 8;
        _this._nodeWidth = 30;
        _this._on.mouseenter = function() {};
        _this._on["mouseleave.shape"] = function() {
            _this.hover(false);
        };
        var defaultMouseMove = _this._on["mousemove.shape"];
        _this._on["mousemove.shape"] = function(d, i, x, event) {
            defaultMouseMove(d, i, x, event);
            if (_this._focus && _this._focus === d.id) {
                _this.hover(false);
                _this._on.mouseenter.bind(_this)(d, i, x, event);
                _this._focus = undefined;
            } else {
                var id = _this._nodeId(d, i), node = _this._nodeLookup[id], nodeLookup = Object.keys(_this._nodeLookup).reduce(function(all, item) {
                    all[_this._nodeLookup[item]] = !isNaN(item) ? parseInt(item, 10) : item;
                    return all;
                }, {});
                var links = _this._linkLookup[node];
                var filterIds = [
                    id
                ];
                links.forEach(function(l) {
                    filterIds.push(nodeLookup[l]);
                });
                _this.hover(function(h, x) {
                    if (h.source && h.target) {
                        return h.source.id === id || h.target.id === id;
                    } else {
                        return filterIds.includes(_this._nodeId(h, x));
                    }
                });
            }
        };
        _this._path = sankeyLinkHorizontal();
        _this._sankey = sankey();
        _this._shape = constant("Rect");
        _this._shapeConfig = assign(_this._shapeConfig, {
            Path: {
                fill: "none",
                hoverStyle: {
                    "stroke-width": function(d) {
                        return Math.max(1, Math.abs(d.source.y1 - d.source.y0) * (d.value / d.source.value) - 2);
                    }
                },
                label: false,
                stroke: "#DBDBDB",
                strokeOpacity: 0.5,
                strokeWidth: function strokeWidth(d) {
                    return Math.max(1, Math.abs(d.source.y1 - d.source.y0) * (d.value / d.source.value) - 2);
                }
            },
            Rect: {}
        });
        _this._value = constant(1);
        return _this;
    }
    _create_class(Sankey, [
        {
            /**
      Extends the draw behavior of the abstract Viz class.
      @private
*/ key: "_draw",
            value: function _draw(callback) {
                var _this = this;
                _get(_get_prototype_of(Sankey.prototype), "_draw", this).call(this, callback);
                var height = this._height - this._margin.top - this._margin.bottom, width = this._width - this._margin.left - this._margin.right;
                var _nodes = Array.isArray(this._nodes) ? this._nodes : this._links.reduce(function(all, d) {
                    if (!all.includes(d[_this._linksSource])) all.push(d[_this._linksSource]);
                    if (!all.includes(d[_this._linksTarget])) all.push(d[_this._linksTarget]);
                    return all;
                }, []).map(function(id) {
                    return {
                        id: id
                    };
                });
                var nodes = _nodes.map(function(n, i) {
                    return {
                        __d3plus__: true,
                        data: n,
                        i: i,
                        id: _this._nodeId(n, i),
                        node: n,
                        shape: "Rect"
                    };
                });
                var nodeLookup = this._nodeLookup = nodes.reduce(function(obj, d, i) {
                    obj[d.id] = i;
                    return obj;
                }, {});
                var links = this._links.map(function(link, i) {
                    var check = [
                        _this._linksSource,
                        _this._linksTarget
                    ];
                    var linkLookup = check.reduce(function(result, item) {
                        result[item] = nodeLookup[link[item]];
                        return result;
                    }, {});
                    return {
                        source: linkLookup[_this._linksSource],
                        target: linkLookup[_this._linksTarget],
                        value: _this._value(link, i)
                    };
                });
                this._linkLookup = links.reduce(function(obj, d) {
                    if (!obj[d.source]) obj[d.source] = [];
                    obj[d.source].push(d.target);
                    if (!obj[d.target]) obj[d.target] = [];
                    obj[d.target].push(d.source);
                    return obj;
                }, {});
                var transform = "translate(".concat(this._margin.left, ", ").concat(this._margin.top, ")");
                this._sankey.nodeAlign(this._nodeAlign).nodePadding(this._nodePadding).nodeWidth(this._nodeWidth).nodes(nodes).nodeSort(this._nodeSort).links(links).linkSort(this._linkSort).iterations(this._iterations).size([
                    width,
                    height
                ])();
                this._shapes.push(new Path().config(this._shapeConfig.Path).data(links).d(this._path).select(elem("g.d3plus-Links", {
                    parent: this._select,
                    enter: {
                        transform: transform
                    },
                    update: {
                        transform: transform
                    }
                }).node()).render());
                groups(nodes, function(d) {
                    return d.shape;
                }).forEach(function(param) {
                    var _param = _sliced_to_array(param, 2), key = _param[0], values = _param[1];
                    _this._shapes.push(new shapes[key]().data(values).height(function(d) {
                        return d.y1 - d.y0;
                    }).width(function(d) {
                        return d.x1 - d.x0;
                    }).x(function(d) {
                        return (d.x1 + d.x0) / 2;
                    }).y(function(d) {
                        return (d.y1 + d.y0) / 2;
                    }).select(elem("g.d3plus-sankey-nodes", {
                        parent: _this._select,
                        enter: {
                            transform: transform
                        },
                        update: {
                            transform: transform
                        }
                    }).node()).config(configPrep.bind(_this)(_this._shapeConfig, "shape", key)).render());
                });
                return this;
            }
        },
        {
            /**
      The hover callback function for highlighting shapes on mouseover.
*/ key: "hover",
            value: function hover(_) {
                this._hover = _;
                this._shapes.forEach(function(s) {
                    return s.hover(_);
                });
                if (this._legend) this._legendClass.hover(_);
                return this;
            }
        },
        {
            /**
      A pass-through for the d3-sankey [iterations](https://github.com/d3/d3-sankey?tab=readme-ov-file#sankey_iterations) function.
*/ key: "iterations",
            value: function iterations(_) {
                return arguments.length ? (this._iterations = _, this) : this._iterations;
            }
        },
        {
            /**
      A predefined *Array* of edges that connect each object passed to the [node](#Sankey.node) method. The `source` and `target` keys in each link need to map to the nodes in one of one way:
1. A *String* value matching the `id` of the node.

The value passed should be an *Array* of data. An optional formatting function can be passed as a second argument to this method. This custom function will be passed the data that has been loaded, as long as there are no errors. This function should return the final links *Array*.
    @param f Array of link objects or a URL to load links from.
*/ key: "links",
            value: function links(_, f) {
                if (arguments.length) {
                    addToQueue.bind(this)(_, f, "links");
                    return this;
                }
                return this._links;
            }
        },
        {
            /**
      A pass-through for the d3-sankey [linkSort](https://github.com/d3/d3-sankey?tab=readme-ov-file#sankey_linkSort) function.
*/ key: "linkSort",
            value: function linkSort(_) {
                return arguments.length ? (this._linkSort = _, this) : this._linkSort;
            }
        },
        {
            /**
      The key inside of each link Object that references the source node.
*/ key: "linksSource",
            value: function linksSource(_) {
                return arguments.length ? (this._linksSource = _, this) : this._linksSource;
            }
        },
        {
            /**
      The key inside of each link Object that references the target node.
*/ key: "linksTarget",
            value: function linksTarget(_) {
                return arguments.length ? (this._linksTarget = _, this) : this._linksTarget;
            }
        },
        {
            /**
      The nodeAlign property of the sankey layout, which can be "left", "right", "center", or "justify".
*/ key: "nodeAlign",
            value: function nodeAlign(_) {
                return arguments.length ? (this._nodeAlign = typeof _ === "function" ? _ : sankeyAligns[_], this) : this._nodeAlign;
            }
        },
        {
            /**
      The node id accessor(s).
*/ key: "nodeId",
            value: function nodeId(_) {
                return arguments.length ? (this._nodeId = typeof _ === "function" ? _ : accessor(_), this) : this._nodeId;
            }
        },
        {
            /**
      The list of nodes to be used for drawing the network. The value passed must be an *Array* of data.

Additionally, a custom formatting function can be passed as a second argument to this method. This custom function will be passed the data that has been loaded, as long as there are no errors. This function should return the final node *Array*.
    @param f Array of node objects or a URL to load nodes from.
*/ key: "nodes",
            value: function nodes(_, f) {
                if (arguments.length) {
                    addToQueue.bind(this)(_, f, "nodes");
                    return this;
                }
                return this._nodes;
            }
        },
        {
            /**
      Padding of the node. By default, the nodePadding size is 8.
*/ key: "nodePadding",
            value: function nodePadding(_) {
                return arguments.length ? (this._nodePadding = _, this) : this._nodePadding;
            }
        },
        {
            /**
      A pass-through for the d3-sankey [nodeSort](https://github.com/d3/d3-sankey?tab=readme-ov-file#sankey_nodeSort) function.
*/ key: "nodeSort",
            value: function nodeSort(_) {
                return arguments.length ? (this._nodeSort = _, this) : this._nodeSort;
            }
        },
        {
            /**
      Width of the node. By default, the nodeWidth size is 30.
*/ key: "nodeWidth",
            value: function nodeWidth(_) {
                return arguments.length ? (this._nodeWidth = _, this) : this._nodeWidth;
            }
        },
        {
            /**
      Width of the links.

@example
function value(d) {
  return d.value;
}
*/ key: "value",
            value: function value(_) {
                return arguments.length ? (this._value = typeof _ === "function" ? _ : accessor(_), this) : this._value;
            }
        }
    ]);
    return Sankey;
}(Viz);
/**
    Creates a sankey visualization based on a defined set of nodes and links. [Click here](http://d3plus.org/examples/d3plus-network/sankey-diagram/) for help getting started using the Sankey class.
*/ export { Sankey as default };
