在d3.v4 documentation中,陈述如下:
要用时间刻度每15分钟生成一次滴答声,请说:
axis.tickArguments([d3.timeMinute.every(15)]);
是否有类似的方法可用于时间以外的值?我正在绘制正弦曲线和余弦曲线,所以我希望刻度线从-2 * Math.PI开始,以2 * Math.PI结束,在这些值之间,我想在每个Math.PI / 2。当然,我可以明确地计算刻度值并将它们提供给tickValue方法;但是,如果有一种更简单的方法可以实现这一点,就像上面引用的与时间相关的例子一样,我宁愿使用它。
答案 0 :(得分:2)
设置结束标记并以线性标度指定标记的精确空间是一个痛苦的问题。原因是D3轴生成器的创建方式使得刻度线自动生成和间隔。因此,对于那些不太关心定制的人而言,对于那些想要精确定制的人来说,这样做会很麻烦。
我的解决方案是 hack :创建两个比例,一个用于绘制数据的线性比例,以及第二个比例,你将仅用于制作轴,您可以根据自己的意愿设置其值。在这里,我为顺序量表选择VALUES (?s ?p ?o) { (<http://abc#X> <http://abc#P1> UNDEF)
(UNDEF <http://abc#P2> <http://abc#Y>) }
。
这样的事情:
scalePoint()
不要介意var realScale = d3.scaleLinear()
.range([10,width-10])
.domain([-2*Math.PI, 2*Math.PI]);
var axisScale = d3.scalePoint()
.range([10,width-10])
.domain(["-2 \u03c0", "-1.5 \u03c0", "-\u03c0", "-0.5 \u03c0", "0",
"0.5 \u03c0", "\u03c0", "1.5 \u03c0", "2 \u03c0"]);
,这只是Unicode中的π(pi)。
检查此演示,将鼠标悬停在圈子上以查看其位置:
\u03c0
var width = 500,
height = 150;
var data = [-2, -1, 0, 0.5, 1.5];
var realScale = d3.scaleLinear()
.range([10, width - 10])
.domain([-2 * Math.PI, 2 * Math.PI]);
var axisScale = d3.scalePoint()
.range([10, width - 10])
.domain(["-2 \u03c0", "-1.5 \u03c0", "-\u03c0", "-0.5 \u03c0", "0", "0.5 \u03c0", "\u03c0", "1.5 \u03c0", "2 \u03c0"]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var circles = svg.selectAll("circle").data(data)
.enter()
.append("circle")
.attr("r", 8)
.attr("fill", "teal")
.attr("cy", 50)
.attr("cx", function(d) {
return realScale(d * Math.PI)
})
.append("title")
.text(function(d) {
return "this circle is at " + d + " \u03c0"
});
var axis = d3.axisBottom(axisScale);
var gX = svg.append("g")
.attr("transform", "translate(0,100)")
.call(axis);
答案 1 :(得分:0)
我能够通过目标D3 tickValues
和tickFormat
方法,在程序控制下(不是手动布局)以PI / 2为单位实现x轴。对tickValues
的调用以PI / 2的间隔设置滴答。对tickFormat
的调用会生成相应的刻度标签。您可以在GitHub上查看完整代码:
https://github.com/quantbo/sine_cosine
答案 2 :(得分:0)
我的解决方案是自定义tickValues和tickFormat。仅需要1个小数位,并且委托d3.ticks函数可以为我提供与Math.PI成正比的新tickValues。
const piChar = String.fromCharCode(960);
const tickFormat = val => {
const piVal = val / Math.PI;
return piVal + piChar;
};
const convertSIToTrig = siDomain => {
const trigMin = siDomain[0] / Math.PI;
const trigMax = siDomain[1] / Math.PI;
return d3.ticks(trigMin, trigMax, 10).map(v => v * Math.PI);
};
const xScale = d3.scaleLinear().domain([-Math.PI * 2, Math.PI * 2]).range([0, 600]);
const xAxis = d3.axisBottom(xScale)
.tickValues(convertSIToTrig(xScale.domain()))
.tickFormat(tickFormat);
这样,如果通过缩放/平移更改了xScale的域,则会以较小/较大的间隔很好地生成新的tickValues