d3-brush
Взаимодействие «прорисовки» — это интерактивное определение одномерной или двумерной области выбора с помощью жестов указателя, например, нажатия и перетаскивания мыши. Прорисовка часто используется для выбора отдельных элементов, таких как точки на диаграмме рассеяния или файлы на рабочем столе. Она также может использоваться для приближения к области интереса или для выбора непрерывных областей для перекрестного фильтра данных или живых гистограмм:
Модуль d3-brush реализует прорисовку для событий мыши и сенсорного ввода с использованием SVG. Нажимайте и перетаскивайте область выделения кисти для перемещения выделения. Нажимайте и перетаскивайте одну из ручек выделения, чтобы передвинуть соответствующий край (или края) выделения. Нажимайте и перетаскивайте невидимую наложение, чтобы определить новое выделение кисти, или щелкните где-либо в области, доступной для прорисовки, удерживая клавишу META (⌘). Удержание клавиши ALT (⌥) во время перемещения кисти приводит к её перепозиционированию вокруг центра, а удержание клавиши SPACE фиксирует текущий размер кисти, позволяя только перемещать её.
Кисти также поддерживают программно-управляемый контроль. Например, вы можете прослушивать события end, а затем инициировать переход с помощью brush.move, чтобы «привязать» выделение кисти к семантическим границам:
Или вы можете заставить кисть перецентрироваться, когда вы щелкните вне текущего выделения:
Установка
Если вы используете npm, npm install d3-brush. Вы также можете загрузить последнюю версию с GitHub. Для обычного HTML в современных браузерах импортируйте d3-brush из Skypack:
<script type="module">
import {brushX} from "https://cdn.skypack.dev/d3-brush@3";
const brush = brushX();
</script> Для устаревших сред вы можете загрузить UMD-сборку d3-brush с CDN на основе npm, например, с jsDelivr; экспортируется глобальная переменная d3:
<script src="https://cdn.jsdelivr.net/npm/d3-color@3"></script> <script src="https://cdn.jsdelivr.net/npm/d3-dispatch@3"></script> <script src="https://cdn.jsdelivr.net/npm/d3-ease@3"></script> <script src="https://cdn.jsdelivr.net/npm/d3-interpolate@3"></script> <script src="https://cdn.jsdelivr.net/npm/d3-selection@3"></script> <script src="https://cdn.jsdelivr.net/npm/d3-timer@3"></script> <script src="https://cdn.jsdelivr.net/npm/d3-drag@3"></script> <script src="https://cdn.jsdelivr.net/npm/d3-transition@3"></script> <script src="https://cdn.jsdelivr.net/npm/d3-brush@3"></script> <script> const brush = d3.brushX(); </script>
Попробуйте d3-brush в вашем браузере.
Справочник по API
d3.brush() · Исходный код, Примеры
Создаёт новую двумерную кисть.
d3.brushX() · Исходный код, Примеры
Создаёт новую одномерную кисть по оси x.
d3.brushY() · Исходный код
Создаёт новую одномерную кисть по оси y.
brush(group) · Исходный код, Примеры
Применяет кисть к указанной группе, которая должна быть выборкой SVG-элементов G. Обычно эта функция не вызывается напрямую, а вызывается через selection.call. Например, для отрисовки кисти:
svg.append("g")
.attr("class", "brush")
.call(d3.brush().on("brush", brushed)); Внутренне кисть использует selection.on для связывания необходимых обработчиков событий при перетаскивании. Обработчики используют имя .brush, поэтому вы можете впоследствии отвязать обработчики событий кисти следующим образом:
group.on(".brush", null); Кисть также создаёт необходимые SVG-элементы для отображения выделения кисти и для получения событий ввода для взаимодействия. Вы можете добавлять, удалять или изменять эти элементы по своему усмотрению, чтобы изменить внешний вид кисти; вы также можете применять таблицы стилей для изменения внешнего вида кисти. Структура двумерной кисти представлена следующим образом:
<g class="brush" fill="none" pointer-events="all" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"> <rect class="overlay" pointer-events="all" cursor="crosshair" x="0" y="0" width="960" height="500"></rect> <rect class="selection" cursor="move" fill="#777" fill-opacity="0.3" stroke="#fff" shape-rendering="crispEdges" x="112" y="194" width="182" height="83"></rect> <rect class="handle handle--n" cursor="ns-resize" x="107" y="189" width="192" height="10"></rect> <rect class="handle handle--e" cursor="ew-resize" x="289" y="189" width="10" height="93"></rect> <rect class="handle handle--s" cursor="ns-resize" x="107" y="272" width="192" height="10"></rect> <rect class="handle handle--w" cursor="ew-resize" x="107" y="189" width="10" height="93"></rect> <rect class="handle handle--nw" cursor="nwse-resize" x="107" y="189" width="10" height="10"></rect> <rect class="handle handle--ne" cursor="nesw-resize" x="289" y="189" width="10" height="10"></rect> <rect class="handle handle--se" cursor="nwse-resize" x="289" y="272" width="10" height="10"></rect> <rect class="handle handle--sw" cursor="nesw-resize" x="107" y="272" width="10" height="10"></rect> </g>
Прямоугольник наложения покрывает область, доступную для прорисовки, определенную с помощью brush.extent. Прямоугольник выделения покрывает область, определенную текущим выделением кисти. Прямоугольники ручек покрывают края и углы выделения кисти, позволяя изменять соответствующее значение в выделении кисти интерактивно. Для программированного изменения выделения кисти используйте brush.move.
brush.move(group, selection[, event]) · Исходный код, Примеры
Устанавливает активное выделение кисти на указанной группе, которая должна быть выборкой или переходом SVG-элементов G. Выделение должно быть определено как массив чисел или null для очистки выделения кисти. Для двумерной кисти оно должно быть определено как [[x0, y0], [x1, y1]], где x0 — минимальное значение x, y0 — минимальное значение y, x1 — максимальное значение x, а y1 — максимальное значение y. Для x-кисти оно должно быть определено как [x0, x1]; для y-кисти — как [y0, y1]. Выделение также может быть указано как функция, которая возвращает такой массив; если функция, она вызывается для каждого выбранного элемента, получая текущее данное d и индекс i, с контекстом this как текущим элементом DOM. Возвращаемый массив определяет выделение кисти для этого элемента.
brush.clear(group[, event]) · Исходный код, Примеры
Псевдоним для brush.move с нулевым выделением.
brush.extent([extent]) · Исходный код, Примеры
Если extent указан, устанавливает область прорисовки в указанный массив точек [[x0, y0], [x1, y1]], где [x0, y0] — верхний левый угол, а [x1, y1] — нижний правый угол, и возвращает эту кисть. extent также может быть задан как функция, возвращающая такой массив; если функция, она вызывается для каждого выбранного элемента, получая текущее данное d и индекс i, с контекстом this как текущим элементом DOM. Если extent не указан, возвращает текущий аксессор области, по умолчанию:
function defaultExtent() {
var svg = this.ownerSVGElement || this;
if (svg.hasAttribute("viewBox")) {
svg = svg.viewBox.baseVal;
return [[svg.x, svg.y], [svg.x + svg.width, svg.y + svg.height]];
}
return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
} Эта реализация по умолчанию требует, чтобы у владельца SVG-элемента был определён viewBox или атрибуты width и height. В качестве альтернативы, рассмотрите использование element.getBoundingClientRect. (В Firefox, element.clientWidth и element.clientHeight равны нулю для SVG-элементов!)
Область прорисовки кисти определяет размер невидимого наложения и также ограничивает выделение кисти; выделение кисти не может выходить за пределы области прорисовки.
brush.filter([filter]) · Исходный код, Примеры
Если filter указан, устанавливает фильтр в указанную функцию и возвращает кисть. Если filter не указан, возвращает текущий фильтр, по умолчанию:
function filter(event) {
return !event.ctrlKey && !event.button;
} Если фильтр возвращает ложное значение, инициирующее событие игнорируется, и жест прорисовки не начинается. Таким образом, фильтр определяет, какие события ввода игнорируются. Фильтр по умолчанию игнорирует события mousedown на дополнительных кнопках, так как эти кнопки, как правило, предназначены для других целей, таких как контекстное меню.
brush.touchable([touchable]) · Исходный код
Если touchable указан, устанавливает детектор поддержки сенсорного ввода в указанную функцию и возвращает кисть. Если touchable не указан, возвращает текущий детектор поддержки сенсорного ввода, по умолчанию:
function touchable() {
return navigator.maxTouchPoints || ("ontouchstart" in this);
} Обработчики событий сенсорного ввода регистрируются только в том случае, если детектор возвращает истинное значение для соответствующего элемента, когда кисть применяется. Детектор по умолчанию хорошо работает для большинства браузеров, поддерживающих сенсорный ввод, но не для всех; например, эмулятор мобильного устройства Chrome не обнаруживает его.
brush.keyModifiers([modifiers]) · Исходный код
Если modifiers указан, устанавливает, отслеживает ли кисть события клавиш в процессе прорисовки, и возвращает кисть. Если modifiers не указан, возвращает текущее поведение, которое по умолчанию равно true.
brush.handleSize([size]) · Исходный код
Если size указан, устанавливает размер ручек кисти в указанное число и возвращает кисть. Если size не указан, возвращает текущий размер ручки, который по умолчанию равен шести. Этот метод должен быть вызван перед применением кисти к выборке; изменение размера ручки не влияет на кисти, которые были ранее отрисованы.
brush.on(typenames[, listener]) · Исходный код
Если listener указан, устанавливает обработчик события listener для указанных typenames и возвращает кисть. Если обработчик событий уже был зарегистрирован для того же типа и имени, существующий обработчик удаляется перед добавлением нового. Если listener равен null, удаляет текущие обработчики событий для указанных typenames, если таковые имеются. Если listener не указан, возвращает первый в настоящее время назначенный обработчик, соответствующий указанным typenames, если таковой имеется. Когда указанное событие отправляется, каждый listener будет вызван с тем же контекстом и аргументами, что и обработчики selection.on: текущее событие event и данные d, с контекстом this в качестве текущего элемента DOM.
typenames — это строка, содержащая один или несколько typename, разделенных пробелами. Каждый typename — это type, необязательно после которого следует точка (.) и name, например, brush.foo и brush.bar; имя позволяет регистрировать несколько обработчиков для одного и того же type. type должен быть одним из следующих:
-
start— в начале жеста кисти, например, при нажатии мыши. -
brush— когда кисть перемещается, например, при перемещении мыши. -
end— в конце жеста кисти, например, при отпускании мыши.
См. dispatch.on и События кисти для получения дополнительной информации.
d3.brushSelection(node) · Исходный код, Примеры
Возвращает текущую выделенную область кисти для указанного node. Внутренне состояние кисти элемента хранится как element.__brush; однако, следует использовать этот метод, а не обращаться к нему напрямую. Если у данного node нет выделения, возвращает null. В противном случае, выделение определяется как массив чисел. Для двумерной кисти это [[x0, y0], [x1, y1]], где x0 — минимальное значение x, y0 — минимальное значение y, x1 — максимальное значение x, а y1 — максимальное значение y. Для кисти по оси x это [x0, x1]; для кисти по оси y это [y0, y1].
События кисти
При вызове обработчика события кисти он получает текущее событие кисти. Объект event предоставляет несколько полей:
-
target— связанное поведение кисти. -
type— строка “start”, “brush” или “end”; см. brush.on. -
selection— текущее выделение кисти. -
sourceEvent— базовое событие ввода, например, mousemove или touchmove. -
mode— строка “drag”, “space”, “handle” или “center”; режим кисти.
© 2010–2023 Michael Bostock
Licensed under the BSD License.
https://github.com/d3/d3-brush