2016-09-03 6 views
2

Wie kann ich mit der D3 Version 4 den Zoom auf die x-Achse beschränken?Horizontaler Zoom mit D3 Version 4?

Beispiel mit uneingeschränktem Zoom:

var sideLength = 190; 
 
var data = [ 
 
    [0, 0], 
 
    [0.5, 0.8], 
 
    [1, 0.4] 
 
]; 
 
var svg = d3.select("body") 
 
    .append("svg") 
 
    .attr("width", sideLength) 
 
    .attr("height", sideLength); 
 
var yScale = d3.scaleLinear().range([sideLength, 0]); 
 
var xScale = d3.scaleLinear().range([0, sideLength]); 
 
var graphGroup = svg.append("g"); 
 
var onZoom = function() { 
 
    graphGroup.attr("transform", d3.event.transform); 
 
}; 
 
var zoomBehavior = d3.zoom().on("zoom", onZoom); 
 
var line = d3.line() 
 
    .x(function(d) { 
 
    return xScale(d[0]); 
 
    }) 
 
    .y(function(d) { 
 
    return yScale(d[1]); 
 
    }); 
 

 
svg.call(zoomBehavior); 
 
graphGroup.selectAll("path").remove(); 
 
graphGroup.append("path") 
 
    .datum(data) 
 
    .attr("class", "line") 
 
    .attr("d", line);
<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <meta charset="utf-8"> 
 
    <title>D3 Zoom</title> 
 
</head> 
 

 
<body> 
 
    <script src="http://d3js.org/d3.v4.min.js"></script> 
 
</body> 
 

 
</html>

Antwort

2

Ich weiß nicht, was Sie genau von „beschränkt Zoom nur x-Achse“ suchen, aber wenn Sie möchten, y-Achse bedeuten Um beim Zoomen unberührt zu bleiben (und damit Ihre Formen verzerrt werden) können Sie die Transformationsfunktion manuell erstellen.

d3.event.transform hat 3 Attribute x, y und k welche Koordinaten von Zoom-Punkt und Skala sind.

d3.event.transform.toString würden Sie eine Zeichenfolge wie folgt:

translate(x, y) scale(k) und wenn Sie mit Transformationen vertraut sind, Sie bereits wissen, wie Sie die gewünschte Umwandlung zu machen. Aber FYI zwei Teile der ursprünglichen Transformation sind:

translate(x, y): Der Grund, warum Sie Zoom fiel tritt bei Punkt Maus zeigt auf. Es verschiebt das Objekt tatsächlich. Wenn Sie also diesen Teil entfernen, wird die Leinwand um den Mittelpunkt herum skaliert.

scale(k) skaliert die Leinwand.

Der Trick ist, wenn Sie Y-Achse nicht skalieren möchten, können Sie zusätzliche Arg übergeben, um für Y-Achse zu skalieren.

Also, wenn Sie nur y-Achse wollen unberührt sein (nicht skaliert und nicht übersetzt) ​​Sie haben können:

var sideLength = 190; 
 
var data = [ 
 
    [0, 0], 
 
    [0.5, 0.8], 
 
    [1, 0.4] 
 
]; 
 
var svg = d3.select("body") 
 
    .append("svg") 
 
    .attr("width", sideLength) 
 
    .attr("height", sideLength); 
 
var yScale = d3.scaleLinear().range([sideLength, 0]); 
 
var xScale = d3.scaleLinear().range([0, sideLength]); 
 
var graphGroup = svg.append("g"); 
 
var onZoom = function() { 
 
var transform = d3.event.transform; 
 
    var transformString = 'translate(' + transform.x + ',' + '0) scale(' + transform.k + ',1)'; 
 
    graphGroup.attr("transform", transformString); 
 
}; 
 
var zoomBehavior = d3.zoom().on("zoom", onZoom); 
 
var line = d3.line() 
 
    .x(function(d) { 
 
    return xScale(d[0]); 
 
    }) 
 
    .y(function(d) { 
 
    return yScale(d[1]); 
 
    }); 
 

 
svg.call(zoomBehavior); 
 
graphGroup.selectAll("path").remove(); 
 
graphGroup.append("path") 
 
    .datum(data) 
 
    .attr("class", "line") 
 
    .attr("d", line);
<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <meta charset="utf-8"> 
 
    <title>D3 Zoom</title> 
 
</head> 
 

 
<body> 
 
    <script src="http://d3js.org/d3.v4.min.js"></script> 
 
</body> 
 

 
</html>

+0

Wissen Sie, wie Verzerrung auf dem graphGroup zu verhindern? Linien innerhalb sehen schlecht aus –

+0

@TomRoggero Was meinst du? Wenn Sie nicht sowohl über x als auch über y zoomen, ändert sich das Seitenverhältnis der Form. – Mehraban