import type { Operator, Rankdir } from "./layout";
/** @internal */
interface IdDagreNode extends DagreNode {
    id: string;
}
type DagreOperator = Operator<IdDagreNode, undefined>;
export type { Rankdir } from "./layout";
/** quality preset for layout speed/quality trade-off */
export type DagreQuality = "fast" | "medium" | "slow";
/** layering algorithm for rank assignment */
export type DagreRanker = "network-simplex" | "longest-path" | "topological";
/** layout algorithm */
export type DagreAlgorithm = "sugiyama" | "zherebko" | "grid";
/** graph configuration set via {@link DagreGraph.setGraph} */
export interface DagreGraphConfig {
    /** layout direction (default: `"TB"`) */
    rankdir?: Rankdir;
    /** within-layer gap (default: `50`) */
    nodesep?: number;
    /** between-layer gap (default: `50`) */
    ranksep?: number;
    /** quality preset (default: `"medium"`) */
    quality?: DagreQuality;
    /** layering algorithm (default: `undefined`, uses preset default) */
    ranker?: DagreRanker;
    /** layout algorithm (default: `"sugiyama"`); `quality`/`ranker` only apply to sugiyama */
    algorithm?: DagreAlgorithm;
    /** total layout width (set by {@link dagre.layout}) */
    width?: number;
    /** total layout height (set by {@link dagre.layout}) */
    height?: number;
}
/** node label with position (x, y set by {@link dagre.layout}) */
export interface DagreNode {
    /** center x coordinate */
    x: number;
    /** center y coordinate */
    y: number;
    /** node width */
    width: number;
    /** node height */
    height: number;
}
/** a control point with x and y coordinates */
export interface DagrePoint {
    /** x coordinate */
    x: number;
    /** y coordinate */
    y: number;
}
/** edge label with control points (set by {@link dagre.layout}) */
export interface DagreEdge {
    /** control points (matches dagre's `{x, y}` format) */
    points: DagrePoint[];
}
/** edge descriptor returned by {@link DagreGraph.edges} */
export interface DagreEdgeDescriptor {
    /** source node id */
    v: string;
    /** target node id */
    w: string;
}
/**
 * dagre-compatible mutable graph backed by d3-dag
 *
 * Accessed as `dagre.graphlib.Graph`. Use with {@link dagre.layout}.
 *
 * @example
 *
 * ```ts
 * import { dagre } from "d3-dag";
 *
 * const grf = new dagre.graphlib.Graph();
 * grf.setGraph({});
 * grf.setDefaultEdgeLabel(() => ({}));
 * grf.setNode("a", { width: 40, height: 40 });
 * grf.setNode("b", { width: 40, height: 40 });
 * grf.setEdge("a", "b");
 * dagre.layout(grf);
 * const pos = grf.node("a"); // { x, y, width, height }
 * ```
 */
export declare class DagreGraph {
    #private;
    /** set graph configuration */
    setGraph(config?: DagreGraphConfig): this;
    /** get graph configuration (includes width/height after layout) */
    graph(): Required<DagreGraphConfig>;
    /** set default node label factory, used when {@link setNode} is called without a label */
    setDefaultNodeLabel(fn: () => {
        readonly width?: number;
        readonly height?: number;
    }): this;
    /** set default edge label factory (accepted for compatibility, not used) */
    setDefaultEdgeLabel(_fn: () => Record<string, unknown>): this;
    /** add or update a node */
    setNode(id: string, label?: {
        readonly width?: number;
        readonly height?: number;
    }): this;
    /** add or update multiple nodes */
    setNodes(ids: string[], label?: {
        readonly width?: number;
        readonly height?: number;
    }): this;
    /** add an edge (label is accepted for dagre compatibility but not used) */
    setEdge(v: string, w: string, _label?: Record<string, unknown>): this;
    /** check if a node exists */
    hasNode(id: string): boolean;
    /** check if an edge exists */
    hasEdge(v: string, w: string): boolean;
    /** remove a node and all its edges */
    removeNode(id: string): this;
    /** remove an edge */
    removeEdge(v: string, w: string): this;
    /** get node label (includes x, y after layout) */
    node(id: string): DagreNode;
    /** get edge label (includes points after layout) */
    edge(v: string, w: string): DagreEdge;
    /** get all node ids */
    nodes(): string[];
    /** get all edges as `{ v, w }` descriptors */
    edges(): DagreEdgeDescriptor[];
    /** number of nodes */
    nodeCount(): number;
    /** number of edges */
    edgeCount(): number;
    /** get predecessor node ids */
    predecessors(id: string): string[];
    /** get successor node ids */
    successors(id: string): string[];
    /** get all neighbor node ids (predecessors and successors, deduplicated) */
    neighbors(id: string): string[];
    /** get incoming edge descriptors, optionally filtered to edges from `w` */
    inEdges(v: string, w?: string): DagreEdgeDescriptor[];
    /** get outgoing edge descriptors, optionally filtered to edges to `w` */
    outEdges(v: string, w?: string): DagreEdgeDescriptor[];
    /** get all edge descriptors incident to `v`, optionally filtered to edges with `w` */
    nodeEdges(v: string, w?: string): DagreEdgeDescriptor[];
    /** get source node ids (no parents) */
    sources(): string[];
    /** get sink node ids (no children) */
    sinks(): string[];
    /** always true — dagre graphs are directed */
    isDirected(): true;
    /** always false — compound graphs are not supported */
    isCompound(): false;
    /** true if the graph has multiple edges between the same pair of nodes */
    isMultigraph(): boolean;
    /** add edges between consecutive pairs of nodes */
    setPath(nodes: string[]): this;
    /** create a new graph containing only nodes that pass the filter */
    filterNodes(fn: (id: string) => boolean): DagreGraph;
    /**
     * run layout — called by {@link dagre.layout}
     *
     * @internal
     */
    static layout(grf: DagreGraph, operator?: DagreOperator): void;
}
/**
 * dagre-compatible namespace backed by d3-dag
 *
 * Drop-in replacement for `dagre` using d3-dag's layout algorithms.
 * Optionally pass a custom {@link sugiyama} or {@link zherebko} operator
 * to `layout` for fine-tuned algorithm selection.
 *
 * @example
 *
 * ```ts
 * import { dagre } from "d3-dag";
 *
 * const grf = new dagre.graphlib.Graph();
 * grf.setGraph({});
 * grf.setDefaultEdgeLabel(() => ({}));
 * grf.setNode("a", { width: 40, height: 40 });
 * grf.setNode("b", { width: 40, height: 40 });
 * grf.setEdge("a", "b");
 * dagre.layout(grf);
 * const { x, y } = grf.node("a");
 * ```
 */
export declare const dagre: {
    /** graph constructors */
    readonly graphlib: {
        /** dagre-compatible graph class */
        readonly Graph: typeof DagreGraph;
    };
    /**
     * run layout on a graph, mutating it in-place
     *
     * Sets `x`/`y` on node labels, `points` on edge labels, and
     * `width`/`height` on the graph config.
     *
     * @param grf - the graph to lay out
     * @param operator - optional {@link Operator}; graph config is applied on top
     */
    readonly layout: typeof DagreGraph.layout;
};
