2013-03-29 12 views
15

Oto mój kod do rysowania wykresu liniowego z możliwościami powiększania. Problem polega jednak na tym, że kiedy powiększam kursor nie pozostaje w tym samym punkcie. Chciałbym powiększyć tam, gdzie znajduje się kursor myszy (mam nadzieję, że jestem wystarczająco jasny).Powiększanie mapy w D3

Oto jsfiddle: http://jsfiddle.net/KSAbK/

width = 400 - margin.left - margin.right; 
height = 200 - margin.top - margin.bottom; 

var x = d3.time.scale() 
    .domain(d3.extent(data, function (d) { 
    return d.date; 
})) 
    .range([0, width]); 

var y = d3.scale.linear() 
    .domain(d3.extent(data, function (d) { 
    return d.value; 
})) 
    .range([height, 0]); 

var line = d3.svg.line() 
    .x(function (d) { 
    return x(d.date); 
}) 
    .y(function (d) { 
    return y(d.value); 
}); 

var zoom = d3.behavior.zoom() 
    .x(x) 
    .y(y) 
    .on("zoom", zoomed); 

svg = d3.select('#chart') 
    .append("svg:svg") 
    .attr('width', width + margin.left + margin.right) 
    .attr('height', height + margin.top + margin.bottom) 
    .call(zoom) 
    .append("svg:g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

var make_x_axis = function() { 
    return d3.svg.axis() 
     .scale(x) 
     .orient("bottom") 
     .ticks(5); 
}; 

var make_y_axis = function() { 
    return d3.svg.axis() 
     .scale(y) 
     .orient("left") 
     .ticks(5); 
}; 

var xAxis = make_x_axis(); 

svg.append("svg:g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0, " + height + ")") 
    .call(xAxis); 

var yAxis = make_y_axis(); 

svg.append("g") 
    .attr("class", "y axis") 
    .call(yAxis); 

svg.append("g") 
    .attr("class", "x grid") 
    .attr("transform", "translate(0," + height + ")") 
    .call(make_x_axis() 
    .tickSize(-height, 0, 0) 
    .tickFormat("")); 

svg.append("g") 
    .attr("class", "y grid") 
    .call(make_y_axis() 
    .tickSize(-width, 0, 0) 
    .tickFormat("")); 

var clip = svg.append("svg:clipPath") 
    .attr("id", "clip") 
    .append("svg:rect") 
    .attr("x", 0) 
    .attr("y", 0) 
    .attr("width", width) 
    .attr("height", height); 

var chartBody = svg.append("g") 
    .attr("clip-path", "url(#clip)"); 

chartBody.append("svg:path") 
    .datum(data) 
    .attr("class", "line") 
    .attr("d", line); 

function zoomed() { 
    console.log(d3.event.translate); 
    console.log(d3.event.scale); 
    svg.select(".x.axis").call(xAxis); 
    svg.select(".y.axis").call(yAxis); 
    svg.select(".x.grid") 
     .call(make_x_axis() 
     .tickSize(-height, 0, 0) 
     .tickFormat("")); 
    svg.select(".y.grid") 
     .call(make_y_axis() 
     .tickSize(-width, 0, 0) 
     .tickFormat("")); 
    svg.select(".line") 
     .attr("class", "line") 
     .attr("d", line); 
} 

Odpowiedz

16

Zdobione. Musiałem użyć elementu .call(zoom) na elemencie g, a także dodałem kolejny prostokąt, aby uzyskać powiększenie, gdy kursor myszy znajduje się w dowolnym miejscu obszaru wykresów.

svg = d3.select('#chart') 
    .append("svg:svg") 
    .attr('width', width + margin.left + margin.right) 
    .attr('height', height + margin.top + margin.bottom) 
    .append("svg:g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
    .call(zoom); 

svg.append("svg:rect") 
    .attr("width", width) 
    .attr("height", height) 
    .attr("class", "plot"); 
+0

Dzięki za dzielenie się, znajdując tę ​​pomocne. Pytanie: dlaczego dwie oddzielne zmienne mają tutaj zasadniczo ten sam kod (np. Var make_x_axis i xAxis)? Zauważam subtelną różnicę w dodawaniu funkcji anonowej + powrót, ale dlaczego to robisz? Dzięki – DeBraid

+0

@DeBraid Nie ma powodu, zapomniałem o refaktorze. Dzięki za uwagę, zredagowałem kod. – Strudel