2017-08-24 75 views
1

小问题难以确定。我正在使用example使用d3 v4创建线图。我正在使用d3.line()而不是d3.area()。同时在线峰点上绘制圆圈。事情工作正常。D3 V4如何根据放大线图移动点?

问题是与绘制的圆形。当我放大图形时,他们没有移动到正确的位置。 下面是完整的代码:

.area { 
 
    fill: none; 
 
    stroke: #a2dced; 
 
    stroke-width: 2; 
 
    clip-path: url(#clip); 
 
} 
 

 
.zoom { 
 
    cursor: move; 
 
    fill: none; 
 
    pointer-events: all; 
 
} 
 

 
rect.selection 
 
{ 
 
\t fill:green; 
 
}
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<svg width="960" height="500"></svg> 
 
<script> 
 
var data = [{date: "10:30:00", price: 36000}, 
 
\t \t \t {date: "11:00:20", price: 40000}, 
 
\t \t \t {date: "12:00:00", price: 38000}, 
 
\t \t \t {date: "14:20:00", price: 50400}]; 
 
\t \t \t 
 
var svg = d3.select("svg"), 
 
    margin = {top: 20, right: 20, bottom: 110, left: 40}, 
 
    margin2 = {top: 430, right: 20, bottom: 30, left: 40}, 
 
    width = +svg.attr("width") - margin.left - margin.right, 
 
    height = +svg.attr("height") - margin.top - margin.bottom, 
 
    height2 = +svg.attr("height") - margin2.top - margin2.bottom; 
 

 
var parseDate = d3.timeParse("%H:%M:%S");//"%b %Y"); 
 

 
var x = d3.scaleTime().range([0, width]), 
 
    x2 = d3.scaleTime().range([0, width]), 
 
    y = d3.scaleLinear().range([height, 0]), 
 
    y2 = d3.scaleLinear().range([height2, 0]); 
 

 
var xAxis = d3.axisBottom(x), 
 
    xAxis2 = d3.axisBottom(x2), 
 
    yAxis = d3.axisLeft(y); 
 

 
var brush = d3.brushX() 
 
    .extent([[0, 0], [width, height2]]) 
 
    .on("brush end", brushed); 
 

 
var zoom = d3.zoom() 
 
    .scaleExtent([1, Infinity]) 
 
    .translateExtent([[0, 0], [width, height]]) 
 
    .extent([[0, 0], [width, height]]) 
 
    .on("zoom", zoomed); 
 

 
var area = d3.line() 
 
\t //.curve(d3.curveMonotoneX) 
 
\t .x(function (d) { 
 
\t \t return x(d.date); 
 
\t }) 
 
\t .y(function (d) { 
 
\t \t return y(d.price); 
 
\t }); 
 
\t \t \t \t 
 
var area2 = d3.line() 
 
\t .curve(d3.curveMonotoneX) 
 
\t .x(function (d) { 
 
\t \t return x2(d.date); 
 
\t }) 
 
\t .y(function (d) { 
 
\t \t return y2(d.price); 
 
\t }); 
 
\t 
 

 
svg.append("defs").append("clipPath") 
 
    .attr("id", "clip") 
 
    .append("rect") 
 
    .attr("width", width) 
 
    .attr("height", height); 
 

 
var focus = svg.append("g") 
 
    .attr("class", "focus") 
 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
var context = svg.append("g") 
 
    .attr("class", "context") 
 
    .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")"); 
 

 
    function update(){ \t 
 
\t 
 
\t for(var k in data) 
 
\t \t { 
 
\t \t \t type(data[k]); 
 
\t \t } \t 
 
\t 
 
\t x.domain(d3.extent(data, function(d) { return d.date; })); 
 
\t y.domain([0, d3.max(data, function(d) { return d.price; })]); 
 
\t x2.domain(x.domain()); 
 
\t y2.domain(y.domain()); 
 

 

 
     focus.append("path") 
 
\t \t .datum(data) 
 
\t \t .attr("class", "area") 
 
\t \t .attr("d", area); 
 

 
\t focus.append("g") 
 
\t \t .attr("class", "axis axis--x") 
 
\t \t .attr("transform", "translate(0," + height + ")") 
 
\t \t .call(xAxis); 
 

 
\t focus.append("g") 
 
\t \t .attr("class", "axis axis--y") 
 
\t \t .call(yAxis); 
 

 
\t focus.selectAll("circle")          
 
\t \t .data(data)           
 
\t \t .enter().append("circle") 
 
\t \t .attr("class","circle") \t 
 
\t \t .attr("r", 5) 
 
\t \t .style("fill", 'orange') 
 
\t \t .style("stroke", 'red') 
 
\t \t .style("stroke-width", "2") 
 
\t \t .attr("cx", function(d) { return x(d.date) }) 
 
\t \t .attr("cy", function(d) { return y(d.price); }); 
 
\t 
 
\t context.append("path") 
 
\t \t .datum(data) 
 
\t \t .attr("class", "area") 
 
\t \t .attr("d", area2); 
 

 
\t context.append("g") 
 
\t \t .attr("class", "axis axis--x") 
 
\t \t .attr("transform", "translate(0," + height2 + ")") 
 
\t \t .call(xAxis2); 
 
\t 
 
\t context.selectAll("circle")          
 
\t \t .data(data)           
 
\t \t .enter().append("circle") 
 
\t \t .attr("class","circle") \t 
 
\t \t .attr("r", 1) 
 
\t \t .style("fill", 'blue') 
 
\t \t .style("stroke", 'red') 
 
\t \t .style("stroke-width", "2") 
 
\t \t .attr("cx", function(d) { return x(d.date) }) 
 
\t \t .attr("cy", function(d) { return y(d.price); }); \t 
 

 
\t context.append("g") 
 
\t \t .attr("class", "brush") 
 
\t \t .call(brush) 
 
\t \t .call(brush.move, x.range()); 
 

 
\t svg.append("rect") 
 
\t \t .attr("class", "zoom") 
 
\t \t .attr("width", width) 
 
\t \t .attr("height", height) 
 
\t \t .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
 
\t \t .call(zoom); 
 
} 
 

 

 

 
function brushed() { 
 
    if (d3.event.sourceEvent && d3.event.sourceEvent.type === "zoom") return; // ignore brush-by-zoom 
 
    var s = d3.event.selection || x2.range(); 
 
    x.domain(s.map(x2.invert, x2)); 
 
    focus.select(".area").attr("d", area); 
 
    
 
    focus.selectAll('.circle').attr("transform", function(d) { 
 
\t return "translate(" + x(d.date) + "," + y(d.price) + ")"; 
 
    }); 
 
    
 
    
 

 
    focus.select(".axis--x").call(xAxis); 
 
    svg.select(".zoom").call(zoom.transform, d3.zoomIdentity 
 
     .scale(width/(s[1] - s[0])) 
 
     .translate(-s[0], 0)); 
 
} 
 

 
function zoomed() { 
 
    if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush 
 
    var t = d3.event.transform; 
 
    x.domain(t.rescaleX(x2).domain()); 
 
    focus.select(".area").attr("d", area); 
 
    
 
    focus.selectAll('.circle').attr("transform", function(d) { 
 
\t return "translate(" + x(d.date) + "," + y(d.price) + ")"; 
 
    }); 
 
\t \t 
 
    focus.select(".axis--x").call(xAxis); 
 
    context.select(".brush").call(brush.move, x.range().map(t.invertX, t)); 
 
    context.selectAll('.circle').attr("transform", function(d) { 
 
\t return "translate(" + x2(d.date) + "," + y2(d.price) + ")"; 
 
    }); 
 
} 
 

 
function type(d) { 
 
    d.date = parseDate(d.date); 
 
    d.price = +d.price; 
 
    return d; 
 
} 
 
update(); 
 
</script>

JSFiddle链接。

回答

0

我,改成cxcy,更新您jsfiddle更换所有transform属性如:

focus.selectAll('.circle').attr("transform", function(d) { 
    return "translate(" + x(d.date) + "," + y(d.price) + ")"; 
    }); 

focus.selectAll('.circle') 
     .attr("cx", function(d) { return x(d.date) }) 
     .attr("cy", function(d) { return y(d.price); }); 

否则,将翻译e与您的其他坐标,这可能会导致难以找到问题

+0

感谢Hugues先生的解决方案,但它没有完成。 'context'即使应用'翻译'后也不会移动 – Raghu

+0

好吧,我很抱歉! 'cx''cy'应该来自X2和Y2。现在它工作正常。再次感谢! – Raghu