D3 предоставляет модуль D3.zoom
, который позволяет добавлять масштабирование и панорамирование для HTML или SVG элементов. В этой статье показано, как создать масштабирование, а также как добавить ограничения на масштабирование и панорамирование.
D3 позволяет добавлять масштабирование и панорамирование для HTML или SVG элементов. В следующем примере можно панорамировать, нажав и перемещая мышь, а также масштабировать, используя колесо мыши:
https://codepen.io/wantnocode/pen/vYRPxXx Добавление масштабирования и панорамирования требует трех шагов:
d3.zoom()
для создания масштабирующей функции
d3.zoom()
создает масштабирующую функцию:let zoom = d3.zoom();
Модуль
d3.zoom
предоставляет методы для добавления масштабирования и панорамирования к элементам.zoomвключает обработку событий **масштабирования** и **панорамирования**. Масштабирующая функция представляет собой функцию, которая добавляет обработчики событий (например, для событий перетаскивания, колеса мыши и касания) к элементам. У неё также есть методы, такие как
.on, которые определяются на ней. Метод
.on` можно вызвать для привязки обработчиков событий к масштабирующей функции. Принимает два параметра:
zoom
)анонимная или именованная функция
)function handleZoom(e) {
// масштабирование или панорамирование
}
let zoom = d3.zoom()
.on('zoom', handleZoom);
Тип события
'zoom'
включает'start'
и'end'
.'zoom'
указывает на изменения преобразований (например, пользователь масштабировал или панорамировал).'start'
указывает на начало масштабирования или панорамирования (например, пользователь нажал кнопку мыши).'end'
указывает на окончание масштабирования или панорамирования (например, пользователь отпустил кнопку мыши). ОбработчикhandleZoom
принимает один параметрe
, который представляет объект события масштабирования. Самым полезным свойством этого объекта являетсяtransform
. Это объект, представляющий последнее масштабирующее преобразование, обычно применяемое к элементам графика:
function handleZoom(e) {
d3.select('g.chart')
.attr('transform', e.transform);
}
e.transform` имеет три свойства x, y, k. x, y указывают на трансляцию.k представляет масштабирующий коэффициент. ```Вы можете добавить поведение масштабирования к элементу с помощью метода `call`:
d3.select('svg')
.call(zoom);
Поведение масштабирования — это функция, которая устанавливает слушателей событий на выбранном элементе (например,
svg
в приведенном выше примере). Когда происходят события масштабирования или перетаскивания, вычисляется преобразование, которое передается обработчику событий (например,handleZoom
в приведенном выше примере).
Предположим, что у вас есть SVG элемент g
, содержащий один элемент:
<svg width="600" height="400">
<g></g>
</svg>
В следующем коде создается поведение масштабирования с помощью элемента d3.zoom()
и добавляется к элементу svg
. Обработчик handleZoom
передается методу .on
. Когда происходит масштабирование или перетаскивание, вызывается handleZoom
. Это применяет преобразование к элементу g
.
function handleZoom(e) {
d3.select('svg g')
.attr('transform', e.transform);
}
let zoom = d3.zoom()
.on('zoom', handleZoom);
d3.select('svg')
.call(zoom);
Это полный пример, где случайный массив координат подключается к элементам circle
:
let data = [], width = 600, height = 400, numPoints = 100;
let zoom = d3.zoom()
.on('zoom', handleZoom);
function handleZoom(e) {
d3.select('svg g')
.attr('transform', e.transform);
}
function initZoom() {
d3.select('svg')
.call(zoom);
}
function updateData() {
data = [];
for(let i = 0; i < numPoints; i++) {
data.push({
id: i,
x: Math.random() * width,
y: Math.random() * height
});
}
}
function update() {
d3.select('svg g')
.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; })
.attr('r', 3);
}
initZoom();
updateData();
update();
Вы можете ограничить масштабирование и перетаскивание, чтобы пользователи могли масштабировать и перетаскивать только в определенном диапазоне.
.scaleExtent
можно использовать для ограничения масштабирования, передавая массив [min, max]
, где min
— это минимальный масштабный коэффициент, а max
— максимальный:
let zoom = d3.zoom()
.scaleExtent([1, 5]);
Вы можете использовать .translateExtent
для указания диапазона [x0, y0]
и [x1, y1]
, в котором пользователи не могут перетаскивать:
let width = 600, height = 400;
let zoom = d3.zoom()
.scaleExtent([1, 5])
.translateExtent([[0, 0], [width, height]]);
Теперь вы можете масштабировать только до коэффициента 5. Также вы не можете уменьшать масштаб ниже стандартного коэффициента 1. Кроме того, вы не должны перемещать изображение за пределы области графика:
Масштабирование и перемещение можно контролировать программно. Например, можно создать кнопки для масштабирования и перемещения графика.
Методы масштабирования и перемещения имеют следующие методы для установки масштабирования и перемещения:
| Метод | Описание |
| --- | --- | | :------------- | :----------------------------------------------------------- |
| .translateBy
| Добавляет заданные смещения x, y
к текущему преобразованию |
| .translateTo
| Устанавливает преобразование, чтобы заданные координаты x, y
были центрированы (если заданная точка [px, py]
, то она будет центрирована) |
| .scaleBy
| Умножает текущий масштаб на заданное значение |
| .scaleTo
| Устанавливает масштаб на заданное значение. Параметр 1
соответствует resetzoom
|
| .transform
| Устанавливает преобразование на заданное значение |
Эти методы не следует вызывать напрямую. Вместо этого их следует вызывать на элементах, которые принимают масштабирование и перемещение. Например:
d3.select('svg')
.call(zoom.scaleBy, 0.5);
Эти методы также можно вызывать на транзакциях, что дает хороший эффект:
d3.select('svg')
.transition()
.call(zoom.translateBy, 50, 0);
Это полный пример использования нескольких из вышеперечисленных методов: ! [image-20220822171431745](. /image/image--20220822171431745.png)
let data = [], width = 600, height = 400, numPoints = 100;
let zoom = d3.zoom()
.scaleExtent([0.25, 10])
.on('zoom', handleZoom);
function updateData() {
data = [];
for(let i = 0; i < numPoints; i++) {
data.push({
id: i,
x: Math.random() * width,
y: Math.random() * height
});
}
}
function initZoom() {
d3.select('svg')
.call(zoom);
}
function handleZoom(e) {
d3.select('svg g')
.attr('transform', e.transform);
}
function zoomIn() {
d3.select('svg')
.transition()
.call(zoom.scaleBy, 2);
}
function zoomOut() {
d3.select('svg')
.transition()
.call(zoom.scaleBy, 0.5);
}
function resetZoom() {
d3.select('svg')
.transition()
.call(zoom.scaleTo, 1);
}
``````markdown
function center() {
d3.select('svg')
.transition()
.call(zoom.translate, 0.5 * width, 0.5 * height);
}
function panLeft() {
d3.select('svg')
.transition()
.call(zoom.translateBy, -50, 0);
}
function panRight() {
d3.select('svg')
.transition()
.call(zoom.translateBy, 50, 0);
}
function update() {
d3.select('svg g')
.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; })
.attr('r', 8)
.attr("fill", (d, i) => d3.schemeCategory10[i % 10]);
}
initZoom();
updateData();
update();
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )