这将是一个日志量表的替代,以便它可以处理负数.没有看到很多自定义尺度的例子,尽管我一直在尝试使用d3的对数刻度的源作为起点.
解决方法
据我所知,没有办法在D3中进行自定义刻度(至少不是在你想要的意义上).所有D3尺度分为两个步骤:
>使用域,去插入给定一个去插值函数的输入
>使用范围,插入来自步骤1的中间结果以获得输出
我相信你的理想答案基本上可以回答这个问题,“如何将D3刻度的去插值功能设置为自定义的功能?”,我认为这是不可能的.
但是,您可以设置内插函数.来自Mike Bostock的示例显示了如何使用D3内置的简单功能之一设置插值:
http://bl.ocks.org/mbostock/56ea94205411ee9e4dbec3742f7ad08c
这个例子有一个“鱼眼镜头”效果,这可能与你想要的相反.您可以使用指数小于1的多项式缓和函数d3.easePolyInOut来获得更接近日志缩放的内容(请参阅我的代码段).不幸的是,没有“logInOut”或“asinhInOut”,所以如果你需要更陡峭的滚动(而不是多项式),那么你必须编写自己的缓动/插值函数.
var data = Array.from(Array(21),(_,i)=>{return 10*(i-10)}) var svg = d3.select("svg"),margin = {top: 50,right: 20,bottom: 5,left: 20},width = svg.attr("width") - margin.left - margin.right,height = svg.attr("height") - margin.top - margin.bottom,g = svg.append("g").attr("transform","translate(" + margin.left + "," + margin.top + ")"); var polyexp = 0.25 var x = d3.scaleLinear() .domain([-100,100]) .range([0,width]) .interpolate(easeInterpolate(d3.easePolyInOut.exponent(polyexp))); g.append("g") .attr("class","axis axis--x") .call(d3.axisBottom(x)); g.selectAll("circle").data(data).enter().append("circle") .attr("cx",(d) => x(d)) .attr("cy",-10) .attr("r",3) .attr("fill","steelblue") function easeInterpolate(ease) { return function(a,b) { var i = d3.interpolate(a,b); return function(t) { return i(ease(t)); }; }; }
.axis text { font: 10px sans-serif; } .axis path,.axis line { fill: none; stroke: #000; shape-rendering: crispEdges; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.js"></script> <svg width="600" height="100"></svg>