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 _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 _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 _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 { Axis } from "../components/index.js";
import { assign, elem } from "@d3plus/dom";
import { Rect } from "../shapes/index.js";
import { accessor, configPrep, getProp } from "../utils/index.js";
import Viz from "./Viz.js";
import prepData from "./helpers/matrixData.js";
var defaultAxisConfig = {
    align: "start",
    barConfig: {
        stroke: 0
    },
    gridSize: 0,
    padding: 5,
    paddingInner: 0,
    paddingOuter: 0,
    scale: "band",
    tickSize: 0
};
var Matrix = /*#__PURE__*/ function(Viz) {
    "use strict";
    _inherits(Matrix, Viz);
    function Matrix() {
        _class_call_check(this, Matrix);
        var _this;
        _this = _call_super(this, Matrix);
        _this._cellPadding = 2;
        _this._column = accessor("column");
        _this._columnAxis = new Axis();
        _this._columnConfig = assign({
            orient: "top"
        }, defaultAxisConfig);
        _this._columnSort = function(a, b) {
            return "".concat(a).localeCompare("".concat(b));
        };
        _this._label = function(d, i) {
            return "".concat(getProp.bind(_this)("row", d, i), " / ").concat(getProp.bind(_this)("column", d, i));
        };
        var defaultMouseMoveShape = _this._on["mousemove.shape"];
        _this._on["mousemove.shape"] = function(d, i, x, event) {
            defaultMouseMoveShape(d, i, x, event);
            var row = getProp.bind(_this)("row", d, i);
            var column = getProp.bind(_this)("column", d, i);
            _this.hover(function(h, ii) {
                return getProp.bind(_this)("row", h, ii) === row || getProp.bind(_this)("column", h, ii) === column;
            });
        };
        _this._row = accessor("row");
        _this._rowAxis = new Axis();
        _this._rowConfig = assign({
            orient: "left"
        }, defaultAxisConfig);
        _this._rowSort = function(a, b) {
            return "".concat(a).localeCompare("".concat(b));
        };
        return _this;
    }
    _create_class(Matrix, [
        {
            /**
      Extends the draw behavior of the abstract Viz class.
      @private
  */ key: "_draw",
            value: function _draw(callback) {
                var _prepData_bind = prepData.bind(this)(this._filteredData), rowValues = _prepData_bind.rowValues, columnValues = _prepData_bind.columnValues, shapeData = _prepData_bind.shapeData;
                if (!rowValues.length || !columnValues.length) return this;
                var height = this._height - this._margin.top - this._margin.bottom, parent = this._select, transition = this._transition, width = this._width - this._margin.left - this._margin.right;
                var hidden = {
                    opacity: 0
                };
                var visible = {
                    opacity: 1
                };
                var columnRotation = width / columnValues.length < 120;
                var selectElem = function selectElem(name, opts) {
                    return elem("g.d3plus-Matrix-".concat(name), Object.assign({
                        parent: parent,
                        transition: transition
                    }, opts)).node();
                };
                this._rowAxis.select(selectElem("row", {
                    enter: hidden,
                    update: hidden
                })).domain(rowValues).height(height - this._margin.top - this._margin.bottom - this._padding.bottom - this._padding.top).maxSize(width / 4).width(width).config(this._rowConfig).render();
                var rowPadding = this._rowAxis.outerBounds().width;
                this._padding.left += rowPadding;
                var columnTransform = "translate(0, ".concat(this._margin.top, ")");
                var hiddenTransform = Object.assign({
                    transform: columnTransform
                }, hidden);
                this._columnAxis.select(selectElem("column", {
                    enter: hiddenTransform,
                    update: hiddenTransform
                })).domain(columnValues).range([
                    this._margin.left + this._padding.left,
                    width - this._margin.right + this._padding.right
                ]).height(height).maxSize(height / 4).width(width).labelRotation(columnRotation).config(this._columnConfig).render();
                var columnPadding = this._columnAxis.outerBounds().height;
                this._padding.top += columnPadding;
                _get(_get_prototype_of(Matrix.prototype), "_draw", this).call(this, callback);
                var rowTransform = "translate(".concat(this._margin.left, ", ").concat(this._margin.top, ")");
                columnTransform = "translate(0, ".concat(this._margin.top, ")");
                var visibleTransform = Object.assign({
                    transform: columnTransform
                }, visible);
                this._rowAxis.select(selectElem("row", {
                    update: Object.assign({
                        transform: rowTransform
                    }, visible)
                })).height(height - this._margin.top - this._margin.bottom - this._padding.bottom).maxSize(rowPadding).range([
                    columnPadding + this._columnAxis.padding(),
                    undefined
                ]).render();
                this._columnAxis.select(selectElem("column", {
                    update: visibleTransform
                })).range([
                    this._margin.left + this._padding.left + this._rowAxis.padding(),
                    width - this._margin.right + this._padding.right
                ]).maxSize(columnPadding).render();
                var rowScale = this._rowAxis._getPosition.bind(this._rowAxis);
                var columnScale = this._columnAxis._getPosition.bind(this._columnAxis);
                var cellHeight = rowValues.length > 1 ? rowScale(rowValues[1]) - rowScale(rowValues[0]) : this._rowAxis.height();
                var cellWidth = columnValues.length > 1 ? columnScale(columnValues[1]) - columnScale(columnValues[0]) : this._columnAxis.width();
                var transform = "translate(0, ".concat(this._margin.top, ")");
                var rectConfig = configPrep.bind(this)(this._shapeConfig, "shape", "Rect");
                this._shapes.push(new Rect().data(shapeData).select(elem("g.d3plus-Matrix-cells", {
                    parent: this._select,
                    enter: {
                        transform: transform
                    },
                    update: {
                        transform: transform
                    }
                }).node()).config({
                    height: cellHeight - this._cellPadding,
                    width: cellWidth - this._cellPadding,
                    x: function x(d) {
                        return columnScale(d.column) + cellWidth / 2;
                    },
                    y: function y(d) {
                        return rowScale(d.row) + cellHeight / 2;
                    }
                }).config(rectConfig).render());
                return this;
            }
        },
        {
            /**
      The pixel padding in between each cell.
*/ key: "cellPadding",
            value: function cellPadding(_) {
                return arguments.length ? (this._cellPadding = _, this) : this._cellPadding;
            }
        },
        {
            /**
      Determines which key in your data should be used for each column in the matrix. Can be either a String that matches a key used in every data point, or an accessor function that receives a data point and it's index in the data array, and is expected to return it's column value.

@example
function column(d) {
  return d.name;
}
  */ key: "column",
            value: function column(_) {
                return arguments.length ? (this._column = typeof _ === "function" ? _ : accessor(_), this) : this._column;
            }
        },
        {
            /**
      A pass-through to the underlying [Axis](http://d3plus.org/docs/#Axis) config used for the column labels.
*/ key: "columnConfig",
            value: function columnConfig(_) {
                return arguments.length ? (this._columnConfig = assign(this._columnConfig, _), this) : this._columnConfig;
            }
        },
        {
            /**
      A manual list of IDs to be used for columns.
*/ key: "columnList",
            value: function columnList(_) {
                return arguments.length ? (this._columnList = _, this) : this._columnList;
            }
        },
        {
            /**
      A sort comparator function that is run on the unique set of column values.

@example
function column(a, b) {
  return a.localeCompare(b);
}
  */ key: "columnSort",
            value: function columnSort(_) {
                return arguments.length ? (this._columnSort = _, this) : this._columnSort;
            }
        },
        {
            /**
      Determines which key in your data should be used for each row in the matrix. Can be either a String that matches a key used in every data point, or an accessor function that receives a data point and it's index in the data array, and is expected to return it's row value.

@example
function row(d) {
  return d.name;
}
  */ key: "row",
            value: function row(_) {
                return arguments.length ? (this._row = typeof _ === "function" ? _ : accessor(_), this) : this._row;
            }
        },
        {
            /**
      A pass-through to the underlying [Axis](http://d3plus.org/docs/#Axis) config used for the row labels.
*/ key: "rowConfig",
            value: function rowConfig(_) {
                return arguments.length ? (this._rowConfig = assign(this._rowConfig, _), this) : this._rowConfig;
            }
        },
        {
            /**
      A manual list of IDs to be used for rows.
*/ key: "rowList",
            value: function rowList(_) {
                return arguments.length ? (this._rowList = _, this) : this._rowList;
            }
        },
        {
            /**
      A sort comparator function that is run on the unique set of row values.

@example
function row(a, b) {
  return a.localeCompare(b);
}
  */ key: "rowSort",
            value: function rowSort(_) {
                return arguments.length ? (this._rowSort = _, this) : this._rowSort;
            }
        }
    ]);
    return Matrix;
}(Viz);
/**
    Creates a simple rows/columns Matrix view of any dataset. See [this example](https://d3plus.org/examples/d3plus-matrix/getting-started/) for help getting started using the Matrix class.
*/ export { Matrix as default };
