Angenommen, ich habe ein Histogrammskript, das eine 960 500 svg-Grafik erstellt. Wie kann ich darauf reagieren, um die Größe der Grafikbreiten und -höhen dynamisch zu ändern?
<script>
var n = 10000, // number of trials
m = 10, // number of random variables
data = [];
// Generate an Irwin-Hall distribution.
for (var i = 0; i < n; i++) {
for (var s = 0, j = 0; j < m; j++) {
s += Math.random();
}
data.push(s);
}
var histogram = d3.layout.histogram()
(data);
var width = 960,
height = 500;
var x = d3.scale.ordinal()
.domain(histogram.map(function(d) { return d.x; }))
.rangeRoundBands([0, width]);
var y = d3.scale.linear()
.domain([0, d3.max(histogram.map(function(d) { return d.y; }))])
.range([0, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.selectAll("rect")
.data(histogram)
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("x", function(d) { return x(d.x); })
.attr("y", function(d) { return height - y(d.y); })
.attr("height", function(d) { return y(d.y); });
svg.append("line")
.attr("x1", 0)
.attr("x2", width)
.attr("y1", height)
.attr("y2", height);
</script>
Das vollständige Beispiel für das Histogramm lautet: https://gist.github.com/993912
javascript
responsive-design
d3.js
Matt Alcock
quelle
quelle
Antworten:
Es gibt einen anderen Weg , dies zu tun, erfordert nicht die Grafik neu gezeichnet, und es beinhaltet die Modifizierung viewBox und preserveAspectRatio Attribute auf dem
<svg>
Element:Update 24.11.15 : Die meisten modernen Browser können das Seitenverhältnis von SVG-Elementen aus dem ableiten
viewBox
, sodass Sie die Größe des Diagramms möglicherweise nicht auf dem neuesten Stand halten müssen. Wenn Sie ältere Browser unterstützen müssen, können Sie die Größe Ihres Elements ändern, wenn die Größe des Fensters wie folgt geändert wird:Und der SVG-Inhalt wird automatisch skaliert. Ein funktionierendes Beispiel hierfür (mit einigen Änderungen) finden Sie hier : Ändern Sie einfach die Größe des Fensters oder des unteren rechten Bereichs, um zu sehen, wie es reagiert.
quelle
onload
Funktionsaufruf. Wenn die SVG-Breite und -Höhe im tatsächlichen HTML-Code festgelegt sind und Sie die oben beschriebene Technik verwenden, ist das Bild nicht skalierbar.Suchen Sie nach "Responsive SVG". Es ist ziemlich einfach, eine SVG reaktionsfähig zu machen, und Sie müssen sich keine Gedanken mehr über Größen machen.
So habe ich es gemacht:
Der CSS-Code:
Weitere Infos / Tutorials:
http://demosthenes.info/blog/744/Make-SVG-Responsive
http://soqr.fr/testsvg/embed-svg-liquid-layout-responsive-web-design.php
quelle
Ich habe einen kleinen Kern zusammengestellt, um dies zu lösen.
Das allgemeine Lösungsmuster lautet wie folgt:
Ich habe auch das minimierte d3.js-Skript für die Geschwindigkeit hinzugefügt. Das Wesentliche ist hier: https://gist.github.com/2414111
jquery reference back code:
Entprellungscode:
Genießen!
quelle
Ohne ViewBox zu verwenden
Hier ist ein Beispiel für eine Lösung, die nicht auf der Verwendung von a basiert
viewBox
:Der Schlüssel ist , die im Aktualisierungsbereich der Skalen die zum Platzieren von Daten verwendet werden.
Berechnen Sie zunächst Ihr ursprüngliches Seitenverhältnis:
Aktualisieren Sie dann bei jeder Größenänderung das
range
vonx
undy
:Beachten Sie, dass die Höhe auf der Breite und dem Seitenverhältnis basiert, damit Ihre ursprünglichen Proportionen erhalten bleiben.
Zum Schluss "zeichnen" Sie das Diagramm neu - aktualisieren Sie alle Attribute, die entweder von der
x
oder dery
Skala abhängen :Beachten Sie, dass Sie bei der Größenänderung von die
rects
Obergrenze vonrange
von verwenden könneny
, anstatt die Höhe explizit zu verwenden:Code-Snippet anzeigen
quelle
Wenn Sie d3.js bis c3.js verwenden, ist die Lösung des Problems der Reaktionsfähigkeit recht einfach:
wo der generierte HTML aussieht:
quelle
Shawn Allens Antwort war großartig. Möglicherweise möchten Sie dies jedoch nicht jedes Mal tun. Wenn Sie es auf vida.io hosten , reagieren Sie automatisch auf Ihre SVG-Visualisierung.
Mit diesem einfachen Einbettungscode können Sie auf iframe reagieren:
http://jsfiddle.net/dnprock/npxp3v9d/1/
Disclosure: Ich habe dieses Feature bei bauen vida.io .
quelle
Wenn Sie einen d3-Wrapper wie plottable.js verwenden , beachten Sie, dass die einfachste Lösung darin besteht , einen Ereignis-Listener hinzuzufügen und dann eine Redraw- Funktion aufzurufen (
redraw
in plottable.js). Im Fall von plottable.js funktioniert dies hervorragend (dieser Ansatz ist schlecht dokumentiert):quelle
Falls die Leute diese Frage immer noch besuchen - hier ist, was für mich funktioniert hat:
Fügen Sie den Iframe in ein Div ein und verwenden Sie CSS, um diesem Div einen Abstand von beispielsweise 40% hinzuzufügen (der Prozentsatz hängt vom gewünschten Seitenverhältnis ab). Stellen Sie dann sowohl die Breite als auch die Höhe des Iframes selbst auf 100% ein.
Stellen Sie im HTML-Dokument mit dem Diagramm, das in den Iframe geladen werden soll, die Breite auf die Breite des Divs ein, an das das SVG angehängt wird (oder auf die Breite des Körpers), und legen Sie das Seitenverhältnis Höhe zu Breite * fest.
Schreiben Sie eine Funktion, mit der der Iframe-Inhalt beim Ändern der Fenstergröße neu geladen wird, um die Größe des Diagramms anzupassen, wenn Benutzer ihr Telefon drehen.
Beispiel hier auf meiner Website: http://dirkmjk.nl/de/2016/05/embedding-d3js-charts-responsive-website
UPDATE 30. Dezember 2016
Der oben beschriebene Ansatz hat einige Nachteile, insbesondere, dass die Höhe keine Titel und Beschriftungen berücksichtigt, die nicht Teil des von D3 erstellten SVG sind. Ich bin seitdem auf einen meiner Meinung nach besseren Ansatz gestoßen:
Beispiel hier auf meiner Website: http://dirkmjk.nl/de/2016/12/embedding-d3js-charts-responsive-website-better-solution
quelle
Eines der Grundprinzipien des D3-Daten-Joins ist, dass er idempotent ist. Mit anderen Worten, wenn Sie wiederholt eine Datenverknüpfung mit denselben Daten auswerten, ist die gerenderte Ausgabe dieselbe. Solange Sie Ihr Diagramm korrekt rendern und dabei Ihre Auswahl zum Eingeben, Aktualisieren und Beenden beachten - alles, was Sie tun müssen, wenn sich die Größe ändert, ist, das Diagramm in seiner Gesamtheit neu zu rendern.
Es gibt noch ein paar andere Dinge, die Sie tun sollten. Eine davon ist, den Handler für die Größenänderung des Fensters zu entprellen, um ihn zu drosseln. Anstatt Breiten / Höhen hart zu codieren, sollte dies auch durch Messen des enthaltenen Elements erreicht werden.
Als Alternative wird hier Ihr Diagramm mit d3fc gerendert. Hierbei handelt es sich um eine Reihe von D3-Komponenten, die Datenverknüpfungen korrekt verarbeiten. Es hat auch ein kartesisches Diagramm, das das Element misst, wodurch es einfach ist, "reaktionsfähige" Diagramme zu erstellen:
Sie können es in Aktion in diesem Codepen sehen:
https://codepen.io/ColinEberhardt/pen/dOBvOy
Hier können Sie die Fenstergröße ändern und überprüfen, ob das Diagramm korrekt neu gerendert wurde.
Bitte beachten Sie, dass ich als vollständige Offenlegung einer der Betreuer von d3fc bin.
quelle
Ich würde Größenänderungs- / Häkchenlösungen wie die Pest vermeiden, da sie ineffizient sind und Probleme in Ihrer App verursachen können (z. B. berechnet ein Tooltip die Position neu, die beim Ändern der Fenstergröße angezeigt werden soll, und einen Moment später ändert sich auch die Größe Ihres Diagramms und die Seite ändert sich neu Layouts und jetzt ist dein Tooltip wieder falsch).
Sie können dieses Verhalten in einigen älteren Browsern simulieren, die es nicht richtig unterstützen, wie z. B. IE11, indem Sie a verwenden
<canvas>
Element verwenden, das seinen Aspekt beibehält.Bei 960x540 ist dies ein Aspekt von 16: 9:
quelle
Sie können auch Bootstrap 3 verwenden , um die Größe einer Visualisierung anzupassen. Zum Beispiel können wir den HTML- Code wie folgt einrichten :
Ich habe aufgrund meiner Bedürfnisse eine feste Höhe eingestellt, aber Sie können die Größe auch automatisch belassen. Das "col-sm-6 col-md-4" macht das div für verschiedene Geräte ansprechbar. Weitere Informationen finden Sie unter http://getbootstrap.com/css/#grid-example-basic
Wir können mit Hilfe der ID- Monatsansicht auf das Diagramm zugreifen .
Ich werde nicht sehr detailliert auf den d3-Code eingehen, sondern nur den Teil eingeben, der für die Anpassung an verschiedene Bildschirmgrößen erforderlich ist.
Die Breite wird festgelegt, indem die Breite des Div mit der ID-Monatsansicht ermittelt wird.
Die Höhe sollte in meinem Fall nicht den gesamten Bereich umfassen. Ich habe auch Text über der Leiste, daher muss ich auch diesen Bereich berechnen. Deshalb habe ich den Textbereich mit der ID responsivetext identifiziert. Um die zulässige Höhe des Balkens zu berechnen, habe ich die Höhe des Textes von der Höhe des Div abgezogen.
Auf diese Weise können Sie eine Leiste erstellen, die alle unterschiedlichen Bildschirm- / Div-Größen übernimmt. Es ist vielleicht nicht der beste Weg, es zu tun, aber es funktioniert sicherlich für die Bedürfnisse meines Projekts.
quelle