2017-01-09 18 views
1

Я хочу создать временную шкалу, в которой пользователь может выбирать между прокруткой для увеличения или выбором области для увеличения. Есть некоторые примеры первых, как: https://bl.ocks.org/mbostock/4015254 Или наезд на области с кистью: https://bl.ocks.org/mbostock/f48fcdb929a620ed97877e4678ab15e6
Но я не могу найти пример, который делает оба. Как я могу сделать то и другое? Или есть примеры, которые я пропустил?Сдвижная и масштабируемая временная шкала с d3

+0

Помог ли мой комментарий ниже? – HamsterHuey

+0

Нет, я не смог его реализовать. Но в данный момент я сосредотачиваюсь на своих экзаменах, поэтому у меня нет времени потратить на него больше 1 дня. –

ответ

0

Это не самая простая вещь для реализации. Как вы заметите, масштабирование на основе кисти не зависит от d3.zoom, но вместо этого выполняет масштабирование через слушатели, которые запускают события, чтобы делать все необходимое для масштабирования осей и соответственно перемещать элементы сюжета.

Для сравнения, все прокрутка на основе примеры масштабирования обычно полагаются на d3.zoom, который использует d3.zoom() поведения, которое отслеживает все преобразования выполняются на участке в то время как панорамирование/масштабирование и несет полную ответственность за обновление различных элементов диаграммы. Трудность заключается в том, что два подхода отличаются друг от друга, и если вы вручную измените вид диаграммы с помощью чистки, вам нужно выяснить способ обновления внутреннего преобразования масштабирования, который ссылается на d3.zoom, чтобы он знал об изменениях, сделанных с помощью события масштабирования на основе кисти.

Это совсем не легко сделать, потому что d3.zoom не был предназначен для подачи информации из других источников, а внутренняя запись преобразований, которые были выполнены, не должна быть обновляемой/изменяемой. Вы можете обновить преобразование с помощью selection.call(zoom.transform, d3.zoomIdentity);, но, к сожалению, он также запускает целую кучу событий, связанных с фактическим поведением масштабирования, чего вы не хотите, так как уже обработали все операции масштабирования с помощью масштабирования на основе кисти. Некрасиво, но эффективный обходной путь, что я был в состоянии использовать, чтобы сбросить масштаб преобразования был мутировать фактическое .__zoom поля узла DOM, который привязан к d3.zoom поведению следующим образом:

// WARNING: Ugly mutation of __zoom property of pan/scroll-zoom rect to 
// reset the transform without having to fire events associated with zoom 
// d3.select(".zoom").node().__zoom = {k: 1, x: 0, y: 0}; <-- Fails since __zoom contains other hidden objects 
scrollZoom.node().__zoom["k"] = 1; 
scrollZoom.node().__zoom["x"] = 0; 
scrollZoom.node().__zoom["y"] = 0; 

Так, например: Если вам нужна двумерная кисть для масштабирования прямоугольника, но также и d3.zoom масштабирование для панорамирования и прокрутки мыши, тогда в любое время, когда вы будете использовать двумерную кисть для масштабирования, вам нужно сбросить преобразование d3.zoom обратно в преобразование идентичности, как указано выше. Это предотвращает и уродливое и резкое дрожание в реакции панорамирования/прокрутки при соединении 2D-кистей с масштабированием действий с помощью действий панорамирования/мыши с помощью преобразования в записи с d3.zoom, не находящимся в синхронизации с представлением на дисплее (из-за двумерной кисти основанный на масштабировании, изменяющий представление без знания d3.zoom).

Вот что-то еще, что важно отметить:

d3.zoom имеет ограничение в том, что в настоящее время он поддерживает только общий масштаб увеличения для обеих осей Х и Y (Source). Это, к сожалению, означает, что нет возможности сопоставить масштабирование с двухмерной кистью с использованием метода, основанного на d3.zoom, поскольку масштабирование с использованием кисти с двумя кистями дает различное масштабирование масштабирования в X и Y. Если вы хотите делать что-то с минимальными проблемами, используя последовательный подход , Я бы рекомендовал посмотреть на использование d3.xyzoom. Это вилка d3.zoom, которая реализует поддержку различных шкал для осей X и Y. Это позволит вам рассчитать соответствующие значения масштабирования и трансляции масштабирования X и Y для любого выбора кисти 2D, который затем можно будет подать в d3.zoom, что позволит вам выполнить все масштабирование с использованием общего подхода (что также приводит к наименьшей сумме дублирования кода).

Если вы заинтересованы только в масштабировании с 1-му кистью, вы должны иметь возможность сопоставить это с d3.чтобы вам не приходилось иметь дело с двумя разными путями для обработки вида и масштабирования всех осей и других графических элементов в вашей диаграмме. Вот хороший пример этого:

https://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172

Извиняюсь за длину этого поста, и если это немного бессвязное. Я работаю над тем, чтобы собрать блок на моей работе через пару дней, и я попытаюсь вернуться сюда и опубликовать ссылку, когда я это сделаю. Я только начал изучать D3 неделю назад, поэтому я учусь по пути.