我有两个y轴,时间作为数据。 我想在轴上点击刻度线时绘制一条线。 线路正在生成但无法正确定位线路。 这是我的代码。
//dataset
var data = [
{"inTime":"2013-04-24T00:00:00-05:00","outTime":"2013-04-24T00:00:00-05:00"},
{"inTime":"2013-04-24T00:00:00-05:00","outTime":"2013-04-24T00:00:00-05:00"},
{"inTime":"2013-04-24T00:00:00-05:00","outTime":"2013-04-24T00:00:00-05:00"},
{"inTime":"2013-04-24T00:00:00-05:00","outTime":"2013-04-24T00:00:00-05:00"},
{"inTime":"2013-04-24T00:00:00-05:00","outTime":"2013-04-24T00:00:00-05:00"},
{"inTime":"2013-04-24T00:00:00-05:00","outTime":"2013-04-24T00:00:00-05:00"},
{"inTime":"2013-04-24T00:00:00-05:00","outTime":"2013-04-24T00:00:00-05:00"},
{"inTime":"2013-04-24T00:00:00-05:00","outTime":"2013-04-24T00:00:00-05:00"},
];
var margin = {top: 40, right: 40, bottom: 40, left:40},
width = 600,
height = 500;
var padding = 100;
//Define Left Y axis
var y = d3.time.scale()
.domain([new Date(data[0].inTime), d3.time.day.offset(new Date(data[data.length - 1].inTime), 1)])
.rangeRound([0, width - margin.left - margin.right]);
//Define Right Y axis
var y1 = d3.time.scale()
.domain([new Date(data[1].inTime), d3.time.day.offset(new Date(data[data.length - 1].outTime), 1)])
.rangeRound([0, width - margin.left - margin.right]);
//Left Yaxis attributes
var yAxis = d3.svg.axis()
.scale(y)
.orient('left')
.tickFormat(d3.time.format('%m/%d %H:%M'))
.tickSize(8)
.tickPadding(8);
//Right Yaxis attributes
var yAxisRight = d3.svg.axis()
.scale(y1)
.orient('right')
.tickFormat(d3.time.format('%m/%d %H:%M'))
.tickSize(8)
.tickPadding(8);
//Create chart
var svg = d3.select('body').append('svg')
.attr('class', 'chart')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
//Add left Yaxis to group
svg.append('g')
.attr('class', 'y axis')
.attr('transform', 'translate(100, 5)')
.call(yAxis);
//Add right Yaxis to group
svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(400, 1)')
.call(yAxisRight);
var parse = d3.time.format('%m/%d %H:%M');
//Function to add a line between two ticks
function addLine(t1, t2){
var ticks = {};
console.log("print ", d3.selectAll('.tick text').each(function(d) {
ticks[d3.select(this).text()] = this;
}));
d3.selectAll('.tick text').each(function(d) {
ticks[d3.select(this).text()] = this;
});
console.log("ticks are",ticks);
console.log("ticks[t1] is",ticks[t1]);
console.log("t1 is",t1);
var pos1 = ticks[t1].getBoundingClientRect();
var pos2 = ticks[t2].getBoundingClientRect();
console.log("pos1 is",pos1);
console.log("pos2 is",pos2);
svg.append('line')
.attr('x1', pos1.top - pos1.width)
.attr('y1', pos1.top + 5)
.attr('x2', pos2.left - 5)
.attr('y2', pos2.top + 5)
.style('stroke','black');
}
//On click event for ticks
svg.selectAll(".y.axis .tick")
.on("click", function(d) {
var parse = d3.time.format('%m/%d %H:%M');
var d1=parse(d);
console.log("d1 is",d1);
svg.selectAll(".x.axis .tick")
.on("click", function(d){
var d2=parse(d);
console.log("d2 is : ",d2);
addLine(d1,d2);
console.log("inner d",d);
})
console.log(d);});
/* svg.selectAll(".x.axis .tick")
.on("click", function(d){
console.log("Right y axis d ",d);
}); */
var ticks = svg.selectAll(".tick");
ticks.each(function() { d3.select(this).append("circle").attr("r", 5); });
ticks.selectAll("line").remove();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
答案 0 :(得分:1)
基本上是因为你在绘制线之前进行平移,而不是从边界框中绘制线条时考虑这一点。
我创建了自己的方式来获得与你的点基本相同的点,除了在我的中我按ID选择刻度而不是像你一样通过列表。
如果你想看一下,这是我的小提琴:https://jsfiddle.net/reko91/p4n9omej/4/
我改变的主要部分是:
.attr('transform', 'translate(' + (-margin.left -15) + ', ' + (-margin.top-5) + ')');
这可以弥补您在创建svg
时的转换。