toolkit/javascript/d3/src/svg/axis.js
changeset 47 c0b4a8b5a012
equal deleted inserted replaced
46:efd9c589177a 47:c0b4a8b5a012
       
     1 d3.svg.axis = function() {
       
     2   var scale = d3.scale.linear(),
       
     3       orient = "bottom",
       
     4       tickMajorSize = 6,
       
     5       tickMinorSize = 6,
       
     6       tickEndSize = 6,
       
     7       tickPadding = 3,
       
     8       tickArguments_ = [10],
       
     9       tickFormat_,
       
    10       tickSubdivide = 0;
       
    11 
       
    12   function axis(selection) {
       
    13     selection.each(function(d, i, j) {
       
    14       var g = d3.select(this);
       
    15 
       
    16       // If selection is a transition, create subtransitions.
       
    17       var transition = selection.delay ? function(o) {
       
    18         var id = d3_transitionInheritId;
       
    19         try {
       
    20           d3_transitionInheritId = selection.id;
       
    21           return o.transition()
       
    22               .delay(selection[j][i].delay)
       
    23               .duration(selection[j][i].duration)
       
    24               .ease(selection.ease());
       
    25         } finally {
       
    26           d3_transitionInheritId = id;
       
    27         }
       
    28       } : Object;
       
    29 
       
    30       // Ticks.
       
    31       var ticks = scale.ticks.apply(scale, tickArguments_),
       
    32           tickFormat = tickFormat_ == null ? scale.tickFormat.apply(scale, tickArguments_) : tickFormat_;
       
    33 
       
    34       // Minor ticks.
       
    35       var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide),
       
    36           subtick = g.selectAll(".minor").data(subticks, String),
       
    37           subtickEnter = subtick.enter().insert("svg:line", "g").attr("class", "tick minor").style("opacity", 1e-6),
       
    38           subtickExit = transition(subtick.exit()).style("opacity", 1e-6).remove(),
       
    39           subtickUpdate = transition(subtick).style("opacity", 1);
       
    40 
       
    41       // Major ticks.
       
    42       var tick = g.selectAll("g").data(ticks, String),
       
    43           tickEnter = tick.enter().insert("svg:g", "path").style("opacity", 1e-6),
       
    44           tickExit = transition(tick.exit()).style("opacity", 1e-6).remove(),
       
    45           tickUpdate = transition(tick).style("opacity", 1),
       
    46           tickTransform;
       
    47 
       
    48       // Domain.
       
    49       var range = d3_scaleExtent(scale.range()),
       
    50           path = g.selectAll(".domain").data([0]),
       
    51           pathEnter = path.enter().append("svg:path").attr("class", "domain"),
       
    52           pathUpdate = transition(path);
       
    53 
       
    54       // Stash the new scale and grab the old scale.
       
    55       var scale0 = this.__chart__ || scale;
       
    56       this.__chart__ = scale.copy();
       
    57 
       
    58       tickEnter.append("svg:line").attr("class", "tick");
       
    59       tickEnter.append("svg:text");
       
    60       tickUpdate.select("text").text(tickFormat);
       
    61 
       
    62       switch (orient) {
       
    63         case "bottom": {
       
    64           tickTransform = d3_svg_axisX;
       
    65           subtickUpdate.attr("x2", 0).attr("y2", tickMinorSize);
       
    66           tickUpdate.select("line").attr("x2", 0).attr("y2", tickMajorSize);
       
    67           tickUpdate.select("text").attr("x", 0).attr("y", Math.max(tickMajorSize, 0) + tickPadding).attr("dy", ".71em").attr("text-anchor", "middle");
       
    68           pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize);
       
    69           break;
       
    70         }
       
    71         case "top": {
       
    72           tickTransform = d3_svg_axisX;
       
    73           subtickUpdate.attr("x2", 0).attr("y2", -tickMinorSize);
       
    74           tickUpdate.select("line").attr("x2", 0).attr("y2", -tickMajorSize);
       
    75           tickUpdate.select("text").attr("x", 0).attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("dy", "0em").attr("text-anchor", "middle");
       
    76           pathUpdate.attr("d", "M" + range[0] + "," + -tickEndSize + "V0H" + range[1] + "V" + -tickEndSize);
       
    77           break;
       
    78         }
       
    79         case "left": {
       
    80           tickTransform = d3_svg_axisY;
       
    81           subtickUpdate.attr("x2", -tickMinorSize).attr("y2", 0);
       
    82           tickUpdate.select("line").attr("x2", -tickMajorSize).attr("y2", 0);
       
    83           tickUpdate.select("text").attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("y", 0).attr("dy", ".32em").attr("text-anchor", "end");
       
    84           pathUpdate.attr("d", "M" + -tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + -tickEndSize);
       
    85           break;
       
    86         }
       
    87         case "right": {
       
    88           tickTransform = d3_svg_axisY;
       
    89           subtickUpdate.attr("x2", tickMinorSize).attr("y2", 0);
       
    90           tickUpdate.select("line").attr("x2", tickMajorSize).attr("y2", 0);
       
    91           tickUpdate.select("text").attr("x", Math.max(tickMajorSize, 0) + tickPadding).attr("y", 0).attr("dy", ".32em").attr("text-anchor", "start");
       
    92           pathUpdate.attr("d", "M" + tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + tickEndSize);
       
    93           break;
       
    94         }
       
    95       }
       
    96 
       
    97       tickEnter.call(tickTransform, scale0);
       
    98       tickUpdate.call(tickTransform, scale);
       
    99       tickExit.call(tickTransform, scale);
       
   100 
       
   101       subtickEnter.call(tickTransform, scale0);
       
   102       subtickUpdate.call(tickTransform, scale);
       
   103       subtickExit.call(tickTransform, scale);
       
   104     });
       
   105   }
       
   106 
       
   107   axis.scale = function(x) {
       
   108     if (!arguments.length) return scale;
       
   109     scale = x;
       
   110     return axis;
       
   111   };
       
   112 
       
   113   axis.orient = function(x) {
       
   114     if (!arguments.length) return orient;
       
   115     orient = x;
       
   116     return axis;
       
   117   };
       
   118 
       
   119   axis.ticks = function() {
       
   120     if (!arguments.length) return tickArguments_;
       
   121     tickArguments_ = arguments;
       
   122     return axis;
       
   123   };
       
   124 
       
   125   axis.tickFormat = function(x) {
       
   126     if (!arguments.length) return tickFormat_;
       
   127     tickFormat_ = x;
       
   128     return axis;
       
   129   };
       
   130 
       
   131   axis.tickSize = function(x, y, z) {
       
   132     if (!arguments.length) return tickMajorSize;
       
   133     var n = arguments.length - 1;
       
   134     tickMajorSize = +x;
       
   135     tickMinorSize = n > 1 ? +y : tickMajorSize;
       
   136     tickEndSize = n > 0 ? +arguments[n] : tickMajorSize;
       
   137     return axis;
       
   138   };
       
   139 
       
   140   axis.tickPadding = function(x) {
       
   141     if (!arguments.length) return tickPadding;
       
   142     tickPadding = +x;
       
   143     return axis;
       
   144   };
       
   145 
       
   146   axis.tickSubdivide = function(x) {
       
   147     if (!arguments.length) return tickSubdivide;
       
   148     tickSubdivide = +x;
       
   149     return axis;
       
   150   };
       
   151 
       
   152   return axis;
       
   153 };
       
   154 
       
   155 function d3_svg_axisX(selection, x) {
       
   156   selection.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; });
       
   157 }
       
   158 
       
   159 function d3_svg_axisY(selection, y) {
       
   160   selection.attr("transform", function(d) { return "translate(0," + y(d) + ")"; });
       
   161 }
       
   162 
       
   163 function d3_svg_axisSubdivide(scale, ticks, m) {
       
   164   subticks = [];
       
   165   if (m && ticks.length > 1) {
       
   166     var extent = d3_scaleExtent(scale.domain()),
       
   167         subticks,
       
   168         i = -1,
       
   169         n = ticks.length,
       
   170         d = (ticks[1] - ticks[0]) / ++m,
       
   171         j,
       
   172         v;
       
   173     while (++i < n) {
       
   174       for (j = m; --j > 0;) {
       
   175         if ((v = +ticks[i] - j * d) >= extent[0]) {
       
   176           subticks.push(v);
       
   177         }
       
   178       }
       
   179     }
       
   180     for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) {
       
   181       subticks.push(v);
       
   182     }
       
   183   }
       
   184   return subticks;
       
   185 }