import { Group } from './group'; import { Node } from './node'; type ValidId = string | number; type NodeConstructor = new () => TNode; type NodeFactory> = (datum: TDatum) => TNode; type NodeConstructorOrFactory> = NodeConstructor | NodeFactory; /** * `Selection['nodeFactory']` causes some Selections to unintuitively become unassignable to something that looks like * it should be. * * Example: * * type A = { opacity: number, yValue: number }; * type B = { opacity: number }; * type U = unknown; * const myA = new Selection>(new Group, Rect); * const myB: Selection> = myA; // error. * const myU: Selection> = myA; // also an error (same reason). * const myI: SelectionInterface> = myA; // OK * * Error for `myB` assignment * * Type 'Selection>' is not assignable to type 'Selection>'. * Types of property 'nodeFactory' are incompatible. * Type 'NodeFactory>' is not assignable to type 'NodeFactory>'. * Type 'B' is not assignable to type 'A'. * * Which basically mean: this is unsafe, because `myB` might end up in a situation where you create a `TDatum` that does * not include the `yValue` property, which would break the assumptions that you can make about `myA`. * * However, assignments like `myB` and `myU` are genuine cases that we want to support: * * 1. `myB` Animation: Partially update a scene-node * 2. `myU` Highlight: Call `Node.getBBox()` (we do not intend to access `Node.datum`). * * Using `SelectionInterface` works because you are telling Typescript that you only care about the methods `Selection` * (interface) and not about the properties used internally (implementation). */ export interface SelectionInterface> { [Symbol.iterator](): IterableIterator<{ node: TChild; }>; readonly length: number; nodes(): TChild[]; at(index: number): TChild | undefined; cleanup(): void; isGarbage(node: TChild): boolean; batchedUpdate(fn: () => void): void; } export declare class Selection> implements SelectionInterface { private readonly parentNode; private readonly autoCleanup; static select>(parent: Group, classOrFactory: NodeConstructorOrFactory, garbageCollection?: boolean): Selection ? Datum : never, N>; static selectNoInference>(parent: Group, classOrFactory: NodeConstructorOrFactory, garbageCollection?: boolean): Selection; static selectAll(parent: Node, predicate: (node: Node) => node is TChild): TChild[]; static selectByClass(node: Node, ...Classes: Array TChild>): TChild[]; static selectByTag(node: Node, tag: number): TChild[]; private readonly nodeFactory; private readonly garbageBin; private readonly _nodesMap; private _nodes; private data; private readonly debug; constructor(parentNode: Group, classOrFactory: NodeConstructorOrFactory, autoCleanup?: boolean); private createNode; /** * Update the data in a selection. If an `getDatumId()` function is provided, maintain a list of ids related to * the nodes. Otherwise, take the more efficient route of simply creating and destroying nodes at the end * of the array. */ update(data: TDatum[], initializer?: (node: TChild) => void, getDatumId?: (datum: TDatum) => ValidId): this; cleanup(): this; clear(): this; isGarbage(node: TChild): boolean; each(iterate: (node: TChild, datum: TDatum, index: number) => void): this; [Symbol.iterator](): IterableIterator<{ node: TChild; datum: TDatum; index: number; }>; select(predicate: (node: Node) => node is TChild2): TChild2[]; selectByClass(Class: new () => TChild2): TChild2[]; selectByTag(tag: number): TChild2[]; nodes(): TChild[]; at(index: number): TChild | undefined; get length(): number; batchedUpdate(fn: () => void): void; } export {};