import type { OrdinalCustomLayout } from "../stream/ordinalCustomLayout";
import type { Datum } from "../charts/shared/datumTypes";
export interface ParallelCoordinatesConfig {
    /**
     * Field names (in order) defining the axes. Each field must yield a
     * numeric value per datum. The leftmost field is axis 0.
     */
    fields: string[];
    /**
     * Field (or function) yielding a category per datum used for line
     * coloring. If omitted, all lines render in the theme primary color.
     */
    colorBy?: string | ((d: Datum) => string);
    /**
     * Optional per-field [min, max] domains. If omitted, computed from
     * data per field. Useful for locking axes when streaming.
     */
    domains?: Record<string, [number, number]>;
    /** Line opacity. Lower for many overlapping rows. @default 0.45 */
    opacity?: number;
    /** Line stroke width in px. @default 1.25 */
    strokeWidth?: number;
    /**
     * Render small dots at each row's value on each axis. @default false
     * (recommended for low-cardinality data only — gets noisy with 100+ rows).
     */
    showPoints?: boolean;
    /**
     * Render axis chrome — vertical axis lines, top labels (the field
     * name), and 5 tick marks per axis showing the domain range. Each
     * axis is independently scaled, so each gets its own ticks. @default
     * true
     */
    showAxes?: boolean;
    /**
     * Pixel padding reserved at the **top** of the plot for axis field-name
     * labels. Used only when `showAxes` is `true`. Subtracted from the line
     * drawing area along with bottom padding. @default 24
     *
     * The recipe also reserves bottom padding for tick numbers — 18px when
     * `showAxes` is true, 8px when it's false. That bottom value is fixed;
     * use a smaller chart `margin.bottom` if you need tighter packing.
     * Top padding when `showAxes` is false is also a fixed 8px (so polyline
     * endpoints don't hug the chart edge).
     */
    axisLabelPadding?: number;
    /**
     * Optional per-field tick formatter map. Falls back to
     * `v.toLocaleString()` for fields without explicit formatters.
     */
    tickFormat?: Record<string, (v: number) => string>;
    /**
     * Predicate that decides which rows render at full opacity. Rows where
     * `highlightFn(d) === false` render at `dimmedOpacity` instead, with
     * the matching rows z-ordered on top so they don't get covered by
     * neighbors. Recipes are pure functions so they can't own brush state
     * themselves — wire this from a parent component that manages the
     * selection (hover, brush, search query, etc.). Leave undefined for
     * uniform opacity.
     *
     * Roadmap: a future `<ParallelCoordinatesBrushes>` overlay component
     * will manage drag-to-brush state and feed this hook automatically;
     * `useBrushSelection` will carry per-field range constraints across
     * linked charts. This prop is the integration point both will use.
     */
    highlightFn?: (d: Datum) => boolean;
    /** Stroke opacity for non-matching rows when `highlightFn` is set. @default 0.08 */
    dimmedOpacity?: number;
}
/**
 * Parallel coordinates — one polyline per row, traced across N parallel
 * vertical axes. Each axis represents a numeric field with its own
 * independent linear scale, so columns in different units can sit
 * side-by-side without normalizing.
 *
 * Useful for high-dimensional pattern hunting: clusters of similar rows,
 * outliers that "swing wildly" between axes, and inverse correlations
 * (lines crossing).
 *
 * @example
 * ```tsx
 * import { OrdinalCustomChart } from "semiotic/ordinal"
 * import { parallelCoordinatesLayout } from "semiotic/recipes"
 *
 * <OrdinalCustomChart
 *   data={cars}
 *   layout={parallelCoordinatesLayout}
 *   layoutConfig={{
 *     fields: ["mpg", "displacement", "horsepower", "weight", "acceleration"],
 *     colorBy: "origin",
 *   }}
 *   width={800}
 *   height={400}
 * />
 * ```
 */
export declare const parallelCoordinatesLayout: OrdinalCustomLayout<ParallelCoordinatesConfig>;
