Guest User

Untitled

a guest
Nov 21st, 2018
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.03 KB | None | 0 0
  1. var d3co = {};
  2.  
  3. (function(ns){
  4.  
  5. ns.axis = axis;
  6. ns.axes = axes;
  7.  
  8. function axis() {
  9. var scale = d3.scale.linear(),
  10. orient = Math.PI/2, // default: "bottom"
  11. tickAngle = Math.PI/2, // angle between axis and ticks (affects labels and legend too)
  12. shift = 0, // translation along ticks
  13. legend = null,
  14. tickMajorSize = 6,
  15. tickMinorSize = 6,
  16. tickEndSize = 6,
  17. tickPadding = 3,
  18. tickArguments_ = [10],
  19. tickValues = null,
  20. tickFormat_,
  21. tickSubdivide = 0;
  22.  
  23. function axis(g) {
  24. g.each(function() {
  25. var g = d3.select(this);
  26.  
  27. // Ticks, or domain values for ordinal scales.
  28. var ticks = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain()) : tickValues,
  29. tickFormat = tickFormat_ == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : String) : tickFormat_;
  30.  
  31. // Minor ticks.
  32. var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide),
  33. subtick = g.selectAll(".minor").data(subticks, String),
  34. subtickEnter = subtick.enter().insert("line", "g").attr("class", "tick minor").style("opacity", 1e-6),
  35. subtickExit = d3.transition(subtick.exit()).style("opacity", 1e-6).remove(),
  36. subtickUpdate = d3.transition(subtick).style("opacity", 1);
  37.  
  38. // Major ticks.
  39. var tick = g.selectAll("g").data(ticks, String),
  40. tickEnter = tick.enter().insert("g", "path").style("opacity", 1e-6),
  41. tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(),
  42. tickUpdate = d3.transition(tick).style("opacity", 1),
  43. tickTransform;
  44.  
  45. // Domain.
  46. var range = d3_scaleRange(scale),
  47. path = g.selectAll(".domain").data([0]),
  48. pathEnter = path.enter().append("path").attr("class", "domain"),
  49. pathUpdate = d3.transition(path);
  50.  
  51. // Geometry for ticks, labels, legend
  52. var U = d3_svg_axisUnitVector(orient),
  53. tickU = d3_svg_axisUnitVector(orient + tickAngle),
  54. labelDist = Math.max(tickMajorSize, 0) + tickPadding,
  55. m = ((tickAngle / (2*Math.PI)) % 1 + 1) % 1 < .5 ? -1: 1,
  56. labelU = { x: (tickU.x+m*U.y)/2, y: (tickU.y-m*U.x)/2 };
  57.  
  58. var halfRange = (range[0] + range[1])/2,
  59. orientDeg = orient * 180 / Math.PI,
  60. legendDist = labelDist + 3*tickPadding,
  61. leg = g.selectAll("g.axisLegend").data([legend]);
  62.  
  63. // Stash a snapshot of the new scale, and retrieve the old snapshot.
  64. var scale1 = scale.copy(),
  65. scale0 = this.__chart__ || scale1;
  66. this.__chart__ = scale1;
  67.  
  68.  
  69. // shift group
  70. d3.transition(g).attr("transform", "translate("+shift*tickU.x+","+shift*tickU.y+")");
  71.  
  72. tickEnter.append("line").attr("class", "tick");
  73. tickEnter.append("text");
  74.  
  75. subtickEnter.attr("x2", tickMinorSize * tickU.x).attr("y2", tickMinorSize * tickU.y);
  76. subtickUpdate.attr("x2", tickMinorSize * tickU.x).attr("y2", tickMinorSize * tickU.y);
  77. tickEnter.select("line").attr("x2", tickMajorSize * tickU.x).attr("y2", tickMajorSize * tickU.y);
  78. tickEnter.select("text").attr("x", labelDist * labelU.x).attr("y", labelDist * labelU.y);
  79. tickUpdate.select("line").attr("x2", tickMajorSize * tickU.x).attr("y2", tickMajorSize * tickU.y);
  80. tickUpdate.select("text").text(tickFormat)
  81. .attr("x", labelDist * labelU.x).attr("y", labelDist * labelU.y).attr("dy", (labelU.y + 1) * .35 + "em")
  82. .attr("text-anchor", (Math.abs(labelU.y) > .5) ? "middle" : ((labelU.x > 0) ? "start": "end") );
  83. pathUpdate.attr("d", " M " + (range[0]*U.x + tickEndSize*tickU.x) + " " + (range[0]*U.y + tickEndSize*tickU.y) + " L " + range[0]*U.x + " " + range[0]*U.y + " L " + range[1]*U.x + " " + range[1]*U.y + " " + (range[1]*U.x + tickEndSize*tickU.x) + " " + (range[1]*U.y + tickEndSize*tickU.y));
  84.  
  85. tickTransform = function(selection, scale) {
  86. selection.attr("transform", function(d) { var r = scale(d); return "translate("+r*U.x+","+r*U.y+")"; });
  87. };
  88.  
  89. // For quantitative scales:
  90. // - enter new ticks from the old scale
  91. // - exit old ticks to the new scale
  92. if (scale.ticks) {
  93. tickEnter.call(tickTransform, scale0);
  94. tickUpdate.call(tickTransform, scale1);
  95. tickExit.call(tickTransform, scale1);
  96. subtickEnter.call(tickTransform, scale0);
  97. subtickUpdate.call(tickTransform, scale1);
  98. subtickExit.call(tickTransform, scale1);
  99. }
  100.  
  101. // For ordinal scales:
  102. // - any entering ticks are undefined in the old scale
  103. // - any exiting ticks are undefined in the new scale
  104. // Therefore, we only need to transition updating ticks.
  105. else {
  106. var dx = scale1.rangeBand() / 2, x = function(d) { return scale1(d) + dx; };
  107. tickEnter.call(tickTransform, x);
  108. tickUpdate.call(tickTransform, x);
  109. }
  110.  
  111. leg.enter().append("g").attr("class", "axisLegend").append("text");
  112. leg.attr("transform", "translate("+(halfRange*U.x + (m*U.y*legendDist))+","+(halfRange*U.y+(-m*U.x*legendDist))+")" + "rotate("+(orientDeg + (((orientDeg % 360)+360)%360 > 180 ? 90 : -90))+")")
  113. .select("text").text(legend).attr("text-anchor", "middle").attr("dy", "0em");
  114.  
  115. });
  116. }
  117.  
  118. axis.scale = function(x) {
  119. if (!arguments.length) return scale;
  120. scale = x;
  121. return axis;
  122. };
  123.  
  124. axis.orient = function(x) {
  125. if (!arguments.length) return orient;
  126. switch (x) {
  127. case "bottom": orient = tickAngle = Math.PI/2; break;
  128. case "top": orient = Math.PI/2; tickAngle = -Math.PI/2; break;
  129. case "left": orient = Math.PI; tickAngle = Math.PI/2; break;
  130. case "right": orient = Math.PI; tickAngle = -Math.PI/2; break;
  131. default: orient = x;
  132. }
  133. return axis;
  134. };
  135.  
  136. axis.orientVector = function(v) {
  137. if (!arguments.length) return d3_svg_axisUnitVector(orient);
  138. return axis.orient(Math.atan2(v.x,-v.y));
  139. };
  140.  
  141. axis.tickAngle = function(x) {
  142. if (!arguments.length) return tickAngle;
  143. tickAngle = x;
  144. return axis;
  145. };
  146.  
  147. axis.ticks = function() {
  148. if (!arguments.length) return tickArguments_;
  149. tickArguments_ = arguments;
  150. return axis;
  151. };
  152.  
  153. axis.tickValues = function(x) {
  154. if (!arguments.length) return tickValues;
  155. tickValues = x;
  156. return axis;
  157. };
  158.  
  159. axis.tickFormat = function(x) {
  160. if (!arguments.length) return tickFormat_;
  161. tickFormat_ = x;
  162. return axis;
  163. };
  164.  
  165. axis.tickSize = function(x, y, z) {
  166. if (!arguments.length) return tickMajorSize;
  167. var n = arguments.length - 1;
  168. tickMajorSize = +x;
  169. tickMinorSize = n > 1 ? +y : tickMajorSize;
  170. tickEndSize = n > 0 ? +arguments[n] : tickMajorSize;
  171. return axis;
  172. };
  173.  
  174. axis.tickPadding = function(x) {
  175. if (!arguments.length) return tickPadding;
  176. tickPadding = +x;
  177. return axis;
  178. };
  179.  
  180. axis.tickSubdivide = function(x) {
  181. if (!arguments.length) return tickSubdivide;
  182. tickSubdivide = +x;
  183. return axis;
  184. };
  185.  
  186. axis.shift = function(x) {
  187. if (!arguments.length) return shift;
  188. shift = x;
  189. return axis;
  190. };
  191.  
  192. axis.legend = function(x) {
  193. if (!arguments.length) return legend;
  194. legend = x;
  195. return axis;
  196. };
  197.  
  198. return axis;
  199. };
  200.  
  201. function d3_svg_axisUnitVector(orient) {
  202. var a = orient - Math.PI/2; // same as orient + d3_svg_arcOffset;
  203. return { x: Math.cos(a), y: Math.sin(a) };
  204. }
  205.  
  206. function d3_svg_axisSubdivide(scale, ticks, m) {
  207. var subticks = [];
  208. if (m && ticks.length > 1) {
  209. var extent = d3_scaleExtent(scale.domain()),
  210. i = -1,
  211. n = ticks.length,
  212. d = (ticks[1] - ticks[0]) / ++m,
  213. j,
  214. v;
  215. while (++i < n) {
  216. for (j = m; --j > 0;) {
  217. if ((v = +ticks[i] - j * d) >= extent[0]) {
  218. subticks.push(v);
  219. }
  220. }
  221. }
  222. for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) {
  223. subticks.push(v);
  224. }
  225. }
  226. return subticks;
  227. }
  228.  
  229. // copied from d3/scale/scale.js
  230. function d3_scaleExtent(domain) {
  231. var start = domain[0], stop = domain[domain.length - 1];
  232. return start < stop ? [start, stop] : [stop, start];
  233. }
  234.  
  235. function d3_scaleRange(scale) {
  236. return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range());
  237. }
  238.  
  239.  
  240. function axes(){
  241.  
  242. var axis1 = ns.axis().orient('bottom'),
  243. axis2 = ns.axis().orient('right');
  244.  
  245. function axes(selection){
  246. selection.each(function (d, i) {
  247.  
  248. var g = d3.select(this),
  249. a1 = g.selectAll('.axis.axis1').data([0]), a2 = g.selectAll('.axis.axis2').data([0]),
  250. u1 = axis1.orientVector(), u2 = axis2.orientVector(),
  251. angle = axis1.orient() - axis2.orient();
  252.  
  253. a1.enter().append('g').attr('class', 'axis1 axis');
  254. a2.enter().append('g').attr('class', 'axis2 axis');
  255.  
  256. a1.call(axis1/*.tickAngle(-angle)*/);
  257. a2.call(axis2/*.tickAngle(angle)*/);
  258.  
  259. });
  260.  
  261. return selection;
  262. }
  263.  
  264. axes.axis1 = function(x){
  265. if (!arguments.length) return axis1;
  266. axis1 = x;
  267. return axes;
  268. };
  269.  
  270. axes.axis2 = function(x){
  271. if (!arguments.length) return axis2;
  272. axis2 = x;
  273. return axes;
  274. };
  275.  
  276. axes.translate = function(c1, c2){
  277. var s1 = axis1.scale()(c1), s2 = axis2.scale()(c2),
  278. u1 = axis1.orientVector(), u2 = axis2.orientVector();
  279. return { x: s1*u1.x + s2*u2.x, y: s1*u1.y + s2*u2.y };
  280. };
  281.  
  282. return axes;
  283.  
  284. }
  285.  
  286. })(d3co);
Add Comment
Please, Sign In to add comment