import “../scale/linear”; import “../scale/scale”; import “../selection/selection”; import “../transition/transition”; import “svg”;

d3.svg.axis = function() {

var scale = d3.scale.linear(),
    orient = d3_svg_axisDefaultOrient,
    tickMajorSize = 6,
    tickMinorSize = 6,
    tickEndSize = 6,
    tickPadding = 3,
    tickArguments_ = [10],
    tickValues = null,
    tickFormat_,
    tickSubdivide = 0;

function axis(g) {
  g.each(function() {
    var g = d3.select(this);

    // Ticks, or domain values for ordinal scales.
    var ticks = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain()) : tickValues,
        tickFormat = tickFormat_ == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : String) : tickFormat_;

    // Minor ticks.
    var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide),
        subtick = g.selectAll(".tick.minor").data(subticks, String),
        subtickEnter = subtick.enter().insert("line", ".tick").attr("class", "tick minor").style("opacity", 1e-6),
        subtickExit = d3.transition(subtick.exit()).style("opacity", 1e-6).remove(),
        subtickUpdate = d3.transition(subtick).style("opacity", 1);

    // Major ticks.
    var tick = g.selectAll(".tick.major").data(ticks, String),
        tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick major").style("opacity", 1e-6),
        tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(),
        tickUpdate = d3.transition(tick).style("opacity", 1),
        tickTransform;

    // Domain.
    var range = d3_scaleRange(scale),
        path = g.selectAll(".domain").data([0]),
        pathUpdate = (path.enter().append("path").attr("class", "domain"), d3.transition(path));

    // Stash a snapshot of the new scale, and retrieve the old snapshot.
    var scale1 = scale.copy(),
        scale0 = this.__chart__ || scale1;
    this.__chart__ = scale1;

    tickEnter.append("line");
    tickEnter.append("text");

    var lineEnter = tickEnter.select("line"),
        lineUpdate = tickUpdate.select("line"),
        text = tick.select("text").text(tickFormat),
        textEnter = tickEnter.select("text"),
        textUpdate = tickUpdate.select("text");

    switch (orient) {
      case "bottom": {
        tickTransform = d3_svg_axisX;
        subtickEnter.attr("y2", tickMinorSize);
        subtickUpdate.attr("x2", 0).attr("y2", tickMinorSize);
        lineEnter.attr("y2", tickMajorSize);
        textEnter.attr("y", Math.max(tickMajorSize, 0) + tickPadding);
        lineUpdate.attr("x2", 0).attr("y2", tickMajorSize);
        textUpdate.attr("x", 0).attr("y", Math.max(tickMajorSize, 0) + tickPadding);
        text.attr("dy", ".71em").style("text-anchor", "middle");
        pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize);
        break;
      }
      case "top": {
        tickTransform = d3_svg_axisX;
        subtickEnter.attr("y2", -tickMinorSize);
        subtickUpdate.attr("x2", 0).attr("y2", -tickMinorSize);
        lineEnter.attr("y2", -tickMajorSize);
        textEnter.attr("y", -(Math.max(tickMajorSize, 0) + tickPadding));
        lineUpdate.attr("x2", 0).attr("y2", -tickMajorSize);
        textUpdate.attr("x", 0).attr("y", -(Math.max(tickMajorSize, 0) + tickPadding));
        text.attr("dy", "0em").style("text-anchor", "middle");
        pathUpdate.attr("d", "M" + range[0] + "," + -tickEndSize + "V0H" + range[1] + "V" + -tickEndSize);
        break;
      }
      case "left": {
        tickTransform = d3_svg_axisY;
        subtickEnter.attr("x2", -tickMinorSize);
        subtickUpdate.attr("x2", -tickMinorSize).attr("y2", 0);
        lineEnter.attr("x2", -tickMajorSize);
        textEnter.attr("x", -(Math.max(tickMajorSize, 0) + tickPadding));
        lineUpdate.attr("x2", -tickMajorSize).attr("y2", 0);
        textUpdate.attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("y", 0);
        text.attr("dy", ".32em").style("text-anchor", "end");
        pathUpdate.attr("d", "M" + -tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + -tickEndSize);
        break;
      }
      case "right": {
        tickTransform = d3_svg_axisY;
        subtickEnter.attr("x2", tickMinorSize);
        subtickUpdate.attr("x2", tickMinorSize).attr("y2", 0);
        lineEnter.attr("x2", tickMajorSize);
        textEnter.attr("x", Math.max(tickMajorSize, 0) + tickPadding);
        lineUpdate.attr("x2", tickMajorSize).attr("y2", 0);
        textUpdate.attr("x", Math.max(tickMajorSize, 0) + tickPadding).attr("y", 0);
        text.attr("dy", ".32em").style("text-anchor", "start");
        pathUpdate.attr("d", "M" + tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + tickEndSize);
        break;
      }
    }

    // For ordinal scales:
    // - any entering ticks are undefined in the old scale
    // - any exiting ticks are undefined in the new scale
    // Therefore, we only need to transition updating ticks.
    if (scale.rangeBand) {
      var dx = scale1.rangeBand() / 2, x = function(d) { return scale1(d) + dx; };
      tickEnter.call(tickTransform, x);
      tickUpdate.call(tickTransform, x);
    }

    // For quantitative scales:
    // - enter new ticks from the old scale
    // - exit old ticks to the new scale
    else {
      tickEnter.call(tickTransform, scale0);
      tickUpdate.call(tickTransform, scale1);
      tickExit.call(tickTransform, scale1);
      subtickEnter.call(tickTransform, scale0);
      subtickUpdate.call(tickTransform, scale1);
      subtickExit.call(tickTransform, scale1);
    }
  });
}

axis.scale = function(x) {
  if (!arguments.length) return scale;
  scale = x;
  return axis;
};

axis.orient = function(x) {
  if (!arguments.length) return orient;
  orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient;
  return axis;
};

axis.ticks = function() {
  if (!arguments.length) return tickArguments_;
  tickArguments_ = arguments;
  return axis;
};

axis.tickValues = function(x) {
  if (!arguments.length) return tickValues;
  tickValues = x;
  return axis;
};

axis.tickFormat = function(x) {
  if (!arguments.length) return tickFormat_;
  tickFormat_ = x;
  return axis;
};

axis.tickSize = function(x, y) {
  if (!arguments.length) return tickMajorSize;
  var n = arguments.length - 1;
  tickMajorSize = +x;
  tickMinorSize = n > 1 ? +y : tickMajorSize;
  tickEndSize = n > 0 ? +arguments[n] : tickMajorSize;
  return axis;
};

axis.tickPadding = function(x) {
  if (!arguments.length) return tickPadding;
  tickPadding = +x;
  return axis;
};

axis.tickSubdivide = function(x) {
  if (!arguments.length) return tickSubdivide;
  tickSubdivide = +x;
  return axis;
};

return axis;

};

var d3_svg_axisDefaultOrient = “bottom”,

d3_svg_axisOrients = {top: 1, right: 1, bottom: 1, left: 1};

function d3_svg_axisX(selection, x) {

selection.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; });

}

function d3_svg_axisY(selection, y) {

selection.attr("transform", function(d) { return "translate(0," + y(d) + ")"; });

}

function d3_svg_axisSubdivide(scale, ticks, m) {

subticks = [];
if (m && ticks.length > 1) {
  var extent = d3_scaleExtent(scale.domain()),
      subticks,
      i = -1,
      n = ticks.length,
      d = (ticks[1] - ticks[0]) / ++m,
      j,
      v;
  while (++i < n) {
    for (j = m; --j > 0;) {
      if ((v = +ticks[i] - j * d) >= extent[0]) {
        subticks.push(v);
      }
    }
  }
  for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) {
    subticks.push(v);
  }
}
return subticks;

}