var _excluded = ["stroke", "length"],
  _excluded2 = ["fill", "label"],
  _excluded3 = ["ticks"],
  _excluded4 = ["ticks"];
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
import React, { useEffect } from 'react';
import * as R from 'ramda';
import { format } from 'd3-format';
import { scaleLinear } from 'd3-scale';
import styles from "./axes.module.css";
var getTickLabels = R.curry(function (scale, nticks) {
  var formatter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : format('.2~f');
  var ticks = scale.nice(nticks).ticks(nticks);
  var scaled = R.map(n => Math.round(n * 10) / 10)(R.map(scale)(ticks));
  var formatted = R.map(formatter)(ticks);
  return {
    scaled,
    formatted
  };
});

// Note with scales:
// The scales are exported from axes.js and passed as args to the
// axes you use so that is is configurable. They are used in here, 
// but only generically as passed args.
var linearYScale = props => {
  var ymax = props.ydata ? Math.max(...props.ydata) : props.ymax;
  return scaleLinear().domain([0, ymax]).range([0, props.height]);
};
var scaleHistLin = props => {
  var max = Math.max(...props.xdata) * (1 + 1 / props.nbins);
  return scaleLinear().domain([0, max]).range([0, props.width]);
};
var customYscale = R.curry((yscale, min, max, props) => {
  var ymin = min ? min : 0;
  var ymax = max ? max : props.ydata ? Math.max(...props.ydata) : props.ymax;
  return yscale().domain([ymin, ymax]).range([0, props.height]);
});
var customXscale = R.curry((xscale, min, max, props) => {
  var xmin = min ? min : 0;
  var xmax = max ? max : Math.max(...props.xdata) * (1 + 1 / props.nbins);
  return xscale().domain([xmin, xmax]).range([0, props.width]);
});
var symLogscale = R.curry(function (symscale, min, anchor, max, props) {
  var isX = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
  var dmin = min ? min : 0;
  var dmax = max ? max : isX ? Math.max(...props.xdata) * (1 + 1 / props.nbins) : Math.max(...props.ydata);
  var rangemax = isX ? Math.max(...props.xdata) : Math.max(...props.ydata);
  return symscale().domain([dmin, dmax]).constant(anchor).range([0, rangemax]);
});
var TickLine = _ref => {
  var {
      stroke,
      length
    } = _ref,
    other = _objectWithoutProperties(_ref, _excluded);
  stroke = stroke ? stroke : '#000';
  return /*#__PURE__*/React.createElement("line", _extends({
    className: styles.ticklineRendering,
    stroke: stroke
  }, other));
};
var Gtext = _ref2 => {
  var {
      fill,
      label
    } = _ref2,
    other = _objectWithoutProperties(_ref2, _excluded2);
  fill = fill ? fill : '#000';
  // Use y/dy for Bottomaxis, x/dx for side axes.
  return /*#__PURE__*/React.createElement("text", _extends({
    fill: fill
  }, other), label);
};
var Tick = _ref3 => {
  var {
    stroke,
    offset,
    label,
    line,
    text
  } = _ref3;
  var trans = "translate(0,".concat(offset, ")");
  if (line.y2) {
    trans = "translate(".concat(offset, ",0)");
  }
  return /*#__PURE__*/React.createElement("g", {
    transform: trans
  }, /*#__PURE__*/React.createElement(TickLine, _extends({
    stroke: stroke
  }, line)), /*#__PURE__*/React.createElement(Gtext, _extends({
    fill: stroke,
    label: label
  }, text)));
};
var TickSet = _ref4 => {
  var {
      ticks
    } = _ref4,
    other = _objectWithoutProperties(_ref4, _excluded3);
  return R.map(_ref5 => {
    var [off, lab] = _ref5;
    return /*#__PURE__*/React.createElement(Tick, _extends({}, other, {
      key: off,
      label: lab,
      offset: off
    }));
  })(ticks);
};

// Dumb just means there is no scaling and it takes a guess
// at how to space the ticks based on the width or height arg
var TickDumbSet = _ref6 => {
  var {
      ticks
    } = _ref6,
    other = _objectWithoutProperties(_ref6, _excluded4);
  var stackvert = other.stackvert ? other.stackvert : false;
  var offset = 0;
  var format = other.format ? other.format : n => n;
  return R.map(lab => {
    offset = stackvert ? offset + other.height : offset + other.width;
    return /*#__PURE__*/React.createElement(Tick, _extends({}, other, {
      key: offset,
      label: format(lab),
      offset: offset
    }));
  })(ticks);
};

// axis bottom will assume it is for X data and do all tick, limits, and
// scaling accordingly (using xdata).
// Also sets up the ticks and text to be aligned below the axis.
var AxisBottom = props => {
  var xscale = props.scale(props);
  var {
    scaled,
    formatted
  } = getTickLabels(xscale, props.xticks, props.tickformat);
  var ticks = R.zip(scaled, formatted);
  var defaultStyle = {
    stroke: '#000000'
  };
  var data0 = props.xdata[0];
  useEffect(() => {
    props.limitHook && props.limitHook.setXscale(() => xscale);
    props.xscaleSet(() => xscale);
    props.limitHook && props.limitHook.setRawLims('x', [Math.max(...props.xdata), Math.min(...props.xdata)]);
  }, [props.xdata.length, data0]);
  return /*#__PURE__*/React.createElement("g", {
    transform: "translate(0,".concat(props.height, ")"),
    style: props.style ? props.style : {
      fontSize: '0.8rem'
    }
  }, /*#__PURE__*/React.createElement("line", {
    x1: -1,
    y1: 1,
    x2: props.width,
    y2: 1,
    style: props.linestyle ? props.linestyle : defaultStyle,
    className: styles.axesbottomRendering
    // css={{ shapeRendering: "geometricPrecision"}} 
  }), /*#__PURE__*/React.createElement(TickSet, {
    ticks: ticks,
    line: {
      y2: 6
    },
    text: {
      // anchors middle of text to midpoint left to right
      style: {
        textAnchor: 'middle'
      },
      y: 6,
      dy: '0.9em'
    }
  }));
};

// AxisLeft looks for y data but will operate without it as long as
// some other child sets the ymax value. If that is not set, uses a default.
// Sets up the ticks outside and to the left using what is know about ydata.
// Not configured to deal with Y data only charts like horizontal bars. 
var AxisLeft = props => {
  var yscale = props.scale(props);
  var {
    scaled,
    formatted
  } = getTickLabels(yscale, props.yticks, props.tickformat);
  var ticks = R.zip(R.map(n => Math.round((scaled[scaled.length - 1] - n) * 10) / 10 + 1, R.reverse(scaled)), R.reverse(formatted));
  var defaultStyle = {
    stroke: '#000000'
  };
  useEffect(() => {
    props.yscaleSet(() => yscale);
    props.ydata && props.limitHook.setRawLims('y', [Math.max(...props.ydata), Math.min(...props.ydata)]);
  }, [props.ydata, props.ymax]);
  return /*#__PURE__*/React.createElement("g", {
    textAnchor: "end",
    style: props.style ? props.style : {
      fontSize: '0.8rem'
    }
  }, /*#__PURE__*/React.createElement("line", {
    x1: 0,
    y1: props.height,
    x2: 0,
    y2: 0,
    style: props.linestyle ? props.linestyle : defaultStyle,
    className: styles.axesleftRendering
    // css={{ shapeRendering: "geometricPrecision"}}
  }), /*#__PURE__*/React.createElement(TickSet, {
    ticks: ticks,
    line: {
      x2: -6
    },
    text: {
      style: {
        dominantBaseline: 'mathematical'
      },
      x: -6,
      dx: '-0.4em'
    }
  }));
};
export { customYscale, customXscale, linearYScale, scaleHistLin, AxisBottom, AxisLeft, Tick, TickSet, TickDumbSet, TickLine, Gtext, getTickLabels };