ag-charts-community
Version:
Advanced Charting / Charts supporting Javascript / Typescript / React / Angular / Vue
89 lines (88 loc) • 4.44 kB
TypeScript
import { Group } from './group';
import { Node } from './node';
type ValidId = string | number;
type NodeConstructor<TNode extends Node> = new () => TNode;
type NodeFactory<TDatum, TNode extends Node<TDatum>> = (datum: TDatum) => TNode;
type NodeConstructorOrFactory<TDatum, TNode extends Node<TDatum>> = NodeConstructor<TNode> | NodeFactory<TDatum, TNode>;
/**
* `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<A, Node<A>>(new Group, Rect<A>);
* const myB: Selection<B, Node<B>> = myA; // error.
* const myU: Selection<U, Node<U>> = myA; // also an error (same reason).
* const myI: SelectionInterface<B, Node<B>> = myA; // OK
*
* Error for `myB` assignment
*
* Type 'Selection<A, Node<A>>' is not assignable to type 'Selection<B, Node<B>>'.
* Types of property 'nodeFactory' are incompatible.
* Type 'NodeFactory<A, Node<A>>' is not assignable to type 'NodeFactory<B, Node<B>>'.
* 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<TDatum, TChild extends Node<TDatum>> {
[Symbol.iterator](): IterableIterator<{
node: TChild;
}>;
readonly length: number;
nodes(): TChild[];
cleanup(): void;
isGarbage(node: TChild): boolean;
batchedUpdate(fn: () => void): void;
}
export declare class Selection<TDatum, TChild extends Node<TDatum>> implements SelectionInterface<TDatum, TChild> {
private readonly parentNode;
private readonly autoCleanup;
static select<N extends Node<any>>(parent: Group, classOrFactory: NodeConstructorOrFactory<any, N>, garbageCollection?: boolean): Selection<N extends Node<infer Datum> ? Datum : never, N>;
static selectNoInference<DExplicit, N extends Node<DExplicit>>(parent: Group, classOrFactory: NodeConstructorOrFactory<DExplicit, N>, garbageCollection?: boolean): Selection<DExplicit, N>;
static selectAll<TChild extends Node = Node>(parent: Node, predicate: (node: Node) => node is TChild): TChild[];
static selectByClass<TChild extends Node = Node>(node: Node, ...Classes: Array<new () => TChild>): TChild[];
static selectByTag<TChild extends Node = Node>(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<TDatum, TChild>, 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<TChild2 extends Node>(predicate: (node: Node) => node is TChild2): TChild2[];
selectByClass<TChild2 extends Node>(Class: new () => TChild2): TChild2[];
selectByTag<TChild2 extends Node>(tag: number): TChild2[];
nodes(): TChild[];
at(index: number): TChild | undefined;
get length(): number;
batchedUpdate(fn: () => void): void;
}
export {};