d3.v4:如何设置每个Math.PI / 2的刻度

时间:2016-11-20 05:33:03

标签: d3.js

在d3.v4 documentation中,陈述如下:

  

要用时间刻度每15分钟生成一次滴答声,请说:

axis.tickArguments([d3.timeMinute.every(15)]);

是否有类似的方法可用于时间以外的值?我正在绘制正弦曲线和余弦曲线,所以我希望刻度线从-2 * Math.PI开始,以2 * Math.PI结束,在这些值之间,我想在每个Math.PI / 2。当然,我可以明确地计算刻度值并将它们提供给tickValue方法;但是,如果有一种更简单的方法可以实现这一点,就像上面引用的与时间相关的例子一样,我宁愿使用它。

3 个答案:

答案 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 tickValuestickFormat方法,在程序控制下(不是手动布局)以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