Предположим, у меня есть скрипт гистограммы, который строит графику SVG 960 500. Как сделать так, чтобы изменение размера графической ширины и высоты было динамичным?
<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>
Полный пример гистограммы: https://gist.github.com/993912
javascript
responsive-design
d3.js
Мэтт Алкок
источник
источник
Ответы:
Есть еще один способ сделать это, который не требует перерисовки графика, и включает изменение атрибутов viewBox и preserveAspectRatio для
<svg>
элемента:Обновление 24.11.15 : большинство современных браузеров могут определять соотношение сторон SVG-элементов
viewBox
, поэтому вам может не потребоваться обновлять размер диаграммы. Если вам нужно поддерживать старые браузеры, вы можете изменить размер вашего элемента, когда размер окна изменится следующим образом:И содержимое SVG будет масштабироваться автоматически. Вы можете увидеть рабочий пример этого (с некоторыми изменениями) здесь : просто измените размер окна или нижней правой панели, чтобы увидеть, как оно реагирует.
источник
onload
вызова функции. Если ширина и высота svg установлены в фактическом html, и вы используете вышеупомянутую технику, изображение не будет масштабируемым.Ищите «отзывчивый SVG», сделать SVG отзывчивым довольно просто, и вам больше не нужно беспокоиться о размерах.
Вот как я это сделал:
Код CSS:
Больше информации / учебники:
http://demosthenes.info/blog/744/Make-SVG-Responsive
http://soqr.fr/testsvg/embed-svg-liquid-layout-responsive-web-design.php
источник
Я решил небольшой вопрос, чтобы решить это.
Общий шаблон решения таков:
Я также добавил минимизированный сценарий d3.js для скорости. Суть здесь: https://gist.github.com/2414111
JQuery ссылка обратный код:
Отменить код:
Наслаждайтесь!
источник
Без использования ViewBox
Вот пример решения, которое не зависит от использования
viewBox
:Ключ в обновлении диапазон от чешуи , которые используются для размещения данных.
Сначала рассчитайте исходное соотношение сторон:
Затем при каждом изменении размера обновите
range
ofx
иy
:Обратите внимание, что высота основана на ширине и соотношении сторон, поэтому ваши исходные пропорции сохраняются.
Наконец, «перерисовать» диаграмму - обновите любой атрибут, который зависит от одного из
x
илиy
масштабов:Обратите внимание, что при изменении размера
rects
вы можете использовать верхнюю границуrange
ofy
, а не явно использовать высоту:Показать фрагмент кода
источник
Если вы используете d3.js через c3.js, решение проблемы с отзывчивостью довольно простое:
где сгенерированный HTML выглядит так:
источник
Ответ Шона Аллена был великолепен. Но вы не можете делать это каждый раз. Если вы разместите его на vida.io , вы получите автоматический ответ для вашей визуализации svg.
Вы можете получить отзывчивый iframe с помощью этого простого кода:
http://jsfiddle.net/dnprock/npxp3v9d/1/
Раскрытие информации: Я строй этой функции в vida.io .
источник
В случае, если вы используете оболочку d3, например plottable.js , имейте в виду , что самым простым решением может быть добавление прослушивателя событий, а затем вызов функции перерисовки (
redraw
в plottable.js). В случае plottable.js это будет работать превосходно (этот подход плохо документирован):источник
Если люди все еще посещают этот вопрос - вот что сработало для меня:
Заключите iframe в div и используйте css для добавления отступа, скажем, 40% к этому div (процент в зависимости от желаемого соотношения сторон). Затем установите ширину и высоту самого iframe на 100%.
В html-документе, содержащем диаграмму, которая будет загружена в iframe, задайте width равной ширине div, к которому добавляется svg (или ширине тела), и установите соотношение высоты к ширине *.
Напишите функцию, которая перезагружает содержимое iframe при изменении размера окна, чтобы адаптировать размер диаграммы, когда люди поворачивают свой телефон.
Пример здесь на моем сайте: http://dirkmjk.nl/en/2016/05/embedding-d3js-charts-responsive-website
ОБНОВЛЕНИЕ 30 декабря 2016
Подход, который я описал выше, имеет некоторые недостатки, особенно в том, что он не учитывает высоту любых заголовков и подписей, которые не являются частью svg, созданного D3. С тех пор я столкнулся с тем, что я считаю лучшим подходом:
Пример здесь на моем сайте: http://dirkmjk.nl/en/2016/12/embedding-d3js-charts-responsive-website-better-solution
источник
Одним из основных принципов объединения данных D3 является то, что оно идемпотентно. Другими словами, если вы многократно оцениваете объединение данных с одними и теми же данными, результат вывода будет одинаковым. Поэтому, если вы правильно отображаете диаграмму, заботясь о выбранных параметрах ввода, обновления и выхода - все, что вам нужно делать при изменении размера, - повторно визуализировать диаграмму полностью.
Есть несколько других вещей, которые вы должны сделать, одна из них - отменить обработчик изменения размера окна, чтобы уменьшить его. Кроме того, вместо того, чтобы жестко кодировать ширину / высоту, это должно быть достигнуто путем измерения содержащего элемента.
В качестве альтернативы, ваша диаграмма отображается с использованием d3fc , который представляет собой набор компонентов D3, которые правильно обрабатывают соединения данных. Он также имеет декартову диаграмму, которая измеряет его, содержащий элемент, облегчающий создание «отзывчивых» диаграмм:
Вы можете увидеть это в действии в этом коде:
https://codepen.io/ColinEberhardt/pen/dOBvOy
где вы можете изменить размер окна и убедиться, что диаграмма правильно перерисована.
Обратите внимание, что в качестве полного раскрытия я являюсь одним из сопровождающих d3fc.
источник
Я бы не стал использовать такие решения, как чума, потому что они неэффективны и могут вызвать проблемы в вашем приложении (например, всплывающая подсказка пересчитывает позицию, которая должна появиться при изменении размера окна, затем через мгновение ваша диаграмма тоже изменится, и страница изменится. макеты и теперь ваша подсказка снова не так).
Вы можете смоделировать это поведение в некоторых старых браузерах, которые не поддерживают его должным образом, например, в IE11, используя
<canvas>
элемент, поддерживающий его аспект.Учитывая 960x540, который является аспектом 16: 9:
источник
Здесь много сложных ответов.
В основном все , что вам нужно сделать , это канавы
width
иheight
атрибуты в пользуviewBox
атрибута:Если у вас есть поля, вы можете просто добавить их туда в ширину / высоту, а затем просто добавить
g
и преобразовать, как обычно.источник
Вы также можете использовать загрузчик 3, чтобы адаптировать размер визуализации. Например, мы можем настроить HTML- код следующим образом:
Я установил фиксированную высоту из-за своих потребностей, но вы также можете оставить размер авто. «Col-sm-6 col-md-4» делает div реагирующим на разные устройства. Вы можете узнать больше на http://getbootstrap.com/css/#grid-example-basic
Мы можем получить доступ к графику с помощью идентификатора месяца .
Я не буду вдаваться в подробности о коде d3, я введу только ту часть, которая необходима для адаптации к разным размерам экрана.
Ширина устанавливается путем получения ширины div с идентификатором month-view.
Высота в моем случае не должна включать всю площадь. У меня также есть текст над панелью, поэтому мне нужно рассчитать и эту область. Вот почему я идентифицировал область текста с помощью идентификатора responseivetext. Для расчета допустимой высоты панели я вычел высоту текста из высоты элемента div.
Это позволяет вам иметь панель, которая будет принимать все различные размеры экрана / деления. Возможно, это не лучший способ сделать это, но он, безусловно, работает для нужд моего проекта.
источник