Supposons que j'ai un script d'histogramme qui crée un graphique svg 960 500. Comment puis-je rendre cela réactif ainsi de suite redimensionner les largeurs et hauteurs graphiques sont dynamiques?
<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>
Un exemple d'histogramme complet est: https://gist.github.com/993912
javascript
responsive-design
d3.js
Matt Alcock
la source
la source
Réponses:
Il existe une autre façon de faire cela qui ne nécessite pas de redessiner le graphique, et cela implique de modifier les attributs viewBox et preserveAspectRatio sur l'
<svg>
élément:Mise à jour le 24/11/15 : la plupart des navigateurs modernes peuvent déduire le rapport d'aspect des éléments SVG à partir du
viewBox
, vous n'aurez donc pas besoin de maintenir la taille du graphique à jour. Si vous devez prendre en charge des navigateurs plus anciens, vous pouvez redimensionner votre élément lorsque la fenêtre se redimensionne comme suit:Et le contenu svg sera mis à l'échelle automatiquement. Vous pouvez voir un exemple de ceci (avec quelques modifications) ici : redimensionnez simplement la fenêtre ou le volet en bas à droite pour voir comment il réagit.
la source
onload
appel de fonction. Si la largeur et la hauteur svg sont définies dans le html réel et que vous utilisez la technique ci-dessus, l'image ne sera pas évolutive.Recherchez «SVG réactif», il est assez simple de rendre un SVG réactif et vous n'avez plus à vous soucier des tailles.
Voici comment je l'ai fait:
Le code CSS:
Plus d'informations / tutoriels:
http://demosthenes.info/blog/744/Make-SVG-Responsive
http://soqr.fr/testsvg/embed-svg-liquid-layout-responsive-web-design.php
la source
J'ai codé un petit résumé pour résoudre ce problème.
Le modèle de solution général est le suivant:
J'ai également ajouté le script d3.js minifié pour la vitesse. L'essentiel est ici: https://gist.github.com/2414111
code retour de référence jquery:
Code anti-rebond:
Prendre plaisir!
la source
Sans utiliser ViewBox
Voici un exemple de solution qui ne repose pas sur l'utilisation d'un
viewBox
:La clé est de mettre à jour la gamme des échelles qui sont utilisées pour placer les données.
Tout d'abord, calculez votre rapport hauteur / largeur d'origine:
Puis, sur chaque Redimensionner, mettez à jour le
range
dex
ety
:Notez que la hauteur est basée sur la largeur et le rapport hauteur / largeur afin que vos proportions d'origine soient conservées.
Enfin, "redessinez" le graphique - mettez à jour tout attribut qui dépend de l'une des échelles
x
ouy
:Notez qu'en redimensionnant le,
rects
vous pouvez utiliser la limite supérieure durange
dey
, plutôt que d'utiliser explicitement la hauteur:Afficher l'extrait de code
la source
Si vous utilisez d3.js à c3.js, la solution au problème de réactivité est assez simple:
où le code HTML généré ressemble à:
la source
La réponse de Shawn Allen était excellente. Mais vous ne voudrez peut-être pas le faire à chaque fois. Si vous l'hébergez sur vida.io , vous obtenez automatiquement une réponse pour votre visualisation svg.
Vous pouvez obtenir un iframe réactif avec ce simple code d'intégration:
http://jsfiddle.net/dnprock/npxp3v9d/1/
Divulgation: Je construis cette fonction à vida.io .
la source
Dans le cas où vous utilisez un wrapper d3 comme plottable.js , sachez que la solution la plus simple pourrait être d' ajouter un écouteur d'événements , puis d'appeler une fonction de rafraîchissement (
redraw
dans plottable.js). Dans le cas de plottable.js, cela fonctionnera parfaitement (cette approche est mal documentée):la source
Au cas où les gens visiteraient encore cette question - voici ce qui a fonctionné pour moi:
Mettez l'iframe dans un div et utilisez css pour ajouter un remplissage de, disons, 40% à ce div (le pourcentage en fonction du rapport d'aspect que vous voulez). Réglez ensuite la largeur et la hauteur de l'iframe lui-même à 100%.
Dans le document html contenant le graphique à charger dans l'iframe, définissez la largeur sur la largeur du div auquel le svg est ajouté (ou sur la largeur du corps) et définissez la hauteur sur la largeur * rapport d'aspect.
Écrivez une fonction qui recharge le contenu de l'iframe lors du redimensionnement de la fenêtre, afin d'adapter la taille du graphique lorsque les gens tournent leur téléphone.
Exemple ici sur mon site Web: http://dirkmjk.nl/en/2016/05/embedding-d3js-charts-responsive-website
MISE À JOUR 30 déc.2016
L'approche que j'ai décrite ci-dessus présente certains inconvénients, surtout qu'elle ne tient pas compte de la hauteur des titres et des légendes qui ne font pas partie du svg créé par D3. Depuis, je suis tombé sur ce que je pense être une meilleure approche:
Exemple ici sur mon site Web: http://dirkmjk.nl/en/2016/12/embedding-d3js-charts-responsive-website-better-solution
la source
L'un des principes de base de la jointure de données D3 est qu'elle est idempotente. En d'autres termes, si vous évaluez à plusieurs reprises une jointure de données avec les mêmes données, la sortie rendue est la même. Par conséquent, tant que vous restituez votre graphique correctement, en prenant soin de vos sélections d'entrée, de mise à jour et de sortie - tout ce que vous avez à faire lorsque la taille change, est de restituer le graphique dans son intégralité.
Il y a quelques autres choses que vous devez faire, l'une consiste à annuler le rebond du gestionnaire de redimensionnement de la fenêtre afin de le limiter. De plus, au lieu de coder en dur les largeurs / hauteurs, cela devrait être obtenu en mesurant l'élément contenant.
Comme alternative, voici votre graphique rendu à l'aide de d3fc , qui est un ensemble de composants D3 qui gèrent correctement les jointures de données. Il a également un graphique cartésien qui le mesure contenant un élément, ce qui facilite la création de graphiques «réactifs»:
Vous pouvez le voir en action dans ce codepen:
https://codepen.io/ColinEberhardt/pen/dOBvOy
où vous pouvez redimensionner la fenêtre et vérifier que le graphique est correctement restitué.
Veuillez noter qu'en tant que divulgation complète, je suis l'un des mainteneurs de d3fc.
la source
J'éviterais de redimensionner / cocher des solutions comme la peste, car elles sont inefficaces et peuvent causer des problèmes dans votre application (par exemple, une info-bulle recalcule la position à laquelle elle devrait apparaître lors du redimensionnement de la fenêtre, puis un instant plus tard, votre graphique se redimensionne également et la page se remet à jour). mises en page et maintenant votre info-bulle est à nouveau erronée).
Vous pouvez simuler ce comportement dans certains anciens navigateurs qui ne le prennent pas correctement en charge, comme IE11, en utilisant un
<canvas>
élément qui conserve son aspect.Étant donné 960x540 qui est un aspect de 16: 9:
la source
Beaucoup de réponses complexes ici.
Fondamentalement, tout ce que vous devez faire est d'abandonner les attributs
width
etheight
en faveur de l'viewBox
attribut:Si vous avez des marges, vous pouvez simplement les ajouter dans la largeur / hauteur, puis les ajouter
g
par la suite et les transformer comme vous le feriez normalement.la source
Vous pouvez également utiliser bootstrap 3 pour adapter la taille d'une visualisation. Par exemple, nous pouvons configurer le code HTML comme:
J'ai mis en place une hauteur fixe en raison de mes besoins, mais vous pouvez également laisser la taille auto. Le "col-sm-6 col-md-4" rend le div réactif pour différents appareils. Vous pouvez en savoir plus sur http://getbootstrap.com/css/#grid-example-basic
Nous pouvons accéder au graphique à l'aide de la vue mois id .
Je n'entrerai pas dans les détails du code d3, je n'entrerai que la partie nécessaire à l'adaptation aux différentes tailles d'écran.
La largeur est définie en obtenant la largeur du div avec la vue mensuelle id.
La hauteur dans mon cas ne doit pas inclure toute la zone. J'ai également du texte au-dessus de la barre, je dois donc également calculer cette zone. C'est pourquoi j'ai identifié la zone du texte avec l'id responsivetext. Pour calculer la hauteur autorisée de la barre, j'ai soustrait la hauteur du texte de la hauteur de la div.
Cela vous permet d'avoir une barre qui adoptera toutes les différentes tailles d'écran / div. Ce n'est peut-être pas la meilleure façon de le faire, mais cela fonctionne sûrement pour les besoins de mon projet.
la source