Spec-Zone.ru › D3.js 6

d3-brush

Фильтрование — это интерактивное задание одномерной или двумерной области выделения с помощью указательного жеста, например, щелкнув и перетащив мышь. Фильтрование часто используется для выделения отдельных элементов, таких как точки на диаграмме рассеяния или файлы на рабочем столе. Также его можно использовать для приближения к области интереса или для выделения непрерывных областей для перекрестного фильтра данных или живых гистограмм:

Mona Lisa Histogram

Модуль d3-brush реализует фильтрование для событий мыши и сенсорного ввода с помощью SVG. Нажмите и перетащите область выделения фильтра, чтобы переместить выделение. Нажмите и перетащите одну из ручек выделения, чтобы переместить соответствующий край (или края) выделения. Нажмите и перетащите невидимую накладку, чтобы определить новое выделение фильтра, или щелкните где-нибудь в области, подлежащей фильтрации, удерживая нажатой клавишу META (⌘). Удержание клавиши ALT (⌥) при перемещении фильтра приводит к его перепозиционированию вокруг центра, а удержание клавиши ПРОБЕЛ фиксирует текущий размер фильтра, позволяя только перемещать его.

Фильтры также поддерживают программирование. Например, вы можете прослушивать события end, а затем инициировать переход с помощью brush.move, чтобы привязать область выделения фильтра к семантическим границам:

Brush Snapping

Или вы можете перецентрировать фильтр при щелчке вне текущего выделения:

Click-to-Recenter

Установка

Если вы используете NPM, npm install d3-brush. В противном случае загрузите последнюю версию. Вы можете загрузить его как отдельную библиотеку или как часть D3. Поддерживаются ES модули, AMD, CommonJS и обычная среда. В обычной среде экспортируется глобальная переменная d3:

<script src="https://d3js.org/d3-color.v2.min.js"></script>
<script src="https://d3js.org/d3-dispatch.v2.min.js"></script>
<script src="https://d3js.org/d3-ease.v2.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v2.min.js"></script>
<script src="https://d3js.org/d3-timer.v2.min.js"></script>
<script src="https://d3js.org/d3-selection.v2.min.js"></script>
<script src="https://d3js.org/d3-transition.v2.min.js"></script>
<script src="https://d3js.org/d3-drag.v2.min.js"></script>
<script src="https://d3js.org/d3-brush.v2.min.js"></script>
<script>

var brush = d3.brush();

</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>

Прямоугольник overlay покрывает область, подлежащую фильтрации, определённую brush.extent. Прямоугольник selection покрывает область, определённую текущим выделением фильтра. Прямоугольники handle покрывают края и углы области выделения фильтра, что позволяет изменять соответствующее значение в области выделения фильтра интерактивно. Чтобы программно изменить область выделения фильтра, используйте brush.move.

brush.move(group, selection) · Исходный код, Примеры

Устанавливает активное выделение фильтра для указанной группы, которая должна быть выборкой или переходом 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) · Исходный код, Примеры

Псевдоним для 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. В противном случае selection определяется как массив чисел. Для двумерной кисти brush это [[x0, y0], [x1, y1]], где x0 — минимальное значение x, y0 — минимальное значение y, x1 — максимальное значение x, а y1 — максимальное значение y. Для кисти по оси x x-brush это [x0, x1]; для кисти по оси y y-brush это [y0, y1].

События кисти

При вызове обработчика события кисти он получает текущее событие кисти. Объект event предоставляет несколько полей:

  • target — связанное поведение кисти brush.
  • type — строка «start», «brush» или «end»; см. brush.on.
  • selection — текущий выбор кисти brush selection.
  • sourceEvent — базовое событие ввода, например, mousemove или touchmove.
  • mode — строка «drag», «space», «handle» или «center»; режим кисти.

© 2010–2020 Michael Bostock
Licensed under the BSD License.
https://github.com/d3/d3-brush

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API