2016-01-15 103 views

回答

2

我剛剛破解這對增加另一個路徑Y軸:

// define how much space you'd like to create the axis "break" in 
var axisBreakSpace = 50; 

// Add the X Axis, with the space 
svg.append("g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + (height + axisBreakSpace) + ")") 
    .call(xAxis); 

// Add the Y Axis, normally 
var yG = svg.append("g") 
    .attr("class", "y axis") 
    .call(yAxis); 

// add the zigzags path 
yG.append("path") 
    .attr("d", function(){ 
    var numZags = 10, // number of zigzags 
     zagDist = (axisBreakSpace - 5)/numZags; // y distance on each zig or zag, -5 is a bit of space to finish it off 

    // build the path at 
    var curZig = height, 
     d = "M0," + curZig; 
    for (var i = 0; i < numZags; i++){ 
     curZig += zagDist; 
     d += (i % 2 === 0) ? " L10," + curZig : " L-10," + curZig; 
    } 

    // finish it off to the x-axis 
    d += " L0," + (height + axisBreakSpace); 
    return d; 
    }); 

完整的工作代碼示例:

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 
<style> 
 
    /* set the CSS */ 
 
    
 
    body { 
 
    font: 12px Arial; 
 
    } 
 
    
 
    path { 
 
    stroke: steelblue; 
 
    stroke-width: 2; 
 
    fill: none; 
 
    } 
 
    
 
    .axis path, 
 
    .axis line { 
 
    fill: none; 
 
    stroke: grey; 
 
    stroke-width: 1; 
 
    shape-rendering: crispEdges; 
 
    } 
 
</style> 
 

 
<body> 
 

 
    <!-- load the d3.js library --> 
 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
 

 
    <script> 
 
    // Set the dimensions of the canvas/graph 
 
    var margin = { 
 
     top: 30, 
 
     right: 20, 
 
     bottom: 100, 
 
     left: 50 
 
     }, 
 
     width = 600 - margin.left - margin.right, 
 
     height = 270 - margin.top - margin.bottom, 
 
     axisBreakSpace = 50; 
 

 
    // Set the ranges 
 
    var x = d3.scale.linear().range([0, width]) 
 
       .domain([0, 10]); 
 
    var y = d3.scale.linear().range([height, 0]) 
 
       .domain([200,1000]); 
 

 
    // Define the axes 
 
    var xAxis = d3.svg.axis().scale(x) 
 
     .orient("bottom") 
 

 
    var yAxis = d3.svg.axis().scale(y) 
 
     .orient("left"); 
 

 
    // Define the line 
 
    var line = d3.svg.line() 
 
     .x(function(d) { 
 
     return x(d.x); 
 
     }) 
 
     .y(function(d) { 
 
     return y(d.y); 
 
     }); 
 

 
    // Adds the svg canvas 
 
    var svg = d3.select("body") 
 
     .append("svg") 
 
     .attr("width", width + margin.left + margin.right) 
 
     .attr("height", height + margin.top + margin.bottom) 
 
     .append("g") 
 
     .attr("transform", 
 
     "translate(" + margin.left + "," + margin.top + ")"); 
 

 
    var data = d3.range(10).map(function(d){ 
 
     return { 
 
     x: d, 
 
     y: (Math.random() * 800) + 200 
 
     } 
 
    }); 
 

 
    // Add the valueline path. 
 
    svg.append("path") 
 
     .attr("class", "line") 
 
     .attr("d", line(data)); 
 

 
    // Add the X Axis 
 
    svg.append("g") 
 
     .attr("class", "x axis") 
 
     .attr("transform", "translate(0," + (height + axisBreakSpace) + ")") 
 
     .call(xAxis); 
 
     
 
    // Add the Y Axis 
 
    var yG = svg.append("g") 
 
     .attr("class", "y axis") 
 
     .call(yAxis); 
 
    
 
    yG.append("path") 
 
     .attr("d", function(){ 
 
     var numZags = 10, 
 
      zagDist = (axisBreakSpace - 5)/numZags; 
 

 
     var curZig = height, 
 
      d = "M0," + curZig; 
 
     for (var i = 0; i < numZags; i++){ 
 
      curZig += zagDist; 
 
      d += (i % 2 === 0) ? " L10," + curZig : " L-10," + curZig; 
 
     } 
 
     d += " L0," + (height + axisBreakSpace); 
 
     return d; 
 
     }); 
 

 
    
 
    </script> 
 
</body>

+0

這似乎在D3給出的限制下做到這一點是最簡單最簡單的方法,謝謝! –

+0

@Algorithm_NL,限制? 'd3'用13行代碼滿足您的要求。 :) – Mark

+0

哈哈,touché。真的愛D3,只是意味着這不是內置功能;-) –

1

我會創建一些數據並將其傳遞給D3庫。類似的東西:

var data = [{ 
x1: xAxisSTARTPOINTX, //start 
y1; xAxisSTARTPOINTY, 
x2: firstXPointOnZigZag, 
y2; firstYPointOnZigZag},{ 
. 
. 
. },{ 
x1: lastXPointOnZigZag, //end 
y1; lastYPointOnZigZag, 
x2: yAxisSTARTPOINTX, 
y2; yAxisSTARTPOINTY} 

}] 

你放在之間的值將是你可以組成或生成的曲折曲線上的點。

那麼這個傳遞給此:

d3.select(container).data(data).enter().append('path') 
.attr('x1', function(d){ return d.x1}) 
.attr('y1', function(d){ return d.y1}) 
.attr('x2', function(d){ return d.x2}) 
.attr('y2', function(d){ return d.y2}) 
.style('stroke','black'); 

您可以生成自己的,所以你可以通過改變改變你要多少「曲折」點「我」在for循環。

創建點的函數,類似於這樣:

function createPoints(xAxisStartPoint, yAxisStartPoint){ //pass two arrays 

     var xAxisStartX = xAxisStartPoint[0], //xAxisStartPointX 
     xAxisStartY = xAxisStartPoint[1], //xAxisStartPointY 
     yAxisStartX = yAxisStartPoint[0], //xAxisStartPointX 
     yAxisStartY = yAxisStartPoint[1]; //yAxisStartPointY 

    var difference = xAxisStartY-yAxisStartY; //gets the difference between xAxis and yAxis to make sure the points are equal distance apart. 

     var allPoints = []; //array to populate with points 
     var numberOfPoints = 4; //number of zigzags 
     var movement = 20; //movement left and right 

     for(var i=0;i<=numberOfPoints;i++){ 
      var thisPoint = []; 
       if(i===0){ //push xAxisStartPoint 
       thisPoint.push({ 
        x:xAxisStartX, 
        y:xAxisStartY 
       }) 
       } else if(i===4){ //push yAxisStartPoint 
       thisPoint.push({ 
        x:yAxisStartX, 
        y:yAxisStartY 
       }) 
       } else { 
        thisCalcPointX; 

        if(i%2 > 0){ //if i is odd move left 
         thisCalcPointX = xAxisStartX-movement; //move point to the left 
        } else { //if it's even move right 
         thisCalcPointX = xAxisStartX+movement; //move point to the right 
        } 
        thisCalcPointY = xAxisStartY + difference/i; //move point up from xAxis start point at equal distance between xAxis and yAxis 
        thisPoint.push({ 
        x: xAxisStartX, 
        y: thisCalcPointY 
       }) 


     } 
    allPoints.push(thisPoint); //push this point to array of points 


     } 


     return allPoints; //return the points 
     } 

//then pass this to create the path 

    var xAxisStart = [ xAxisStartX, xAxisStartY]; 
    var yAxisStart= [ yAxisStartX, yAxisStartY]; 
    var dataPoints = createPoints([xAxisStart, yAxisStart]) 

    d3.select(container).data(dataPoints).enter().append('path') 
     .attr('x1', function(d){ return d.x1}) 
     .attr('y1', function(d){ return d.y1}) 
     .attr('x2', function(d){ return d.x2}) 
     .attr('y2', function(d){ return d.y2}) 
     .style('stroke','black'); 

上面的代碼沒有經過測試,只是在飛行中完成的,可能需要打,但邏輯應該努力創建隨機點兩側在兩個軸之間。