2016-07-30 78 views
0

我嘗試更新http://bl.ocks.org/d3noob/6eb506b129f585ce5c8a並添加塗刷到它(線圖下塗刷顯示),以使它看起來像https://www.google.com.hk/#q=s%26p+500D3刷牙和鼠標移動並存

加入編碼,第一個鏈接:

var brush = d3.svg.brush() 
    .x(x) 
    .on("brush", brushmove) 
    .on("brushend", brushend); 

svg.append("g") 
    .attr("class", "brush") 
    .call(brush) 
    .selectAll('rect') 
    .attr('height', height); 

function brushmove() { 
    var extent = brush.extent(); 
} 

function brushend() { 
x.domain(brush.extent()) 
console.log(brush.extent()); 
} 

問題是,一旦我添加刷牙,有一個背景形成在圖形後面,我不能執行鼠標事件(鼠標移動)了。

有沒有辦法解決它,使其看起來像谷歌? 1)刷牙和鼠標事件共存 2)曲線

VAR CSV下塗刷面積= date,close1, close2 26-Mar-12,606.98,58.13 27-Mar-12,614.48,53.98 28-Mar-12,617.62,67.00 29-Mar-12,609.86,89.70 30-Mar-12,599.55,99.00 2-Apr-12,618.63,130.28 3-Apr-12,629.32,166.70 4-Apr-12,624.31,234.98 5-Apr-12,633.68,345.44 9-Apr-12,636.23,443.34 10-Apr-12,628.44,543.70 11-Apr-12,626.20,580.13 12-Apr-12,622.77,605.23 13-Apr-12,605.23,626.20 16-Apr-12,580.13,628.44 17-Apr-12,543.70,636.23 18-Apr-12,443.34,633.68 19-Apr-12,345.44,624.31 20-Apr-12,234.98,629.32 23-Apr-12,166.70,618.63 24-Apr-12,130.28,599.55 25-Apr-12,99.00,609.86 26-Apr-12,89.70,617.62 27-Apr-12,67.00,614.48 30-Apr-12,53.98,606.98 1-May-12,58.13,503.15

回答

1

兩個鏈接到的例子和brush對劇情的頂部添加rect捕捉鼠標事件。使它們共存的關鍵是添加畫筆(並允許它創建它的矩形),然後使用該矩形添加工具提示事件。這樣你只用一個點活動結束RECT:

// add a g for the brush 
var context = svg.append("g"); 

// add the brush 
context.call(brush); 

// grab the brush's rect and add the tooltip events 
context.select(".background") 
    .on("mouseover", function() { 
    focus.style("display", null); 
    }) 
    .on("mouseout", function() { 
    focus.style("display", "none"); 
    }) 
    .on("mousemove", mousemove); 

全碼:

<!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; 
 
    } 
 
    
 
    .extent { 
 
    stroke: #fff; 
 
    fill-opacity: .125; 
 
    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: 30, 
 
     left: 50 
 
     }, 
 
     width = 600 - margin.left - margin.right, 
 
     height = 270 - margin.top - margin.bottom; 
 

 
    // Parse the date/time 
 
    var parseDate = d3.time.format("%d-%b-%y").parse, 
 
     formatDate = d3.time.format("%d-%b"), 
 
     bisectDate = d3.bisector(function(d) { 
 
     return d.date; 
 
     }).left; 
 

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

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

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

 
    // Define the line 
 
    var valueline = d3.svg.line() 
 
     .x(function(d) { 
 
     return x(d.date); 
 
     }) 
 
     .y(function(d) { 
 
     return y(d.close); 
 
     }); 
 
     
 
    var area = d3.svg.area() 
 
     .x(function(d) { 
 
      return x(d.date); 
 
     }) 
 
     .y0(height) 
 
     .y1(function(d) { 
 
     return y(d.close); 
 
     }); 
 

 
    // 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 defs = svg.append("defs"); 
 

 
    var areaClip = defs.append("clipPath") 
 
     .attr("id", "areaClip") 
 
     .append("rect") 
 
     .attr("x", width) 
 
     .attr("y", 0) 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
    var lineSvg = svg.append("g"); 
 

 
    var focus = svg.append("g") 
 
     .style("display", "none"); 
 
     
 
    var brush = d3.svg.brush() 
 
     .x(x) 
 
     .on("brush", function() { 
 
     var s = brush.extent(), 
 
      x1 = x(s[0]), 
 
      x2 = x(s[1]); 
 
      
 
     areaClip.attr('x', x1); 
 
     areaClip.attr('width', x2 - x1); 
 
     }) 
 

 
    var csv = `date,close 
 
26-Mar-12,606.98 
 
27-Mar-12,614.48 
 
28-Mar-12,617.62 
 
29-Mar-12,609.86 
 
30-Mar-12,599.55 
 
2-Apr-12,618.63 
 
3-Apr-12,629.32 
 
4-Apr-12,624.31 
 
5-Apr-12,633.68 
 
9-Apr-12,636.23 
 
10-Apr-12,628.44 
 
11-Apr-12,626.20 
 
12-Apr-12,622.77 
 
13-Apr-12,605.23 
 
16-Apr-12,580.13 
 
17-Apr-12,543.70 
 
18-Apr-12,443.34 
 
19-Apr-12,345.44 
 
20-Apr-12,234.98 
 
23-Apr-12,166.70 
 
24-Apr-12,130.28 
 
25-Apr-12,99.00 
 
26-Apr-12,89.70 
 
27-Apr-12,67.00 
 
30-Apr-12,53.98 
 
1-May-12,58.13`; 
 

 
    var data = d3.csv.parse(csv); 
 

 
    data.forEach(function(d) { 
 
     d.date = parseDate(d.date); 
 
     d.close = +d.close; 
 
    }); 
 

 
    // Scale the range of the data 
 
    x.domain(d3.extent(data, function(d) { 
 
     return d.date; 
 
    })); 
 
    y.domain([0, d3.max(data, function(d) { 
 
     return d.close+20; 
 
    })]); 
 

 
    // Add the valueline path. 
 
    lineSvg.append("path") 
 
     .attr("class", "line") 
 
     .attr("d", valueline(data)); 
 
     
 
    lineSvg.append("path") 
 
     .attr("d", area(data)) 
 
     .style("fill", "steelblue") 
 
     .style("stroke", "none") 
 
     .style("opacity", "0.5") 
 
     .attr("clip-path", "url(#areaClip)") 
 

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

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

 
    // append the x line 
 
    focus.append("line") 
 
     .attr("class", "x") 
 
     .style("stroke", "blue") 
 
     .style("stroke-dasharray", "3,3") 
 
     .style("opacity", 0.5) 
 
     .attr("y1", 0) 
 
     .attr("y2", height); 
 

 
    // append the y line 
 
    focus.append("line") 
 
     .attr("class", "y") 
 
     .style("stroke", "blue") 
 
     .style("stroke-dasharray", "3,3") 
 
     .style("opacity", 0.5) 
 
     .attr("x1", width) 
 
     .attr("x2", width); 
 

 
    // append the circle at the intersection 
 
    focus.append("circle") 
 
     .attr("class", "y") 
 
     .style("fill", "none") 
 
     .style("stroke", "blue") 
 
     .attr("r", 4); 
 

 
    // place the value at the intersection 
 
    focus.append("text") 
 
     .attr("class", "y1") 
 
     .style("stroke", "white") 
 
     .style("stroke-width", "3.5px") 
 
     .style("opacity", 0.8) 
 
     .attr("dx", 8) 
 
     .attr("dy", "-.3em"); 
 
    focus.append("text") 
 
     .attr("class", "y2") 
 
     .attr("dx", 8) 
 
     .attr("dy", "-.3em"); 
 

 
    // place the date at the intersection 
 
    focus.append("text") 
 
     .attr("class", "y3") 
 
     .style("stroke", "white") 
 
     .style("stroke-width", "3.5px") 
 
     .style("opacity", 0.8) 
 
     .attr("dx", 8) 
 
     .attr("dy", "1em"); 
 
    focus.append("text") 
 
     .attr("class", "y4") 
 
     .attr("dx", 8) 
 
     .attr("dy", "1em"); 
 

 
    // append the rectangle to capture mouse 
 
    var context = svg.append("g"); 
 
    
 
    context.call(brush); 
 
    
 
    context.selectAll(".resize").append("path") 
 
     .attr("d", "M0,2V" + (height - 2)) 
 
     .style("stroke", "black") 
 
    
 
    context.select(".extent") 
 
     .attr("height", height - 2) 
 
     .attr("fill", "none"); 
 
    
 
    context.select(".background") 
 
     .attr("height", height) 
 
     .on("mouseover.tooltip", function() { 
 
     focus.style("display", null); 
 
     }) 
 
     .on("mouseout.tooltip", function() { 
 
     focus.style("display", "none"); 
 
     }) 
 
     .on("mousemove.tooltip", mousemove); 
 

 
    function mousemove() { 
 
     var x0 = x.invert(d3.mouse(this)[0]), 
 
     i = bisectDate(data, x0, 1), 
 
     d0 = data[i - 1], 
 
     d1 = data[i], 
 
     d = x0 - d0.date > d1.date - x0 ? d1 : d0; 
 

 
     focus.select("circle.y") 
 
     .attr("transform", 
 
      "translate(" + x(d.date) + "," + 
 
      y(d.close) + ")"); 
 

 
     focus.select("text.y1") 
 
     .attr("transform", 
 
      "translate(" + x(d.date) + "," + 
 
      y(d.close) + ")") 
 
     .text(d.close); 
 

 
     focus.select("text.y2") 
 
     .attr("transform", 
 
      "translate(" + x(d.date) + "," + 
 
      y(d.close) + ")") 
 
     .text(d.close); 
 

 
     focus.select("text.y3") 
 
     .attr("transform", 
 
      "translate(" + x(d.date) + "," + 
 
      y(d.close) + ")") 
 
     .text(formatDate(d.date)); 
 

 
     focus.select("text.y4") 
 
     .attr("transform", 
 
      "translate(" + x(d.date) + "," + 
 
      y(d.close) + ")") 
 
     .text(formatDate(d.date)); 
 

 
     focus.select(".x") 
 
     .attr("transform", 
 
      "translate(" + x(d.date) + "," + 
 
      y(d.close) + ")") 
 
     .attr("y2", height - y(d.close)); 
 

 
     focus.select(".y") 
 
     .attr("transform", 
 
      "translate(" + width * -1 + "," + 
 
      y(d.close) + ")") 
 
     .attr("x2", width + width); 
 
    } 
 
    
 
    </script> 
 
</body>

+0

謝謝! 你能幫我解決一個問題嗎? 我想讓1)只在曲線下方的畫筆顯示區域(就像谷歌的例子和2)在畫筆的最後有一個像東西一樣的杆子。 不知道如何完成... –

+0

@MINKYUYUN,這實際上很棘手。請參閱上面的代碼片段的編輯。 – Mark

+0

我試圖添加另一條線,就像http://bl.ocks.org/davidshinn/7917466 我試着通過添加另一個svg.line和'路徑'行。 我想我必須映射它......? 1)我怎麼能使用我的問題上的數據呢? 2)目前,刷牙可以從任何座標開始到任何座標。當我console.log(brush.extent()),我得到的時間取決於我擴展畫筆多少。是否有可能讓刷子每天都擴展(僅從圓形到圓形?),就像在谷歌中一樣? 我非常感謝 –