在d3js中绘制两个y轴之间的直线

时间:2016-02-22 09:25:35

标签: d3.js

我有两个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>

1 个答案:

答案 0 :(得分:1)

基本上是因为你在绘制线之前进行平移,而不是从边界框中绘制线条时考虑这一点。

我创建了自己的方式来获得与你的点基本相同的点,除了在我的中我按ID选择刻度而不是像你一样通过列表。

如果你想看一下,这是我的小提琴:https://jsfiddle.net/reko91/p4n9omej/4/

我改变的主要部分是:

.attr('transform', 'translate(' + (-margin.left -15) + ', ' + (-margin.top-5) + ')');

这可以弥补您在创建svg时的转换。