我的数据中有间隙(在y轴上),所以即使我宁愿使用线性刻度,我也必须使用序数刻度 - 这样才能看到孔。
但是,我确实想要使用不同的刻度标记直观地显示数据不连续。这里的想法是检查next value - current value
是否为1,如果没有绘制不同的刻度线。
使用this example我使用this.parentNode.nextSibling
- 但是没有获得所需的值。
我该怎么做呢?
以下示例代码。我希望2,5和8的行显示在不同的刻度线中(比如stroke-dasharray: "10,2"
或者可能是不同的颜色)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ticks problem</title>
</head>
<body>
<svg width="500" height="300"></svg>
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script type="text/javascript">
var svg = d3.select("svg"),
margin = {top: 20, right: 0, bottom: 20, left: 0},
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 data = [5, 15, 7, 10, 4, 12, 14];
var yDomain = [1, 2, 4, 5, 8, 10, 11];
var yRange = Array(data.length+1).fill().map((d,i)=>(i+1)*35);
var yScale = d3.scaleOrdinal()
.domain(yDomain)
.range(yRange);
var yAxis = d3.axisRight(yScale)
.ticks(data.length+1)
.tickSize(width);
function customYAxis(g) {
g.call(yAxis);
g.attr("id", "y-axis");
g.select(".domain").remove();
//g.selectAll(".tick line").attr("stroke", "#777").attr("stroke-dasharray", "2,2");
g.selectAll(".tick line")
.attr("stroke", "#777")
.attr("stroke-dasharray", (d,i)=>{
//let n = d3.select(this.parentNode.nextSibling).datum(); // not working
//console.log(i + " " + d+" "+n);
// return "10,2" if n-d > 1
return "2,2"; // return some default for now
})
g.selectAll(".tick text").attr("x", 4).attr("dy", -4);
}
g.append('g').call(customYAxis);
</script>
</body>
</html>
答案 0 :(得分:2)
请记住,selection.attr()
会被提供三个参数:
传递当前数据( d ),当前索引( i )和当前组(节点),带< em> this 作为当前的DOM元素( nodes [i] )
您可以使用第三个参数来访问下一个元素的基准。由于i
是当前元素的索引,node[i+1]
将指向下一个元素。您可以轻松选择下一个元素并使用.datum()
来检索绑定的数据。
d3.select(nodes[i+1]).datum()
唯一剩下的就是使用安全措施来读取nodes
数组中的最后一个元素。
i < nodes.length - 1 && d3.select(nodes[i+1]).datum()
这可以直接用于您的.attr()
setter:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ticks problem</title>
</head>
<body>
<svg width="500" height="300"></svg>
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script type="text/javascript">
var svg = d3.select("svg"),
margin = {top: 20, right: 0, bottom: 20, left: 0},
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 data = [5, 15, 7, 10, 4, 12, 14];
var yDomain = [1, 2, 4, 5, 8, 10, 11];
var yRange = Array(data.length+1).fill().map((d,i)=>(i+1)*35);
var yScale = d3.scaleOrdinal()
.domain(yDomain)
.range(yRange);
var yAxis = d3.axisRight(yScale)
.ticks(data.length+1)
.tickSize(width);
function customYAxis(g) {
g.call(yAxis);
g.attr("id", "y-axis");
g.select(".domain").remove();
//g.selectAll(".tick line").attr("stroke", "#777").attr("stroke-dasharray", "2,2");
g.selectAll(".tick line")
.attr("stroke", "#777")
.attr("stroke-dasharray", (d, i, nodes) => {
return i < nodes.length - 1 && d3.select(nodes[i+1]).datum() - d > 1 ? "10,2" : "2,2";
})
g.selectAll(".tick text").attr("x", 4).attr("dy", -4);
}
svg.append('g').call(customYAxis);
</script>
</body>
</html>
&#13;