Skip to content
This repository has been archived by the owner on Jul 16, 2023. It is now read-only.

Commit

Permalink
Merge pull request #70 from tomwanzek/d3-axis-finalization
Browse files Browse the repository at this point in the history
Updated d3-axis to fix the dependency issue regarding TimeInterval. Added JSDoc comments.
  • Loading branch information
tomwanzek authored Aug 2, 2016
2 parents bed9395 + c0f8f18 commit 5611c4c
Show file tree
Hide file tree
Showing 2 changed files with 232 additions and 20 deletions.
250 changes: 232 additions & 18 deletions src/d3-axis/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,29 @@

import { Selection, TransitionLike } from '../d3-selection';

// TODO: The below import is commented out, as d3-axis does not have a dependency
// on d3-time. d3-time may only be loaded, if the use case requires a TimeInterval (or CountableTimeInterval)
// for an axis. In which case, the ticks(...) signature with interval argument, would be best-specified
// with the below import.

// import { TimeInterval } from '../d3-time';

// --------------------------------------------------------------------------
// Shared Types and Interfaces
// --------------------------------------------------------------------------


/**
* An interface to which a scale passed into axis must conform (at a minimum)
* A helper interface to describe the minimal contract to be met by a time interval
* which can be passed into the Axis.ticks(...) or Axis.tickArguments(...) methods when
* creating time series axes. Under normal circumstances the argument will be of type
* TimeInterval or CountableTimeInterval as defined in d3-time.
* NB: This helper interface has been created to avoid tight coupling of d3-axis to
* d3-time at the level of definition files. I.e. d3-time is not a
* dependency of d3-axis in the D3 Javascript implementation. This minimal contract
* is based on an analysis of how d3-axis passes a time interval argument into a time scale,
* if a time scale was set using Axis.scale(...). And in turn on how a time scale uses
* the time interval when creating ticks from it.
*/
export interface AxisTimeInterval {
range(start: Date, stop: Date, step?: number): Date[];
}

/**
* A helper interface to which a scale passed into axis must conform (at a minimum)
* for axis to use the scale without error
*/
export interface AxisScale<Domain> {
Expand All @@ -27,48 +36,253 @@ export interface AxisScale<Domain> {
range(): Array<number>;
copy(): AxisScale<Domain>;
bandwidth?(): number;
ticks?(count?: number): Array<number> | Array<Date>;
tickFormat?(count?: number, specifier?: string): ((d: number) => string) | ((d: Date) => string);
ticks?(count: number | AxisTimeInterval): Array<number> | Array<Date>;
tickFormat?(count: number | AxisTimeInterval, specifier?: string): ((d: number) => string) | ((d: Date) => string);
}


/**
* A helper type to alias elements which can serve as a container for an axis
*/
export type AxisContainerElement = SVGSVGElement | SVGGElement;

/**
* Interface defining an axis generator. The generic <Domain> is the type of the axis domain
*/
export interface Axis<Domain> {
/**
* Render the axis to the given context.
*
* @param context A selection of SVG containers (either SVG or G elements).
*/
(context: Selection<AxisContainerElement, any, any, any>): void;

/**
* Render the axis to the given context.
*
* @param context A transition defined on SVG containers (either SVG or G elements).
*/
(context: TransitionLike<AxisContainerElement, any>): void;

/**
* Gets the current scale underlying the axis.
*/
scale(): AxisScale<Domain>;

/**
* Sets the scale and returns the axis.
*
* @param scale The scale to be used for axis generation
*/
scale(scale: AxisScale<Domain>): Axis<Domain>;
ticks(counter: number, specifier?: string): Axis<Domain>;
// TODO: proper typing of interval argument is commented out to avoid import from a
// module that is not a dependency of d3-time (see imports above)

// ticks(interval: TimeInterval, specifier?: string): Axis<Domain>;
/**
* Sets the arguments that will be passed to scale.ticks and scale.tickFormat when the axis is rendered, and returns the axis generator.
*
* @param count Number of ticks that should be rendered
* @param specifier An optional format specifier to customize how the tick values are formatted.
*/
ticks(count: number, specifier?: string): Axis<Domain>;

/**
* Sets the arguments that will be passed to scale.ticks and scale.tickFormat when the axis is rendered, and returns the axis generator.
* Use with a TIME SCALE ONLY.
*
* @param interval A time interval used to generate date-based ticks. This is typically a TimeInterval/CountableTimeInterval as defined
* in d3-time. E.g. as obtained by passing in d3.timeMinute.every(15).
* @param specifier An optional format specifier to customize how the tick values are formatted.
*/
ticks(interval: AxisTimeInterval, specifier?: string): Axis<Domain>;

// HACK: use `any` instead of TimeInterval
ticks(interval: any, specifier?: string): Axis<Domain>;
/**
* Sets the arguments that will be passed to scale.ticks and scale.tickFormat when the axis is rendered, and returns the axis generator.
*/
ticks(arg0: any, ...args: any[]): Axis<Domain>;

/**
* Get an array containing the currently set arguments to be passed into scale.ticks and scale.tickFormat.
*/
tickArguments(): any[];

/**
* Sets the arguments that will be passed to scale.ticks and scale.tickFormat when the axis is rendered, and returns the axis generator.
*
* @param args An array containing a single element representing the count, i.e. number of ticks to be rendered.
*/
tickArguments(args: [number]): Axis<Domain>;

/**
* Sets the arguments that will be passed to scale.ticks and scale.tickFormat when the axis is rendered, and returns the axis generator.
*
* @param args An array containing two elements. The first element represents the count, i.e. number of ticks to be rendered. The second
* element is a string representing the format specifier to customize how the tick values are formatted.
*/
tickArguments(args: [number, string]): Axis<Domain>;

/**
* Sets the arguments that will be passed to scale.ticks and scale.tickFormat when the axis is rendered, and returns the axis generator.
* Use with a TIME SCALE ONLY.
*
* @param args An array containing a single element representing a time interval used to generate date-based ticks.
* This is typically a TimeInterval/CountableTimeInterval as defined in d3-time. E.g. as obtained by passing in d3.timeMinute.every(15).
*/
tickArguments(args: [AxisTimeInterval]): Axis<Domain>;

/**
* Sets the arguments that will be passed to scale.ticks and scale.tickFormat when the axis is rendered, and returns the axis generator.
* Use with a TIME SCALE ONLY.
*
* @param args An array containing two elements. The first element represents a time interval used to generate date-based ticks.
* This is typically a TimeInterval/CountableTimeInterval as defined in d3-time. E.g. as obtained by passing in d3.timeMinute.every(15).
* The second element is a string representing the format specifier to customize how the tick values are formatted.
*/
tickArguments(args: [AxisTimeInterval, string]): Axis<Domain>;

/**
* Sets the arguments that will be passed to scale.ticks and scale.tickFormat when the axis is rendered, and returns the axis generator.
*
* @param args An array with arguments suitable for the scale to be used for tick generation
*/
tickArguments(args: any[]): Axis<Domain>;

/**
* Returns the current tick values, which defaults to null.
*/
tickValues(): Domain[] | null;

/**
* Specified values to be used for ticks rather than using the scale’s automatic tick generator.
* The explicit tick values take precedent over the tick arguments set by axis.tickArguments.
* However, any tick arguments will still be passed to the scale’s tickFormat function if a
* tick format is not also set.
*
* @param values An array with values from the Domain of the scale underlying the axis.
*/
tickValues(values: Domain[]): Axis<Domain>;

/**
* Clears any previously-set explicit tick values and reverts back to the scale’s tick generator.
*
* @param values null
*/
tickValues(values: null): Axis<Domain>;
tickFormat(): (domainValue: Domain) => string;


/**
* Returns the currently set tick format function, which defaults to null.
*/
tickFormat(): ((domainValue: Domain) => string) | null;

/**
* Sets the tick format function and returns the axis.
*
* @param format A function mapping a value from the axis Domain to a formatted string
* for display purposes.
*/
tickFormat(format: (domainValue: Domain) => string): Axis<Domain>;

/**
* Reset the tick format function. A null format indicates that the scale’s
* default formatter should be used, which is generated by calling scale.tickFormat.
* In this case, the arguments specified by axis.tickArguments
* are likewise passed to scale.tickFormat.
*
* @param format null
*/
tickFormat(format: null): Axis<Domain>;

/**
* Get the current inner tick size, which defaults to 6.
*/
tickSize(): number;
/**
* Set the inner and outer tick size to the specified value and return the axis.
*
* @param size Tick size in pixels (Default is 6).
*/
tickSize(size: number): Axis<Domain>;

/**
* Get the current inner tick size, which defaults to 6.
* The inner tick size controls the length of the tick lines,
* offset from the native position of the axis.
*/
tickSizeInner(): number;

/**
* Set the inner tick size to the specified value and return the axis.
* The inner tick size controls the length of the tick lines,
* offset from the native position of the axis.
*
* @param size Tick size in pixels (Default is 6).
*/
tickSizeInner(size: number): Axis<Domain>;

/**
* Get the current outer tick size, which defaults to 6.
* The outer tick size controls the length of the square ends of the domain path,
* offset from the native position of the axis. Thus, the “outer ticks” are not actually
* ticks but part of the domain path, and their position is determined by the associated
* scale’s domain extent. Thus, outer ticks may overlap with the first or last inner tick.
* An outer tick size of 0 suppresses the square ends of the domain path,
* instead producing a straight line.
*/
tickSizeOuter(): number;

/**
* Set the current outer tick size and return the axis.
* The outer tick size controls the length of the square ends of the domain path,
* offset from the native position of the axis. Thus, the “outer ticks” are not actually
* ticks but part of the domain path, and their position is determined by the associated
* scale’s domain extent. Thus, outer ticks may overlap with the first or last inner tick.
* An outer tick size of 0 suppresses the square ends of the domain path,
* instead producing a straight line.
*
* @param size Tick size in pixels (Default is 6).
*/
tickSizeOuter(size: number): Axis<Domain>;

/**
* Get the current padding, which defaults to 3.
*/
tickPadding(): number;

/**
* Set the current padding and return the axis.
*
* @param padding Padding in pixels (Default is 3).
*/
tickPadding(padding: number): Axis<Domain>;

}

/**
* Constructs a new top-oriented axis generator for the given scale, with empty tick arguments,
* a tick size of 6 and padding of 3. In this orientation, ticks are drawn above the horizontal domain path.
*
* @param scale The scale to be used for axis generation
*/
export function axisTop<Domain>(scale: AxisScale<Domain>): Axis<Domain>;

/**
* Constructs a new right-oriented axis generator for the given scale, with empty tick arguments,
* a tick size of 6 and padding of 3. In this orientation, ticks are drawn to the right of the vertical domain path.
*
* @param scale The scale to be used for axis generation
*/
export function axisRight<Domain>(scale: AxisScale<Domain>): Axis<Domain>;

/**
* Constructs a new bottom-oriented axis generator for the given scale, with empty tick arguments,
* a tick size of 6 and padding of 3. In this orientation, ticks are drawn below the horizontal domain path.
*
* @param scale The scale to be used for axis generation
*/
export function axisBottom<Domain>(scale: AxisScale<Domain>): Axis<Domain>;

/**
* Constructs a new left-oriented axis generator for the given scale, with empty tick arguments,
* a tick size of 6 and padding of 3. In this orientation, ticks are drawn to the left of the vertical domain path.
*
* @param scale The scale to be used for axis generation
*/
export function axisLeft<Domain>(scale: AxisScale<Domain>): Axis<Domain>;
2 changes: 0 additions & 2 deletions tests/d3-axis/d3-axis-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ let axisScale: d3Axis.AxisScale<string> = bottomAxis.scale();

topAxis = topAxis.ticks(20, ',f');

// TODO: currently no strict typing for TimeInterval due to choice of
// limiting imports into definition file when d3-axis module has no dependency on d3-time
rightAxis = rightAxis.ticks(timeMinute.every(5));

// tickArguments(...) ----------------------------------------------------------------
Expand Down

0 comments on commit 5611c4c

Please sign in to comment.