d3-ternary
Version:
Generate ternary plots
274 lines (273 loc) • 10.8 kB
TypeScript
import type { ScaleLinear } from "d3-scale";
export { barycentric } from "./barycentric";
/**
* Ternary plot generator
* @public
*/
export interface TernaryPlot<T> {
/**
* Converts data to cartesian coordinates using the provided barycentric converter and scaling by radius
*/
(d: T): [x: number, y: number];
/**
* Returns an SVG path command for the outer triangle
* @remarks
* Generates a path string that can be used with SVG path elements to draw the triangle
*/
triangle(): string;
/**
* Generates and returns an array of arrays containing grid line coordinates for each axis
* @remarks
* Takes a number specifying the number of grid lines for all axes.
* Each array contains the specified number of elements of two-element arrays with the start- and end coordinates of the grid line.
*
* Grid lines are generated using [d3.scaleLinear.ticks()](https://d3js.org/d3-scale/linear#linear_ticks).
* The specified count is only a **hint**; the scale may return more or fewer values depending on the domain.
*/
gridLines(count: number): GridLines;
/**
* Generates and returns an array of arrays containing grid line coordinates for each axis
* @remarks
* Takes an array of three numbers `[A, B, C]` specifying the number of grid lines for each axis.
* Each array contains the specified number of elements of two-element arrays with the start- and end coordinates of the grid line.
*/
gridLines(count: [number, number, number]): GridLines;
/**
* Generates and returns an array containing axis label objects
* @remarks
* Each axis label object contains:
* - `position`: An array of `[x,y]` coordinates
* - `angle`: The rotation angle of the label
* - `label`: The axis label text
* @param options - Configuration options
* @param options.center - If true, places labels at the center of each axis instead of at vertices
*/
axisLabels(options?: {
center?: boolean;
}): [a: AxisLabel, b: AxisLabel, c: AxisLabel];
/**
* Generates and returns an array of tick objects for each axis using the specified count
* @remarks
* Each tick object contains:
* - `tick`: The formatted tick text
* - `position`: An array of [x,y] coordinates
* - `angle`: The tick rotation angle
* - `textAnchor`: The SVG text-anchor value
* - `size`: The length of the tick line
*
* Ticks are generated using [d3.scaleLinear.ticks()](https://d3js.org/d3-scale/linear#linear_ticks).
* The specified count is only a **hint**; the scale may return more or fewer values depending on the domain.
* @param count - The approximate number of ticks to generate for each axis
*/
ticks(count: number): Ticks;
/**
* Generates and returns an array of tick objects for each axis using different counts per axis
* @remarks
* Each tick object contains:
* - `tick`: The formatted tick text
* - `position`: An array of [x,y] coordinates
* - `angle`: The tick rotation angle
* - `textAnchor`: The SVG text-anchor value
* - `size`: The length of the tick line
*
* Ticks are generated using [d3.scaleLinear.ticks()](https://d3js.org/d3-scale/linear#linear_ticks).
* The specified counts are only **hints**; the scale may return more or fewer values depending on the domain.
* @param count - An array of [a,b,c] specifying the approximate number of ticks for each axis
*/
ticks(count: [a: number, b: number, c: number]): Ticks;
/**
* Returns the current tick format, which defaults to `"%"`
*/
tickFormat(): string | ((d: number) => string);
/**
* Sets the tick format and returns the ternary plot
* @remarks
* Format can either be a [format specifier string](https://github.com/d3/d3-format#format)
* that is passed to [d3.tickFormat()](https://github.com/d3/d3-scale/blob/master/README.md#tickFormat),
* or a custom formatter function.
*/
tickFormat(format: string | ((d: number) => string)): TernaryPlot<T>;
/**
* Returns the current radius, which defaults to 300 (px)
*/
radius(): number;
/**
* Sets the radius of the ternary plot to the specified number and returns the ternary plot
*/
radius(radius: number): TernaryPlot<T>;
/**
* Computes ternary values from `[x, y]` coordinates that are scaled by the radius
* @remarks
* Unlike the barycentric.invert() method this method takes the plot radius into account.
* Note that for inverting mouse positions, the ternary plot should be centered at the origin of the containing SVG element.
*/
invert(coords: [number, number]): [number, number, number];
/**
* Returns the current axis labels, which defaults to `["A", "B", "C"]`
*/
labels(): [a: string, b: string, c: string];
/**
* Sets the axis labels to the specified labels in order of `[A, B, C]` and returns the ternary plot
*/
labels(labels: [a: string, b: string, c: string]): TernaryPlot<T>;
/**
* Returns the current tick angles, which defaults to `[0, 60, -60]`
*/
tickAngles(): [a: number, b: number, c: number];
/**
* Sets the angle of the ticks of each axis to the specified angles in order `[A, B, C]` and returns the ternary plot
*/
tickAngles(angles: [a: number, b: number, c: number]): TernaryPlot<T>;
/**
* Returns the current label angles, which defaults to `[0, 60, -60]`
*/
labelAngles(): [a: number, b: number, c: number];
/**
* Sets the angle of the axis labels to the specified angles in order `[A, B, C]` and returns the ternary plot
*/
labelAngles(angles: [a: number, b: number, c: number]): TernaryPlot<T>;
/**
* Returns the current text anchors, which defaults to `["start", "end", "end"]`
*/
tickTextAnchors(): [a: TextAnchor, b: TextAnchor, c: TextAnchor];
/**
* Sets the text-anchor of the ticks of each axis to the specified values in order `[A, B, C]` and returns the ternary plot
*/
tickTextAnchors(anchors: [a: TextAnchor, b: TextAnchor, c: TextAnchor]): TernaryPlot<T>;
/**
* Returns the current tick sizes, which defaults to `[6, 6, 6]` (px)
*/
tickSizes(): [number, number, number];
/**
* Sets the tick sizes of all axes to the specified size (px) and returns the ternary plot
*/
tickSizes(size: number): TernaryPlot<T>;
/**
* Sets the axis tick sizes to the specified tick sizes in order `[A, B, C]` and returns the ternary plot
*/
tickSizes(sizes: readonly [number, number, number]): TernaryPlot<T>;
/**
* Returns the current label offsets, which defaults to `[45, 45, 45]` (px)
*/
labelOffsets(): [a: number, b: number, c: number];
/**
* Sets the label offset of all axes to the specified size (px) and returns the ternary plot
*/
labelOffsets(offset: number): TernaryPlot<T>;
/**
* Sets the label offsets to the specified sizes in order `[A, B, C]` and returns the ternary plot
*/
labelOffsets(offsets: [a: number, b: number, c: number]): TernaryPlot<T>;
}
export type TextAnchor = "start" | "middle" | "end";
export type AxisLabel = {
position: [x: number, y: number];
label: string;
angle: number;
};
export type Tick = {
tick: string;
angle: number;
textAnchor: string;
size: number;
position: [x: number, y: number];
};
export type Ticks = [Array<Tick>, Array<Tick>, Array<Tick>];
export type GridLine = [
start: [x: number, y: number],
end: [x: number, y: number]
];
export type GridLines = [Array<GridLine>, Array<GridLine>, Array<GridLine>];
/**
* Accessor function for getting component values
* @public
*/
export type Accessor<T> = (d: T) => number;
/**
* Barycentric coordinate converter
* @public
*/
export interface Barycentric<T> {
/**
* Converts data to cartesian coordinates using the current accessors and scales
*/
(d: T): [x: number, y: number];
/**
* Converts raw barycentric coordinates to cartesian coordinates without scaling
*/
unscaled(d: [number, number, number]): [number, number];
/**
* Computes ternary values from coordinates
* @remarks
* Converts x,y coordinates back into barycentric coordinates, taking into account any rotation
*/
invert([x, y]: [number, number]): [number, number, number];
/**
* Returns the current accessor function for the A component
*/
a(): Accessor<T>;
/**
* Sets the accessor function for the A component and returns the barycentric converter
* @param fn - Accessor function that defaults to `(d) => d[0]`
*/
a(fn: Accessor<T>): Barycentric<T>;
/**
* Returns the current accessor function for the B component
*/
b(): Accessor<T>;
/**
* Sets the accessor function for the B component and returns the barycentric converter
* @param fn - Accessor function that defaults to `(d) => d[1]`
*/
b(fn: Accessor<T>): Barycentric<T>;
/**
* Returns the current accessor function for the C component
*/
c(): Accessor<T>;
/**
* Sets the accessor function for the C component and returns the barycentric converter
* @param fn - Accessor function that defaults to `(d) => d[2]`
*/
c(fn: Accessor<T>): Barycentric<T>;
/**
* Returns the current rotation angle in degrees, which defaults to 0.
*/
rotation(): number;
/**
* Sets the rotation angle to the specified angle in degrees and returns the barycentric converter.
* Positive angles rotate the plot clockwise.
*/
rotation(angle: number): Barycentric<T>;
/**
* Returns an array of the current domains.
* Each domain is a two-element array containing the start and end values, in order of `[A, B, C]`.
*/
domains(): [[number, number], [number, number], [number, number]];
/**
* Sets the domains for each axis and returns the barycentric converter.
* Each domain is a two-element array containing the start and end values, in order of `[A, B, C]`.
*/
domains(domains: [
[
start: number,
end: number
],
[
start: number,
end: number
],
[
start: number,
end: number
]
]): Barycentric<T>;
/**
* Returns the scales for the three axes
* @returns Array of d3 linear scales in order [A, B, C]
*/
scales(): [
ScaleLinear<number, number, never>,
ScaleLinear<number, number, never>,
ScaleLinear<number, number, never>
];
}