d3 - 如何显示持续时间间隔而不是tickValues

时间:2016-11-28 10:29:06

标签: javascript d3.js svg

让我们考虑一张水平条形图,如附图所示。我需要显示每个细分的持续时间以及x-axis。我可以使用d3.svg.axis().tickValues(vals)显示刻度值。

但我需要在两个刻度之间显示持续时间。任何人都可以帮助我使用d3实现这一目标吗? enter image description here 提前谢谢。

1 个答案:

答案 0 :(得分:1)

这是我的解决方案。我使用D3版本3(因为你在你的问题中写了 d3.svg.axis())和一个线性比例,只是为了向你展示原理。您可以轻松地将其更改为时间范围。

鉴于此数据:

var data = [0, 10, 40, 45, 85, 100];

我们将在蜱之间绘制差异,即:10,30,5,40和15。

第一步是设置比例:

var scale = d3.scale.linear()
    .domain(d3.extent(data))
    .range([margin, w - margin]);

然后,在轴生成器中,我们设置刻度以匹配数据:

.tickValues(data)

我们用以下方法计算正确的数字:

.tickFormat(function(d,i){
    if(i>0){
        return data[i] - data[i-1];
    } else { return ""};
});

最后一步是将文本翻译到中间位置:

var ticks = d3.selectAll(".tick text").each(function(d, i) {
    d3.select(this).attr("transform", function() {
        if (i > 0) {
            return "translate(" + (-scale(data[i] - data[i - 1]) / 2 + margin/2) + ",0)";
        }
    })
})

查看演示:



var w = 500,
    h = 100;
var svg = d3.select("body")
    .append("svg")
    .attr("width", w)
    .attr("height", h);

var data = [0, 10, 40, 45, 85, 100];

var margin = 20;

var scale = d3.scale.linear()
    .domain(d3.extent(data))
    .range([margin, w - margin]);

var colors = d3.scale.category10();

var rects = svg.selectAll(".rects")
	.data(data)
	.enter()
	.append("rect");
	
rects.attr("y", 10)
	.attr("height", 35)
	.attr("fill", (d,i)=> colors(i))
	.attr("x", d=>scale(d))
	.attr("width", (d,i)=> {
		return scale(data[i+1] - data[i]) - margin
	});

var axis = d3.svg.axis()
    .scale(scale)
    .orient("bottom")
    .tickValues(data)
    .tickFormat(function(d, i) {
        if (i > 0) {
            return data[i] - data[i - 1];
        } else {
            return ""
        };
    });

var gX = svg.append("g")
    .attr("transform", "translate(0,50)")
    .attr("class", "axis")
    .call(axis);

var ticks = d3.selectAll(".tick text").each(function(d, i) {
    d3.select(this).attr("transform", function() {
        if (i > 0) {
            return "translate(" + (-scale(data[i] - data[i - 1]) / 2 + margin / 2) + ",0)";
        }
    })
})

.axis path,
.axis line {
    fill: none;
    stroke: black;
    shape-rendering: crispEdges;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;