import type { Twolayer } from ".";
/**
 * an interface for aggregating numbers
 *
 * It takes an iterable of indices and returns an aggregate index.  The
 * returned value must be between the min and the max index, and only return
 * undefined if and only if indices is empty.
 */
export type Aggregator = (indices: Iterable<number>) => number | undefined;
/** a simple efficient mean aggregator */
export declare function aggMean(indices: Iterable<number>): number | undefined;
/**
 * a median aggregator
 *
 * This produces close to optimal results.
 */
export declare function aggMedian(indices: Iterable<number>): number | undefined;
/**
 * a weighted median aggregator
 *
 * This produces close to optimal results, slightly better than median, with
 * slightly more computation time.
 */
export declare function aggWeightedMedian(indices: Iterable<number>): number | undefined;
/**
 * a {@link Twolayer} that orders nodes based off aggregated ancestor indices
 *
 * This is much faster than {@link twolayerOpt}, and often produces comparable
 * or better layouts.
 * Nodes without ancestors will be placed first to minimize the distance
 * between nodes with common ancestors, and then to minimize rank inversions
 * with respect to the initial ordering.
 *
 * Create with {@link twolayerAgg}.
 */
export interface TwolayerAgg<Agg extends Aggregator = Aggregator> extends Twolayer<unknown, unknown> {
    /**
     * set the {@link Aggregator} for this operator
     *
     * The aggregator is used to combine the indices of ancestors to provide a
     * suitable rank for ordering. There are three built-in variants:
     * - {@link aggMean} - The simple mean of indices. This is very fast and
     *   memory efficient, but is often worse than the other two.
     * - {@link aggMedian} - Takes the median of the indices. This is often
     *   better for minimizing edge crossings than mean.
     * - {@link aggWeightedMedian} - This slightly skews the results for nodes
     *   with an even number of ancestors, that tends to be a little better than
     *   {@link aggMedian} but runs a little slower.
     *
     * (default: {@link aggWeightedMedian})
     *
     * @example
     *
     * ```ts
     * const twolayer = twolayerAgg().aggregator(aggMedian);
     * ```
     */
    aggregator<NewAgg extends Aggregator>(val: NewAgg): TwolayerAgg<NewAgg>;
    /**
     * get the current aggregator
     */
    aggregator(): Agg;
    /** @internal flag indicating that this is built in to d3dag and shouldn't error in specific instances */
    readonly d3dagBuiltin: true;
}
/**
 * create a default {@link TwolayerAgg}
 *
 * This two-layer operator is a heuristic that is very fast, but doesn't do a
 * great job at minimizing edge crossings. It works well when combined with
 * {@link twolayerGreedy}.
 *
 * @example
 *
 * ```ts
 * const layout = sugiyama().decross(decrossTwoLayer().order(twolayerAgg()));
 * ```
 */
export declare function twolayerAgg(...args: never[]): TwolayerAgg;
