2016-08-01 35 views
5

Wie kann man in D3 Version 4 separate Zoomskalen für x- und y-Achse bereitstellen?Anisotropes Zoomen in d3 Version 4

This example by Patrick Brockman gab eine Methode, die wunderbar unter v3 funktionierte, die das Zoomen auf Skalierungsfaktorobjekte ermöglichte. Der entsprechende Code:

xyzoom = d3.behavior.zoom() 
    .x(xscale) 
    .y(yscale) 
    .on("zoom", zoomable ? draw : null); 
    xzoom = d3.behavior.zoom() 
    .x(xscale) 
    .on("zoom", zoomable ? draw : null); 
    yzoom = d3.behavior.zoom() 
    .y(yscale) 
    .on("zoom", zoomable ? draw : null); 

Hinweis, dass es zwei Skalierungs Objekte, ein für jede Achse, und sie sind sowohl von der Achse Markierung gebunden/Ticks Bereich und die Haupthandlung, so dass die Schwenk-/Zoom-Aktivitäten sind kumulativ über alle drei Bereiche.

Im neuen Paradigma gibt es ein Zoom-Transform-Objekt, das mit Seitenelementen verknüpft ist, in denen das Zoomen stattfindet, das einen einzigen Skalierungsfaktor und zweidimensionalen Offset hat. Die Unterstützung für das Beeinflussen von Skalierungsobjekten transformiert die Transformation, ohne sie direkt zu aktualisieren. Das Teilen einer Zoom-Transformation zwischen allen drei Bereichen würde insgesamt nur einen Skalierungsfaktor ergeben (ganz zu schweigen von dem Problem, dass das Zoomen in einer Achsenbeschriftung/einem Häkchen-Bereich immer noch die andere Achse beeinflusst) und das Erzielen einer eigenen Zoom-Transformation eine schreckliche Problem mit der Reihenfolge der Anwendung (Transformationsmultiplikation ist NICHT kommutativ).

Es scheint nicht einmal eine einfache Möglichkeit zu sein, die Transformation für einzelne Schritte zu erhalten und sie selbst zu kombinieren (das Zurücksetzen der Zoom-Transformation auf Identität löst alle die gleichen Ereignisse aus wie Benutzeraktionen).

Wie kann man in Version 4 einen anisotropen Zoom (verschiedene Dehnungsfaktoren in verschiedenen Richtungen) erreichen?

Hier ist, was ich bisher, was völlig falsch ist (es sammelt sich die Wirkung eines Zoom-Transformation, die sich von Zoom Ereignisse kumulativ):

function zoom_update() { 
    svg.select('rect.zoom.x.box').call(d3.zoom().on('zoom', function() { 
       xscale = d3.event.transform.rescaleX(xscale); 
       update(); 
     })); 
    svg.select('rect.zoom.y.box').call(d3.zoom().on('zoom', function() { 
       yscale = d3.event.transform.rescaleY(yscale); 
       update(); 
     })); 
    svg.select('rect.zoom.xy.box').call(d3.zoom().on('zoom', function() { 
       xscale = d3.event.transform.rescaleX(xscale); 
       yscale = d3.event.transform.rescaleY(yscale); 
       update(); 
     })); 

Ist es notwendig, über die zoom Modul zu überspringen und Mausereignisse direkt verarbeiten?

Antwort

0

Werfen Sie einen Blick auf diese example

Für Ihren Fall würde ich so etwas wie

// define the zoom 
d3.zoom().on('zoom', function() { 
    zoom_update(); 
}); 

function zoom_update() { 
    // re-scale 
    svg.select('rect.zoom.x.box') 
     .call(xAxis.scale(d3.event.transform.rescaleX(x))); 
    svg.select('rect.zoom.y.box') 
     .call(yAxis.scale(d3.event.transform.rescaleY(y))); 

    svg.select('rect.zoom.xy.box') 
     .call(xAxis.scale(d3.event.transform.rescaleX(x))); 
    svg.select('rect.zoom.xy.box') 
     .call(yAxis.scale(d3.event.transform.rescaleY(y))); 

    update(); 
} 
vorschlagen