我正在尝试用自己的代码创建一个平行坐标,以便我可以很好地学习d3.js。现在我陷入困境。我有两个轴,其中有一些数据
我希望用一条线连接数据。我尝试在轴上获取两个数据的位置,但它对我不起作用并且它变得复杂
jsfiddle链接在下面评论。请找到它
感谢您的帮助
答案 0 :(得分:0)
在这些刻度之间追加svg:line是要走的路,但困难的部分是在整个SVG文档中找到正确的位置。由于事物正在转换两次(一次用于轴g
,一次用于打勾g
),您有两个选项,通过在元素上使用d3.tranform来总结所有位置,或者在节点上使用类似getBoundingClientRect的内容。
在下面的代码中,我选择了后者。此快速函数将获取任意两个刻度的text
值并绘制一条线。请注意,这些文本值必须是唯一的:
function addLine(t1, t2){
var ticks = {};
d3.selectAll('.tick text').each(function(d) {
ticks[d3.select(this).text()] = this;
});
var pos1 = ticks[t1].getBoundingClientRect();
var pos2 = ticks[t2].getBoundingClientRect();
svg.append('line')
.attr('x1', pos1.left)
.attr('y1', pos1.top + 5)
.attr('x2', pos2.left - 5)
.attr('y2', pos2.top + 5)
.style('stroke','black');
}
addLine('a', 'ab');
addLine('a', 'bb');
完整的工作示例:
var w = 200;
var h = 400;
var padding = 100;
var x = ["a","b"];
var z = ["aa","ab","ba","bb"];
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
for(var i=1;i<3;i++){
var yScale = d3.scale.linear()
.domain([0, i === 1 ? x.length : z.length])
.range([h - padding, padding]);
//Define Y axis
var yAxis = d3.svg.axis()
.scale(yScale)
.ticks(i === 1 ? x.length : z.length)
.orient("left")
.tickSize(1)
.tickFormat(function(d){
return i === 1 ? x[d] : z[d];
})
// .style("text-anchor", "middle");
//Create SVG element
svg.append("g")
.attr("class", "axis" + i)
.attr("transform", "translate("+(i*padding)+",0)")
.call(yAxis)
.attr("fill","red");
}
function addLine(t1, t2){
var ticks = {};
d3.selectAll('.tick text').each(function(d) {
ticks[d3.select(this).text()] = this;
});
var pos1 = ticks[t1].getBoundingClientRect();
var pos2 = ticks[t2].getBoundingClientRect();
svg.append('line')
.attr('x1', pos1.left)
.attr('y1', pos1.top + 5)
.attr('x2', pos2.left - 5)
.attr('y2', pos2.top + 5)
.style('stroke','black');
}
addLine('a', 'ab');
addLine('a', 'bb');
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;