Event handling systems for implementing drag, zoom, and brush selection interactions to create engaging, responsive visualizations.
System for implementing drag and drop interactions.
/**
* Create drag behavior
* @returns Drag behavior function
*/
function drag<GElement extends Element, Datum>(): DragBehavior<GElement, Datum, Datum>;
interface DragBehavior<GElement extends Element, Datum, Subject> {
/**
* Apply drag behavior to selection
* @param selection - Selection to apply drag to
*/
(selection: Selection<GElement, Datum, any, any>): void;
/**
* Set coordinate system container
* @param container - Container element or accessor
* @returns Drag behavior for chaining
*/
container(container: Element | ((this: GElement, datum: Datum) => Element)): DragBehavior<GElement, Datum, Subject>;
/**
* Filter drag initiation events
* @param filter - Predicate function
* @returns Drag behavior for chaining
*/
filter(filter: (this: GElement, event: any, datum: Datum) => boolean): DragBehavior<GElement, Datum, Subject>;
/**
* Set drag subject (what is being dragged)
* @param subject - Subject accessor function
* @returns Drag behavior for chaining
*/
subject(subject: (this: GElement, event: any, datum: Datum) => Subject): DragBehavior<GElement, Datum, Subject>;
/**
* Add event listener
* @param typenames - Event type names
* @param listener - Event listener function
* @returns Drag behavior for chaining
*/
on(typenames: string, listener: ((this: GElement, event: D3DragEvent<GElement, Datum, Subject>, d: Datum) => void) | null): DragBehavior<GElement, Datum, Subject>;
}
interface D3DragEvent<GElement extends Element, Datum, Subject> {
type: "start" | "drag" | "end";
target: DragBehavior<GElement, Datum, Subject>;
subject: Subject;
x: number;
y: number;
dx: number;
dy: number;
identifier: string | number;
active: number;
sourceEvent: any;
}System for implementing pan and zoom interactions.
/**
* Create zoom behavior
* @returns Zoom behavior function
*/
function zoom<GElement extends Element, Datum>(): ZoomBehavior<GElement, Datum>;
interface ZoomBehavior<GElement extends Element, Datum> {
/**
* Apply zoom behavior to selection
* @param selection - Selection to apply zoom to
*/
(selection: Selection<GElement, Datum, any, any>): void;
/**
* Set scale extent (zoom limits)
* @param extent - [min_scale, max_scale]
* @returns Zoom behavior for chaining
*/
scaleExtent(extent: [number, number]): ZoomBehavior<GElement, Datum>;
/**
* Set translation extent (pan limits)
* @param extent - [[x0, y0], [x1, y1]] bounds
* @returns Zoom behavior for chaining
*/
translateExtent(extent: [[number, number], [number, number]]): ZoomBehavior<GElement, Datum>;
/**
* Programmatically apply zoom transform
* @param selection - Selection to transform
* @param transform - Transform to apply
* @returns Void
*/
transform(selection: Selection<GElement, Datum, any, any>, transform: ZoomTransform): void;
/**
* Add event listener
* @param typenames - Event type names
* @param listener - Event listener function
* @returns Zoom behavior for chaining
*/
on(typenames: string, listener: ((this: GElement, event: D3ZoomEvent<GElement, Datum>, d: Datum) => void) | null): ZoomBehavior<GElement, Datum>;
}
/**
* Get zoom transform for element
* @param node - DOM element
* @returns Current zoom transform
*/
function zoomTransform(node: Element): ZoomTransform;
/**
* Identity zoom transform (no scaling or translation)
*/
const zoomIdentity: ZoomTransform;
interface ZoomTransform {
x: number; // Translation x
y: number; // Translation y
k: number; // Scale factor
/**
* Apply transform to point
* @param point - [x, y] coordinates
* @returns Transformed [x, y] coordinates
*/
apply(point: [number, number]): [number, number];
/**
* Invert transform from point
* @param point - [x, y] transformed coordinates
* @returns Original [x, y] coordinates
*/
invert(point: [number, number]): [number, number];
/**
* Scale transform by factor
* @param k - Scale factor
* @returns New transform
*/
scale(k: number): ZoomTransform;
/**
* Translate transform by offset
* @param x - X offset
* @param y - Y offset
* @returns New transform
*/
translate(x: number, y: number): ZoomTransform;
}System for implementing rectangular selection interactions.
/**
* Create two-dimensional brush
* @returns Brush behavior function
*/
function brush<Datum>(): BrushBehavior<Datum>;
/**
* Create one-dimensional horizontal brush
* @returns Brush behavior function
*/
function brushX<Datum>(): BrushBehavior<Datum>;
/**
* Create one-dimensional vertical brush
* @returns Brush behavior function
*/
function brushY<Datum>(): BrushBehavior<Datum>;
interface BrushBehavior<Datum> {
/**
* Apply brush behavior to selection
* @param selection - Selection to apply brush to
*/
(selection: Selection<SVGGElement, Datum, any, any>): void;
/**
* Set brushable extent
* @param extent - [[x0, y0], [x1, y1]] extent
* @returns Brush behavior for chaining
*/
extent(extent: [[number, number], [number, number]]): BrushBehavior<Datum>;
/**
* Programmatically set brush selection
* @param group - Selection of brush groups
* @param selection - Brush selection coordinates or null
*/
move(group: Selection<SVGGElement, Datum, any, any>, selection: BrushSelection | null): void;
/**
* Add event listener
* @param typenames - Event type names
* @param listener - Event listener function
* @returns Brush behavior for chaining
*/
on(typenames: string, listener: ((this: SVGGElement, event: D3BrushEvent<Datum>, d: Datum) => void) | null): BrushBehavior<Datum>;
}
/**
* Get brush selection for element
* @param node - SVG group element
* @returns Current brush selection or null
*/
function brushSelection(node: SVGGElement): BrushSelection | null;
type BrushSelection = [[number, number], [number, number]] | [number, number];
interface D3BrushEvent<Datum> {
type: "start" | "brush" | "end";
target: BrushBehavior<Datum>;
selection: BrushSelection | null;
sourceEvent: any;
}import { drag, zoom, brush, select } from "d3";
// Drag behavior
const dragBehavior = drag()
.on("start", function(event, d) {
console.log("Drag started");
})
.on("drag", function(event, d) {
select(this)
.attr("x", event.x)
.attr("y", event.y);
});
select(".draggable-elements")
.call(dragBehavior);
// Zoom behavior
const zoomBehavior = zoom()
.scaleExtent([0.5, 10])
.on("zoom", function(event) {
const { transform } = event;
svg.selectAll("g")
.attr("transform", transform);
});
svg.call(zoomBehavior);
// Brush behavior
const brushBehavior = brush()
.extent([[0, 0], [400, 300]])
.on("brush end", function(event) {
const selection = event.selection;
if (selection) {
// Handle brush selection
console.log("Brushed area:", selection);
}
});
svg.append("g")
.call(brushBehavior);// Event types
interface D3DragEvent<GElement extends Element, Datum, Subject> {
type: "start" | "drag" | "end";
target: DragBehavior<GElement, Datum, Subject>;
subject: Subject;
x: number;
y: number;
dx: number;
dy: number;
identifier: string | number;
active: number;
sourceEvent: any;
}
interface D3ZoomEvent<GElement extends Element, Datum> {
type: "start" | "zoom" | "end";
target: ZoomBehavior<GElement, Datum>;
transform: ZoomTransform;
sourceEvent: any;
}
interface D3BrushEvent<Datum> {
type: "start" | "brush" | "end";
target: BrushBehavior<Datum>;
selection: BrushSelection | null;
sourceEvent: any;
}
// Transform and selection types
interface ZoomTransform {
x: number;
y: number;
k: number;
apply(point: [number, number]): [number, number];
invert(point: [number, number]): [number, number];
scale(k: number): ZoomTransform;
translate(x: number, y: number): ZoomTransform;
}
type BrushSelection = [[number, number], [number, number]] | [number, number];